Statistics
| Branch: | Revision:

root / hw / pcnet.c @ ec607da7

History | View | Annotate | Download (54 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
#include "vl.h"
31

    
32
//#define PCNET_DEBUG
33
//#define PCNET_DEBUG_IO
34
//#define PCNET_DEBUG_BCR
35
//#define PCNET_DEBUG_CSR
36
//#define PCNET_DEBUG_RMD
37
//#define PCNET_DEBUG_TMD
38
//#define PCNET_DEBUG_MATCH
39

    
40

    
41
#define PCNET_IOPORT_SIZE       0x20
42
#define PCNET_PNPMMIO_SIZE      0x20
43

    
44

    
45
typedef struct PCNetState_st PCNetState;
46

    
47
struct PCNetState_st {
48
    PCIDevice dev;
49
    VLANClientState *vc;
50
    NICInfo *nd;
51
    QEMUTimer *poll_timer;
52
    int mmio_io_addr, rap, isr, lnkst;
53
    target_phys_addr_t rdra, tdra;
54
    uint8_t prom[16];
55
    uint16_t csr[128];
56
    uint16_t bcr[32];
57
    uint64_t timer;
58
    int xmit_pos, recv_pos;
59
    uint8_t buffer[4096];
60
    int tx_busy;
61
};
62

    
63
#ifdef __GNUC__
64
#define PACKED(A) A __attribute__ ((packed))
65
#else
66
#error FixMe
67
#endif
68

    
69
struct qemu_ether_header {
70
    uint8_t ether_dhost[6];
71
    uint8_t ether_shost[6];
72
    uint16_t ether_type;
73
};
74

    
75
/* BUS CONFIGURATION REGISTERS */
76
#define BCR_MSRDA    0
77
#define BCR_MSWRA    1
78
#define BCR_MC       2
79
#define BCR_LNKST    4
80
#define BCR_LED1     5
81
#define BCR_LED2     6
82
#define BCR_LED3     7
83
#define BCR_FDC      9
84
#define BCR_BSBC     18
85
#define BCR_EECAS    19
86
#define BCR_SWS      20
87
#define BCR_PLAT     22
88

    
89
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
90
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
91
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
92

    
93
#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
94
#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
95
#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
96
#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
97
#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
98
#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
99
#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
100
#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
101
#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
102
#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
103
#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
104
#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
105
#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
106
#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
107
#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
108
#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
109
#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
110
#define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
111
#define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
112
#define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
113

    
114
#define CSR_CRBC(S)      ((S)->csr[40])
115
#define CSR_CRST(S)      ((S)->csr[41])
116
#define CSR_CXBC(S)      ((S)->csr[42])
117
#define CSR_CXST(S)      ((S)->csr[43])
118
#define CSR_NRBC(S)      ((S)->csr[44])
119
#define CSR_NRST(S)      ((S)->csr[45])
120
#define CSR_POLL(S)      ((S)->csr[46])
121
#define CSR_PINT(S)      ((S)->csr[47])
122
#define CSR_RCVRC(S)     ((S)->csr[72])
123
#define CSR_XMTRC(S)     ((S)->csr[74])
124
#define CSR_RCVRL(S)     ((S)->csr[76])
125
#define CSR_XMTRL(S)     ((S)->csr[78])
126
#define CSR_MISSC(S)     ((S)->csr[112])
127

    
128
#define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
129
#define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
130
#define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
131
#define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
132
#define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
133
#define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
134
#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
135
#define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
136
#define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
137
#define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
138
#define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
139
#define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
140
#define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
141
#define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
142

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

    
146
struct pcnet_initblk16 {
147
    uint16_t mode;
148
    uint16_t padr1;
149
    uint16_t padr2;
150
    uint16_t padr3;
151
    uint16_t ladrf1;
152
    uint16_t ladrf2;
153
    uint16_t ladrf3;
154
    uint16_t ladrf4;
155
    unsigned PACKED(rdra:24);
156
    unsigned PACKED(res1:5);
157
    unsigned PACKED(rlen:3);
158
    unsigned PACKED(tdra:24);
159
    unsigned PACKED(res2:5);
160
    unsigned PACKED(tlen:3);
161
};
162

    
163
struct pcnet_initblk32 {
164
    uint16_t mode;
165
    unsigned PACKED(res1:4);
166
    unsigned PACKED(rlen:4);
167
    unsigned PACKED(res2:4);
168
    unsigned PACKED(tlen:4);
169
    uint16_t padr1;
170
    uint16_t padr2;
171
    uint16_t padr3;
172
    uint16_t _res;
173
    uint16_t ladrf1;
174
    uint16_t ladrf2;
175
    uint16_t ladrf3;
176
    uint16_t ladrf4;
177
    uint32_t rdra;
178
    uint32_t tdra;
179
};
180

    
181
struct pcnet_TMD {
182
    struct {
183
        unsigned tbadr:32;
184
    } tmd0;
185
    struct {
186
        unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:7), PACKED(bpe:1);
187
        unsigned PACKED(enp:1), PACKED(stp:1), PACKED(def:1), PACKED(one:1);
188
        unsigned PACKED(ltint:1), PACKED(nofcs:1), PACKED(err:1), PACKED(own:1);
189
    } tmd1;
190
    struct {
191
        unsigned PACKED(trc:4), PACKED(res:12);
192
        unsigned PACKED(tdr:10), PACKED(rtry:1), PACKED(lcar:1);
193
        unsigned PACKED(lcol:1), PACKED(exdef:1), PACKED(uflo:1), PACKED(buff:1);
194
    } tmd2;
195
    struct {
196
        unsigned res:32;
197
    } tmd3;    
198
};
199

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

    
219

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

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

    
252
static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
253
{
254
    if (!BCR_SWSTYLE(s)) {
255
        uint16_t xda[4];
256
        cpu_physical_memory_read(addr,
257
                (void *)&xda[0], sizeof(xda));
258
        ((uint32_t *)tmd)[0] = (xda[0]&0xffff) |
259
                ((xda[1]&0x00ff) << 16);
260
        ((uint32_t *)tmd)[1] = (xda[2]&0xffff)|
261
                ((xda[1] & 0xff00) << 16);
262
        ((uint32_t *)tmd)[2] =
263
                (xda[3] & 0xffff) << 16;
264
        ((uint32_t *)tmd)[3] = 0;
265
    }
266
    else
267
    if (BCR_SWSTYLE(s) != 3)
268
        cpu_physical_memory_read(addr, (void *)tmd, 16);
269
    else {
270
        uint32_t xda[4];
271
        cpu_physical_memory_read(addr,
272
                (void *)&xda[0], sizeof(xda));
273
        ((uint32_t *)tmd)[0] = xda[2];
274
        ((uint32_t *)tmd)[1] = xda[1];
275
        ((uint32_t *)tmd)[2] = xda[0];
276
        ((uint32_t *)tmd)[3] = xda[3];
277
    }
278
}
279

    
280
static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
281
{
282
    if (!BCR_SWSTYLE(s)) {
283
        uint16_t xda[4];
284
        xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
285
        xda[1] = ((((uint32_t *)tmd)[0]>>16)&0x00ff) |
286
            ((((uint32_t *)tmd)[1]>>16)&0xff00);
287
        xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
288
        xda[3] = ((uint32_t *)tmd)[2] >> 16;
289
        cpu_physical_memory_write(addr,
290
                (void *)&xda[0], sizeof(xda));
291
    }
292
    else {
293
        if (BCR_SWSTYLE(s) != 3)
294
            cpu_physical_memory_write(addr, (void *)tmd, 16);
295
        else {
296
            uint32_t xda[4];
297
            xda[0] = ((uint32_t *)tmd)[2];
298
            xda[1] = ((uint32_t *)tmd)[1];
299
            xda[2] = ((uint32_t *)tmd)[0];
300
            xda[3] = ((uint32_t *)tmd)[3];
301
            cpu_physical_memory_write(addr,
302
                    (void *)&xda[0], sizeof(xda));
303
        }
304
    }
305
}
306

    
307
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
308
{
309
    if (!BCR_SWSTYLE(s)) {
310
        uint16_t rda[4];
311
        cpu_physical_memory_read(addr,
312
                (void *)&rda[0], sizeof(rda));
313
        ((uint32_t *)rmd)[0] = (rda[0]&0xffff)|
314
                ((rda[1] & 0x00ff) << 16);
315
        ((uint32_t *)rmd)[1] = (rda[2]&0xffff)|
316
                ((rda[1] & 0xff00) << 16);
317
        ((uint32_t *)rmd)[2] = rda[3] & 0xffff;
318
        ((uint32_t *)rmd)[3] = 0;
319
    }
320
    else
321
    if (BCR_SWSTYLE(s) != 3)
322
        cpu_physical_memory_read(addr, (void *)rmd, 16);
323
    else {
324
        uint32_t rda[4];
325
        cpu_physical_memory_read(addr,
326
                (void *)&rda[0], sizeof(rda));
327
        ((uint32_t *)rmd)[0] = rda[2];
328
        ((uint32_t *)rmd)[1] = rda[1];
329
        ((uint32_t *)rmd)[2] = rda[0];
330
        ((uint32_t *)rmd)[3] = rda[3];
331
    }
332
}
333

    
334
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
335
{
336
    if (!BCR_SWSTYLE(s)) {
337
        uint16_t rda[4];                        \
338
        rda[0] = ((uint32_t *)rmd)[0] & 0xffff; \
339
        rda[1] = ((((uint32_t *)rmd)[0]>>16)&0xff)|\
340
            ((((uint32_t *)rmd)[1]>>16)&0xff00);\
341
        rda[2] = ((uint32_t *)rmd)[1] & 0xffff; \
342
        rda[3] = ((uint32_t *)rmd)[2] & 0xffff; \
343
        cpu_physical_memory_write(addr,         \
344
                (void *)&rda[0], sizeof(rda));  \
345
    }
346
    else {
347
        if (BCR_SWSTYLE(s) != 3)
348
            cpu_physical_memory_write(addr, (void *)rmd, 16);
349
        else {
350
            uint32_t rda[4];
351
            rda[0] = ((uint32_t *)rmd)[2];
352
            rda[1] = ((uint32_t *)rmd)[1];
353
            rda[2] = ((uint32_t *)rmd)[0];
354
            rda[3] = ((uint32_t *)rmd)[3];
355
            cpu_physical_memory_write(addr,
356
                    (void *)&rda[0], sizeof(rda));
357
        }
358
    }
359
}
360

    
361

    
362
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
363

    
364
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
365

    
366
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
367

    
368
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
369

    
370
#if 1
371

    
372
#define CHECK_RMD(ADDR,RES) do {                \
373
    struct pcnet_RMD rmd;                       \
374
    RMDLOAD(&rmd,(ADDR));                       \
375
    (RES) |= (rmd.rmd1.ones != 15)              \
376
          || (rmd.rmd2.zeros != 0);             \
377
} while (0)
378

    
379
#define CHECK_TMD(ADDR,RES) do {                \
380
    struct pcnet_TMD tmd;                       \
381
    TMDLOAD(&tmd,(ADDR));                       \
382
    (RES) |= (tmd.tmd1.ones != 15);             \
383
} while (0)
384

    
385
#else
386

    
387
#define CHECK_RMD(ADDR,RES) do {                \
388
    switch (BCR_SWSTYLE(s)) {                   \
389
    case 0x00:                                  \
390
        do {                                    \
391
            uint16_t rda[4];                    \
392
            cpu_physical_memory_read((ADDR),    \
393
                (void *)&rda[0], sizeof(rda));  \
394
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
395
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
396
        } while (0);                            \
397
        break;                                  \
398
    case 0x01:                                  \
399
    case 0x02:                                  \
400
        do {                                    \
401
            uint32_t rda[4];                    \
402
            cpu_physical_memory_read((ADDR),    \
403
                (void *)&rda[0], sizeof(rda)); \
404
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
405
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
406
        } while (0);                            \
407
        break;                                  \
408
    case 0x03:                                  \
409
        do {                                    \
410
            uint32_t rda[4];                    \
411
            cpu_physical_memory_read((ADDR),    \
412
                (void *)&rda[0], sizeof(rda)); \
413
            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
414
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
415
        } while (0);                            \
416
        break;                                  \
417
    }                                           \
418
} while (0)
419

    
420
#define CHECK_TMD(ADDR,RES) do {                \
421
    switch (BCR_SWSTYLE(s)) {                   \
422
    case 0x00:                                  \
423
        do {                                    \
424
            uint16_t xda[4];                    \
425
            cpu_physical_memory_read((ADDR),    \
426
                (void *)&xda[0], sizeof(xda));  \
427
            (RES) |= (xda[2] & 0xf000)!=0xf000;\
428
        } while (0);                            \
429
        break;                                  \
430
    case 0x01:                                  \
431
    case 0x02:                                  \
432
    case 0x03:                                  \
433
        do {                                    \
434
            uint32_t xda[4];                    \
435
            cpu_physical_memory_read((ADDR),    \
436
                (void *)&xda[0], sizeof(xda));  \
437
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
438
        } while (0);                            \
439
        break;                                  \
440
    }                                           \
441
} while (0)
442

    
443
#endif
444

    
445
#define PRINT_PKTHDR(BUF) do {                  \
446
    struct qemu_ether_header *hdr = (void *)(BUF);   \
447
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "       \
448
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, "              \
449
           "type=0x%04x (bcast=%d)\n",                          \
450
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
451
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
452
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
453
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
454
           be16_to_cpu(hdr->ether_type),                                \
455
           !!ETHER_IS_MULTICAST(hdr->ether_dhost));                     \
456
} while (0)
457

    
458
#define MULTICAST_FILTER_LEN 8
459

    
460
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
461
{
462
#define LNC_POLYNOMIAL          0xEDB88320UL
463
    uint32_t crc = 0xFFFFFFFF;
464
    int idx, bit;
465
    uint8_t data;
466

    
467
    for (idx = 0; idx < 6; idx++) {
468
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
469
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
470
            data >>= 1;
471
        }
472
    }
473
    return crc;
474
#undef LNC_POLYNOMIAL
475
}
476

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

    
479
/* generated using the AUTODIN II polynomial
480
 *        x^32 + x^26 + x^23 + x^22 + x^16 +
481
 *        x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
482
 */
483
static const uint32_t crctab[256] = {
484
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
485
        0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
486
        0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
487
        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
488
        0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
489
        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
490
        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
491
        0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
492
        0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
493
        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
494
        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
495
        0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
496
        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
497
        0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
498
        0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
499
        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
500
        0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
501
        0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
502
        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
503
        0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
504
        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
505
        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
506
        0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
507
        0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
508
        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
509
        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
510
        0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
511
        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
512
        0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
513
        0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
514
        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
515
        0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
516
        0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
517
        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
518
        0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
519
        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
520
        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
521
        0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
522
        0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
523
        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
524
        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
525
        0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
526
        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
527
        0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
528
        0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
529
        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
530
        0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
531
        0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
532
        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
533
        0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
534
        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
535
        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
536
        0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
537
        0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
538
        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
539
        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
540
        0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
541
        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
542
        0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
543
        0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
544
        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
545
        0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
546
        0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
547
        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
548
};
549

    
550
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
551
{
552
    struct qemu_ether_header *hdr = (void *)buf;
553
    uint8_t padr[6] = { 
554
        s->csr[12] & 0xff, s->csr[12] >> 8,
555
        s->csr[13] & 0xff, s->csr[13] >> 8,
556
        s->csr[14] & 0xff, s->csr[14] >> 8 
557
    };
558
    int result = (!CSR_DRCVPA(s)) && !bcmp(hdr->ether_dhost, padr, 6);
559
#ifdef PCNET_DEBUG_MATCH
560
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
561
           "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
562
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
563
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
564
           padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
565
    printf("padr_match result=%d\n", result);
566
#endif
567
    return result;
568
}
569

    
570
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
571
{
572
    static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
573
    struct qemu_ether_header *hdr = (void *)buf;
574
    int result = !CSR_DRCVBC(s) && !bcmp(hdr->ether_dhost, BCAST, 6);
575
#ifdef PCNET_DEBUG_MATCH
576
    printf("padr_bcast result=%d\n", result);
577
#endif
578
    return result;
579
}
580

    
581
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
582
{
583
    struct qemu_ether_header *hdr = (void *)buf;
584
    if ((*(hdr->ether_dhost)&0x01) && 
585
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
586
        uint8_t ladr[8] = { 
587
            s->csr[8] & 0xff, s->csr[8] >> 8,
588
            s->csr[9] & 0xff, s->csr[9] >> 8,
589
            s->csr[10] & 0xff, s->csr[10] >> 8, 
590
            s->csr[11] & 0xff, s->csr[11] >> 8 
591
        };
592
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
593
        return !!(ladr[index >> 3] & (1 << (index & 7)));
594
    }
595
    return 0;
596
}
597

    
598
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx) 
599
{
600
    while (idx < 1) idx += CSR_RCVRL(s);
601
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
602
}
603

    
604
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
605
{
606
    int64_t next_time = current_time + 
607
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)), 
608
                 ticks_per_sec, 33000000L);
609
    if (next_time <= current_time)
610
        next_time = current_time + 1;
611
    return next_time;
612
}
613

    
614
static void pcnet_poll(PCNetState *s);
615
static void pcnet_poll_timer(void *opaque);
616

    
617
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
618
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
619
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
620
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
621

    
622
static void pcnet_s_reset(PCNetState *s)
623
{
624
#ifdef PCNET_DEBUG
625
    printf("pcnet_s_reset\n");
626
#endif
627

    
628
    s->lnkst = 0x40;
629
    s->rdra = 0;
630
    s->tdra = 0;
631
    s->rap = 0;
632
    
633
    s->bcr[BCR_BSBC] &= ~0x0080;
634

    
635
    s->csr[0]   = 0x0004;
636
    s->csr[3]   = 0x0000;
637
    s->csr[4]   = 0x0115;
638
    s->csr[5]   = 0x0000;
639
    s->csr[6]   = 0x0000;
640
    s->csr[8]   = 0;
641
    s->csr[9]   = 0;
642
    s->csr[10]  = 0;
643
    s->csr[11]  = 0;
644
    s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
645
    s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
646
    s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
647
    s->csr[15] &= 0x21c4;
648
    s->csr[72]  = 1;
649
    s->csr[74]  = 1;
650
    s->csr[76]  = 1;
651
    s->csr[78]  = 1;
652
    s->csr[80]  = 0x1410;
653
    s->csr[88]  = 0x1003;
654
    s->csr[89]  = 0x0262;
655
    s->csr[94]  = 0x0000;
656
    s->csr[100] = 0x0200;
657
    s->csr[103] = 0x0105;
658
    s->csr[103] = 0x0105;
659
    s->csr[112] = 0x0000;
660
    s->csr[114] = 0x0000;
661
    s->csr[122] = 0x0000;
662
    s->csr[124] = 0x0000;
663

    
664
    s->tx_busy = 0;
665
}
666

    
667
static void pcnet_update_irq(PCNetState *s)
668
{
669
    int isr = 0;
670
    s->csr[0] &= ~0x0080;
671
    
672
#if 1
673
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
674
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
675
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
676
#else
677
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
678
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
679
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
680
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
681
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
682
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
683
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
684
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
685
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
686
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
687
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
688
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
689
#endif
690
    {
691
       
692
        isr = CSR_INEA(s);
693
        s->csr[0] |= 0x0080;
694
    }
695
    
696
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
697
        s->csr[4] &= ~0x0080;
698
        s->csr[4] |= 0x0040;
699
        s->csr[0] |= 0x0080;
700
        isr = 1;
701
#ifdef PCNET_DEBUG
702
        printf("pcnet user int\n");
703
#endif
704
    }
705

    
706
#if 1
707
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) 
708
#else
709
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
710
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
711
#endif
712
    {
713
        isr = 1;
714
        s->csr[0] |= 0x0080;
715
    }
716

    
717
    if (isr != s->isr) {
718
#ifdef PCNET_DEBUG
719
        printf("pcnet: INTA=%d\n", isr);
720
#endif
721
    }
722
        pci_set_irq(&s->dev, 0, isr);
723
        s->isr = isr;
724
}
725

    
726
static void pcnet_init(PCNetState *s)
727
{
728
#ifdef PCNET_DEBUG
729
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
730
#endif
731
    
732
#define PCNET_INIT() do { \
733
        cpu_physical_memory_read(PHYSADDR(s,CSR_IADR(s)),       \
734
                (uint8_t *)&initblk, sizeof(initblk));          \
735
        s->csr[15] = le16_to_cpu(initblk.mode);                 \
736
        CSR_RCVRL(s) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512;  \
737
        CSR_XMTRL(s) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512;  \
738
        s->csr[ 6] = (initblk.tlen << 12) | (initblk.rlen << 8);        \
739
        s->csr[ 8] = le16_to_cpu(initblk.ladrf1);                       \
740
        s->csr[ 9] = le16_to_cpu(initblk.ladrf2);                       \
741
        s->csr[10] = le16_to_cpu(initblk.ladrf3);                       \
742
        s->csr[11] = le16_to_cpu(initblk.ladrf4);                       \
743
        s->csr[12] = le16_to_cpu(initblk.padr1);                        \
744
        s->csr[13] = le16_to_cpu(initblk.padr2);                        \
745
        s->csr[14] = le16_to_cpu(initblk.padr3);                        \
746
        s->rdra = PHYSADDR(s,initblk.rdra);                             \
747
        s->tdra = PHYSADDR(s,initblk.tdra);                             \
748
} while (0)
749
    
750
    if (BCR_SSIZE32(s)) {
751
        struct pcnet_initblk32 initblk;
752
        PCNET_INIT();
753
#ifdef PCNET_DEBUG
754
        printf("initblk.rlen=0x%02x, initblk.tlen=0x%02x\n",
755
                initblk.rlen, initblk.tlen);
756
#endif
757
    } else {
758
        struct pcnet_initblk16 initblk;
759
        PCNET_INIT();
760
#ifdef PCNET_DEBUG
761
        printf("initblk.rlen=0x%02x, initblk.tlen=0x%02x\n",
762
                initblk.rlen, initblk.tlen);
763
#endif
764
    }
765

    
766
#undef PCNET_INIT
767

    
768
    CSR_RCVRC(s) = CSR_RCVRL(s);
769
    CSR_XMTRC(s) = CSR_XMTRL(s);
770

    
771
#ifdef PCNET_DEBUG
772
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
773
        BCR_SSIZE32(s),
774
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
775
#endif
776

    
777
    s->csr[0] |= 0x0101;    
778
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
779
}
780

    
781
static void pcnet_start(PCNetState *s)
782
{
783
#ifdef PCNET_DEBUG
784
    printf("pcnet_start\n");
785
#endif
786

    
787
    if (!CSR_DTX(s))
788
        s->csr[0] |= 0x0010;    /* set TXON */
789
        
790
    if (!CSR_DRX(s))
791
        s->csr[0] |= 0x0020;    /* set RXON */
792

    
793
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
794
    s->csr[0] |= 0x0002;
795
}
796

    
797
static void pcnet_stop(PCNetState *s)
798
{
799
#ifdef PCNET_DEBUG
800
    printf("pcnet_stop\n");
801
#endif
802
    s->csr[0] &= ~0x7feb;
803
    s->csr[0] |= 0x0014;
804
    s->csr[4] &= ~0x02c2;
805
    s->csr[5] &= ~0x0011;
806
    pcnet_poll_timer(s);
807
}
808

    
809
static void pcnet_rdte_poll(PCNetState *s)
810
{
811
    s->csr[28] = s->csr[29] = 0;
812
    if (s->rdra) {
813
        int bad = 0;
814
#if 1
815
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
816
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
817
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
818
#else
819
        target_phys_addr_t crda = s->rdra + 
820
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
821
            (BCR_SWSTYLE(s) ? 16 : 8 );
822
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
823
        target_phys_addr_t nrda = s->rdra + 
824
            (CSR_RCVRL(s) - nrdc) *
825
            (BCR_SWSTYLE(s) ? 16 : 8 );
826
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
827
        target_phys_addr_t nnrd = s->rdra + 
828
            (CSR_RCVRL(s) - nnrc) *
829
            (BCR_SWSTYLE(s) ? 16 : 8 );
830
#endif
831

    
832
        CHECK_RMD(PHYSADDR(s,crda), bad);
833
        if (!bad) {
834
            CHECK_RMD(PHYSADDR(s,nrda), bad);
835
            if (bad || (nrda == crda)) nrda = 0;
836
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
837
            if (bad || (nnrd == crda)) nnrd = 0;
838

    
839
            s->csr[28] = crda & 0xffff;
840
            s->csr[29] = crda >> 16;
841
            s->csr[26] = nrda & 0xffff;
842
            s->csr[27] = nrda >> 16;
843
            s->csr[36] = nnrd & 0xffff;
844
            s->csr[37] = nnrd >> 16;
845
#ifdef PCNET_DEBUG
846
            if (bad) {
847
                printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
848
                       PHYSADDR(s,crda));
849
            }
850
        } else {
851
            printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
852
#endif
853
        }
854
    }
855
    
856
    if (CSR_CRDA(s)) {
857
        struct pcnet_RMD rmd;
858
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
859
        CSR_CRBC(s) = rmd.rmd1.bcnt;
860
        CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
861
#ifdef PCNET_DEBUG_RMD_X
862
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
863
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
864
                ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
865
        PRINT_RMD(&rmd);
866
#endif
867
    } else {
868
        CSR_CRBC(s) = CSR_CRST(s) = 0;
869
    }
870
    
871
    if (CSR_NRDA(s)) {
872
        struct pcnet_RMD rmd;
873
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
874
        CSR_NRBC(s) = rmd.rmd1.bcnt;
875
        CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
876
    } else {
877
        CSR_NRBC(s) = CSR_NRST(s) = 0;
878
    }
879

    
880
}
881

    
882
static int pcnet_tdte_poll(PCNetState *s)
883
{
884
    s->csr[34] = s->csr[35] = 0;
885
    if (s->tdra) {
886
        target_phys_addr_t cxda = s->tdra + 
887
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
888
            (BCR_SWSTYLE(s) ? 16 : 8 );
889
        int bad = 0;
890
        CHECK_TMD(PHYSADDR(s, cxda),bad);
891
        if (!bad) {
892
            if (CSR_CXDA(s) != cxda) {
893
                s->csr[60] = s->csr[34];
894
                s->csr[61] = s->csr[35];
895
                s->csr[62] = CSR_CXBC(s);
896
                s->csr[63] = CSR_CXST(s);
897
            }
898
            s->csr[34] = cxda & 0xffff;
899
            s->csr[35] = cxda >> 16;
900
#ifdef PCNET_DEBUG
901
        } else {
902
            printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
903
#endif
904
        }
905
    }
906

    
907
    if (CSR_CXDA(s)) {
908
        struct pcnet_TMD tmd;
909

    
910
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
911

    
912
        CSR_CXBC(s) = tmd.tmd1.bcnt;
913
        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
914
    } else {
915
        CSR_CXBC(s) = CSR_CXST(s) = 0;
916
    }
917
    
918
    return !!(CSR_CXST(s) & 0x8000);
919
}
920

    
921
static int pcnet_can_receive(void *opaque)
922
{
923
    PCNetState *s = opaque;
924
    if (CSR_STOP(s) || CSR_SPND(s))
925
        return 0;
926
        
927
    if (s->recv_pos > 0)
928
        return 0;
929

    
930
    return sizeof(s->buffer)-16;
931
}
932

    
933
#define MIN_BUF_SIZE 60
934

    
935
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
936
{
937
    PCNetState *s = opaque;
938
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
939
    uint8_t buf1[60];
940

    
941
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
942
        return;
943

    
944
#ifdef PCNET_DEBUG
945
    printf("pcnet_receive size=%d\n", size);
946
#endif
947

    
948
    /* if too small buffer, then expand it */
949
    if (size < MIN_BUF_SIZE) {
950
        memcpy(buf1, buf, size);
951
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
952
        buf = buf1;
953
        size = MIN_BUF_SIZE;
954
    }
955

    
956
    if (CSR_PROM(s) 
957
        || (is_padr=padr_match(s, buf, size)) 
958
        || (is_bcast=padr_bcast(s, buf, size))
959
        || (is_ladr=ladr_match(s, buf, size))) {
960

    
961
        pcnet_rdte_poll(s);
962

    
963
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
964
            struct pcnet_RMD rmd;
965
            int rcvrc = CSR_RCVRC(s)-1,i;
966
            target_phys_addr_t nrda;
967
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
968
                if (rcvrc <= 1)
969
                    rcvrc = CSR_RCVRL(s);
970
                nrda = s->rdra +
971
                    (CSR_RCVRL(s) - rcvrc) *
972
                    (BCR_SWSTYLE(s) ? 16 : 8 );
973
                RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
974
                if (rmd.rmd1.own) {                
975
#ifdef PCNET_DEBUG_RMD
976
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
977
                                rcvrc, CSR_RCVRC(s));
978
#endif
979
                    CSR_RCVRC(s) = rcvrc;
980
                    pcnet_rdte_poll(s);
981
                    break;
982
                }
983
            }
984
        }
985

    
986
        if (!(CSR_CRST(s) & 0x8000)) {
987
#ifdef PCNET_DEBUG_RMD
988
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
989
#endif
990
            s->csr[0] |= 0x1000; /* Set MISS flag */
991
            CSR_MISSC(s)++;
992
        } else {
993
            uint8_t *src = &s->buffer[8];
994
            target_phys_addr_t crda = CSR_CRDA(s);
995
            struct pcnet_RMD rmd;
996
            int pktcount = 0;
997

    
998
            memcpy(src, buf, size);
999
            
1000
#if 1
1001
            /* no need to compute the CRC */
1002
            src[size] = 0;
1003
            src[size + 1] = 0;
1004
            src[size + 2] = 0;
1005
            src[size + 3] = 0;
1006
            size += 4;
1007
#else
1008
            /* XXX: avoid CRC generation */
1009
            if (!CSR_ASTRP_RCV(s)) {
1010
                uint32_t fcs = ~0;
1011
                uint8_t *p = src;
1012

    
1013
                while (size < 46) {
1014
                    src[size++] = 0;
1015
                }
1016
                
1017
                while (p != &src[size]) {
1018
                    CRC(fcs, *p++);
1019
                }
1020
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1021
                size += 4; /* FCS at end of packet */
1022
            } else size += 4;
1023
#endif
1024

    
1025
#ifdef PCNET_DEBUG_MATCH
1026
            PRINT_PKTHDR(buf);
1027
#endif
1028

    
1029
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1030
            /*if (!CSR_LAPPEN(s))*/
1031
                rmd.rmd1.stp = 1;
1032

    
1033
#define PCNET_RECV_STORE() do {                                 \
1034
    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
1035
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
1036
    cpu_physical_memory_write(rbadr, src, count);               \
1037
    src += count; size -= count;                                \
1038
    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
1039
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1040
    pktcount++;                                                 \
1041
} while (0)
1042

    
1043
            PCNET_RECV_STORE();
1044
            if ((size > 0) && CSR_NRDA(s)) {
1045
                target_phys_addr_t nrda = CSR_NRDA(s);
1046
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1047
                if (rmd.rmd1.own) {
1048
                    crda = nrda;
1049
                    PCNET_RECV_STORE();
1050
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1051
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1052
                        if (rmd.rmd1.own) {
1053
                            crda = nrda;
1054
                            PCNET_RECV_STORE();
1055
                        }
1056
                    }
1057
                }                
1058
            }
1059

    
1060
#undef PCNET_RECV_STORE
1061

    
1062
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1063
            if (size == 0) {
1064
                rmd.rmd1.enp = 1;
1065
                rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
1066
                rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
1067
                rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
1068
            } else {
1069
                rmd.rmd1.oflo = 1;
1070
                rmd.rmd1.buff = 1;
1071
                rmd.rmd1.err = 1;
1072
            }
1073
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1074
            s->csr[0] |= 0x0400;
1075

    
1076
#ifdef PCNET_DEBUG
1077
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1078
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1079
#endif
1080
#ifdef PCNET_DEBUG_RMD
1081
            PRINT_RMD(&rmd);
1082
#endif        
1083

    
1084
            while (pktcount--) {
1085
                if (CSR_RCVRC(s) <= 1)
1086
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1087
                else
1088
                    CSR_RCVRC(s)--;            
1089
            }
1090
            
1091
            pcnet_rdte_poll(s);
1092

    
1093
        }        
1094
    }
1095

    
1096
    pcnet_poll(s);
1097
    pcnet_update_irq(s);    
1098
}
1099

    
1100
static void pcnet_transmit(PCNetState *s)
1101
{
1102
    target_phys_addr_t xmit_cxda = 0;
1103
    int count = CSR_XMTRL(s)-1;
1104
    s->xmit_pos = -1;
1105
    
1106
    if (!CSR_TXON(s)) {
1107
        s->csr[0] &= ~0x0008;
1108
        return;
1109
    }
1110

    
1111
    s->tx_busy = 1;
1112

    
1113
    txagain:
1114
    if (pcnet_tdte_poll(s)) {
1115
        struct pcnet_TMD tmd;
1116

    
1117
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1118

    
1119
#ifdef PCNET_DEBUG_TMD
1120
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1121
        PRINT_TMD(&tmd);
1122
#endif
1123
        if (tmd.tmd1.stp) {
1124
            s->xmit_pos = 0;                
1125
            if (!tmd.tmd1.enp) {
1126
                cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
1127
                        s->buffer, 4096 - tmd.tmd1.bcnt);
1128
                s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1129
            } 
1130
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1131
        }
1132
        if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
1133
            cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
1134
                    s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
1135
            s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1136
#ifdef PCNET_DEBUG
1137
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1138
#endif            
1139
            if (CSR_LOOP(s))
1140
                pcnet_receive(s, s->buffer, s->xmit_pos);
1141
            else
1142
                qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1143

    
1144
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1145
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1146
            s->xmit_pos = -1;
1147
        }
1148

    
1149
        tmd.tmd1.own = 0;
1150
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1151
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
1152
            s->csr[0] |= 0x0200;    /* set TINT */
1153

    
1154
        if (CSR_XMTRC(s)<=1)
1155
            CSR_XMTRC(s) = CSR_XMTRL(s);
1156
        else
1157
            CSR_XMTRC(s)--;
1158
        if (count--)
1159
            goto txagain;
1160

    
1161
    } else 
1162
    if (s->xmit_pos >= 0) {
1163
        struct pcnet_TMD tmd;
1164
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
1165
        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
1166
        tmd.tmd1.own = 0;
1167
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1168
        s->csr[0] |= 0x0200;    /* set TINT */
1169
        if (!CSR_DXSUFLO(s)) {
1170
            s->csr[0] &= ~0x0010;
1171
        } else
1172
        if (count--)
1173
          goto txagain;
1174
    }
1175

    
1176
    s->tx_busy = 0;
1177
}
1178

    
1179
static void pcnet_poll(PCNetState *s)
1180
{
1181
    if (CSR_RXON(s)) {
1182
        pcnet_rdte_poll(s);
1183
    }
1184

    
1185
    if (CSR_TDMD(s) || 
1186
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1187
    {
1188
        /* prevent recursion */
1189
        if (s->tx_busy)
1190
            return;
1191

    
1192
        pcnet_transmit(s);
1193
    }
1194
}
1195

    
1196
static void pcnet_poll_timer(void *opaque)
1197
{
1198
    PCNetState *s = opaque;
1199

    
1200
    qemu_del_timer(s->poll_timer);
1201

    
1202
    if (CSR_TDMD(s)) {
1203
        pcnet_transmit(s);
1204
    }
1205

    
1206
    pcnet_update_irq(s);    
1207

    
1208
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1209
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1210
        if (!s->timer || !now)
1211
            s->timer = now;
1212
        else {
1213
            uint64_t t = now - s->timer + CSR_POLL(s);
1214
            if (t > 0xffffLL) {
1215
                pcnet_poll(s);
1216
                CSR_POLL(s) = CSR_PINT(s);
1217
            } else
1218
                CSR_POLL(s) = t;
1219
        }
1220
        qemu_mod_timer(s->poll_timer, 
1221
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1222
    }
1223
}
1224

    
1225

    
1226
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1227
{
1228
    uint16_t val = new_value;
1229
#ifdef PCNET_DEBUG_CSR
1230
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1231
#endif
1232
    switch (rap) {
1233
    case 0:
1234
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1235

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

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

    
1240
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1241
        if ((val&7) == 7)
1242
          val &= ~3;
1243

    
1244
        if (!CSR_STOP(s) && (val & 4))
1245
            pcnet_stop(s);
1246

    
1247
        if (!CSR_INIT(s) && (val & 1))
1248
            pcnet_init(s);
1249

    
1250
        if (!CSR_STRT(s) && (val & 2))
1251
            pcnet_start(s);
1252

    
1253
        if (CSR_TDMD(s)) 
1254
            pcnet_transmit(s);
1255

    
1256
        return;
1257
    case 1:
1258
    case 2:
1259
    case 8:
1260
    case 9:
1261
    case 10:
1262
    case 11:
1263
    case 12:
1264
    case 13:
1265
    case 14:
1266
    case 15:
1267
    case 18: /* CRBAL */
1268
    case 19: /* CRBAU */
1269
    case 20: /* CXBAL */
1270
    case 21: /* CXBAU */
1271
    case 22: /* NRBAU */
1272
    case 23: /* NRBAU */
1273
    case 24:
1274
    case 25:
1275
    case 26:
1276
    case 27:
1277
    case 28:
1278
    case 29:
1279
    case 30:
1280
    case 31:
1281
    case 32:
1282
    case 33:
1283
    case 34:
1284
    case 35:
1285
    case 36:
1286
    case 37:
1287
    case 38:
1288
    case 39:
1289
    case 40: /* CRBC */
1290
    case 41:
1291
    case 42: /* CXBC */
1292
    case 43:
1293
    case 44:
1294
    case 45:
1295
    case 46: /* POLL */
1296
    case 47: /* POLLINT */
1297
    case 72:
1298
    case 74:
1299
    case 76: /* RCVRL */
1300
    case 78: /* XMTRL */
1301
    case 112:
1302
       if (CSR_STOP(s) || CSR_SPND(s))
1303
           break;
1304
       return;
1305
    case 3:
1306
        break;
1307
    case 4:
1308
        s->csr[4] &= ~(val & 0x026a); 
1309
        val &= ~0x026a; val |= s->csr[4] & 0x026a;
1310
        break;
1311
    case 5:
1312
        s->csr[5] &= ~(val & 0x0a90); 
1313
        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1314
        break;
1315
    case 16:
1316
        pcnet_csr_writew(s,1,val);
1317
        return;
1318
    case 17:
1319
        pcnet_csr_writew(s,2,val);
1320
        return;
1321
    case 58:
1322
        pcnet_bcr_writew(s,BCR_SWS,val);
1323
        break;
1324
    default:
1325
        return;
1326
    }
1327
    s->csr[rap] = val;
1328
}
1329

    
1330
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1331
{
1332
    uint32_t val;
1333
    switch (rap) {
1334
    case 0:
1335
        pcnet_update_irq(s);
1336
        val = s->csr[0];
1337
        val |= (val & 0x7800) ? 0x8000 : 0;
1338
        break;
1339
    case 16:
1340
        return pcnet_csr_readw(s,1);
1341
    case 17:
1342
        return pcnet_csr_readw(s,2);
1343
    case 58:
1344
        return pcnet_bcr_readw(s,BCR_SWS);
1345
    case 88:
1346
        val = s->csr[89];
1347
        val <<= 16;
1348
        val |= s->csr[88];
1349
        break;
1350
    default:
1351
        val = s->csr[rap];
1352
    }
1353
#ifdef PCNET_DEBUG_CSR
1354
    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1355
#endif
1356
    return val;
1357
}
1358

    
1359
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1360
{
1361
    rap &= 127;
1362
#ifdef PCNET_DEBUG_BCR
1363
    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1364
#endif
1365
    switch (rap) {
1366
    case BCR_SWS:
1367
        if (!(CSR_STOP(s) || CSR_SPND(s)))
1368
            return;
1369
        val &= ~0x0300;
1370
        switch (val & 0x00ff) {
1371
        case 0:
1372
            val |= 0x0200;
1373
            break;
1374
        case 1:
1375
            val |= 0x0100;
1376
            break;
1377
        case 2:
1378
        case 3:
1379
            val |= 0x0300;
1380
            break;
1381
        default:
1382
            printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1383
            val = 0x0200;
1384
            break;
1385
        }
1386
#ifdef PCNET_DEBUG
1387
       printf("BCR_SWS=0x%04x\n", val);
1388
#endif
1389
    case BCR_LNKST:
1390
    case BCR_LED1:
1391
    case BCR_LED2:
1392
    case BCR_LED3:
1393
    case BCR_MC:
1394
    case BCR_FDC:
1395
    case BCR_BSBC:
1396
    case BCR_EECAS:
1397
    case BCR_PLAT:
1398
        s->bcr[rap] = val;
1399
        break;
1400
    default:
1401
        break;
1402
    }
1403
}
1404

    
1405
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1406
{
1407
    uint32_t val;
1408
    rap &= 127;
1409
    switch (rap) {
1410
    case BCR_LNKST:
1411
    case BCR_LED1:
1412
    case BCR_LED2:
1413
    case BCR_LED3:
1414
        val = s->bcr[rap] & ~0x8000;
1415
        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1416
        break;
1417
    default:
1418
        val = rap < 32 ? s->bcr[rap] : 0;
1419
        break;
1420
    }
1421
#ifdef PCNET_DEBUG_BCR
1422
    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1423
#endif
1424
    return val;
1425
}
1426

    
1427
static void pcnet_h_reset(PCNetState *s)
1428
{
1429
    int i;
1430
    uint16_t checksum;
1431

    
1432
    /* Initialize the PROM */
1433

    
1434
    memcpy(s->prom, s->nd->macaddr, 6);
1435
    s->prom[12] = s->prom[13] = 0x00;
1436
    s->prom[14] = s->prom[15] = 0x57;
1437

    
1438
    for (i = 0,checksum = 0; i < 16; i++)
1439
        checksum += s->prom[i];
1440
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1441

    
1442

    
1443
    s->bcr[BCR_MSRDA] = 0x0005;
1444
    s->bcr[BCR_MSWRA] = 0x0005;
1445
    s->bcr[BCR_MC   ] = 0x0002;
1446
    s->bcr[BCR_LNKST] = 0x00c0;
1447
    s->bcr[BCR_LED1 ] = 0x0084;
1448
    s->bcr[BCR_LED2 ] = 0x0088;
1449
    s->bcr[BCR_LED3 ] = 0x0090;
1450
    s->bcr[BCR_FDC  ] = 0x0000;
1451
    s->bcr[BCR_BSBC ] = 0x9001;
1452
    s->bcr[BCR_EECAS] = 0x0002;
1453
    s->bcr[BCR_SWS  ] = 0x0200;
1454
    s->bcr[BCR_PLAT ] = 0xff06;
1455

    
1456
    pcnet_s_reset(s);
1457
}
1458

    
1459
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1460
{
1461
    PCNetState *s = opaque;
1462
#ifdef PCNET_DEBUG
1463
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1464
#endif    
1465
    /* Check APROMWE bit to enable write access */
1466
    if (pcnet_bcr_readw(s,2) & 0x80)
1467
        s->prom[addr & 15] = val;
1468
}       
1469

    
1470
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1471
{
1472
    PCNetState *s = opaque;
1473
    uint32_t val = s->prom[addr &= 15];
1474
#ifdef PCNET_DEBUG
1475
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1476
#endif
1477
    return val;
1478
}
1479

    
1480
static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1481
{
1482
    PCNetState *s = opaque;
1483
    pcnet_poll_timer(s);
1484
#ifdef PCNET_DEBUG_IO
1485
    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1486
#endif
1487
    if (!BCR_DWIO(s)) {
1488
        switch (addr & 0x0f) {
1489
        case 0x00: /* RDP */
1490
            pcnet_csr_writew(s, s->rap, val);
1491
            break;
1492
        case 0x02:
1493
            s->rap = val & 0x7f;
1494
            break;
1495
        case 0x06:
1496
            pcnet_bcr_writew(s, s->rap, val);
1497
            break;
1498
        }
1499
    }
1500
    pcnet_update_irq(s);
1501
}
1502

    
1503
static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1504
{
1505
    PCNetState *s = opaque;
1506
    uint32_t val = -1;
1507
    pcnet_poll_timer(s);
1508
    if (!BCR_DWIO(s)) {
1509
        switch (addr & 0x0f) {
1510
        case 0x00: /* RDP */
1511
            val = pcnet_csr_readw(s, s->rap);
1512
            break;
1513
        case 0x02:
1514
            val = s->rap;
1515
            break;
1516
        case 0x04:
1517
            pcnet_s_reset(s);
1518
            val = 0;
1519
            break;
1520
        case 0x06:
1521
            val = pcnet_bcr_readw(s, s->rap);
1522
            break;
1523
        }
1524
    }
1525
    pcnet_update_irq(s);
1526
#ifdef PCNET_DEBUG_IO
1527
    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1528
#endif
1529
    return val;
1530
}
1531

    
1532
static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1533
{
1534
    PCNetState *s = opaque;
1535
    pcnet_poll_timer(s);
1536
#ifdef PCNET_DEBUG_IO
1537
    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1538
#endif
1539
    if (BCR_DWIO(s)) {
1540
        switch (addr & 0x0f) {
1541
        case 0x00: /* RDP */
1542
            pcnet_csr_writew(s, s->rap, val & 0xffff);
1543
            break;
1544
        case 0x04:
1545
            s->rap = val & 0x7f;
1546
            break;
1547
        case 0x0c:
1548
            pcnet_bcr_writew(s, s->rap, val & 0xffff);
1549
            break;
1550
        }
1551
    } else
1552
    if ((addr & 0x0f) == 0) {
1553
        /* switch device to dword i/o mode */
1554
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1555
#ifdef PCNET_DEBUG_IO
1556
        printf("device switched into dword i/o mode\n");
1557
#endif        
1558
    }
1559
    pcnet_update_irq(s);
1560
}
1561

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

    
1591
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, 
1592
                             uint32_t addr, uint32_t size, int type)
1593
{
1594
    PCNetState *d = (PCNetState *)pci_dev;
1595

    
1596
#ifdef PCNET_DEBUG_IO
1597
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1598
#endif
1599

    
1600
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1601
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1602
    
1603
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1604
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1605
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1606
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1607
}
1608

    
1609
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1610
{
1611
    PCNetState *d = opaque;
1612
#ifdef PCNET_DEBUG_IO
1613
    printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
1614
#endif
1615
    if (!(addr & 0x10))
1616
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1617
}
1618

    
1619
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr) 
1620
{
1621
    PCNetState *d = opaque;
1622
    uint32_t val = -1;
1623
    if (!(addr & 0x10))
1624
        val = pcnet_aprom_readb(d, addr & 0x0f);
1625
#ifdef PCNET_DEBUG_IO
1626
    printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
1627
#endif
1628
    return val;
1629
}
1630

    
1631
static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1632
{
1633
    PCNetState *d = opaque;
1634
#ifdef PCNET_DEBUG_IO
1635
    printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
1636
#endif
1637
    if (addr & 0x10)
1638
        pcnet_ioport_writew(d, addr & 0x0f, val);
1639
    else {
1640
        addr &= 0x0f;
1641
        pcnet_aprom_writeb(d, addr, val & 0xff);
1642
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1643
    }
1644
}
1645

    
1646
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr) 
1647
{
1648
    PCNetState *d = opaque;
1649
    uint32_t val = -1;
1650
    if (addr & 0x10)
1651
        val = pcnet_ioport_readw(d, addr & 0x0f);
1652
    else {
1653
        addr &= 0x0f;
1654
        val = pcnet_aprom_readb(d, addr+1);
1655
        val <<= 8;
1656
        val |= pcnet_aprom_readb(d, addr);
1657
    }
1658
#ifdef PCNET_DEBUG_IO
1659
    printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
1660
#endif
1661
    return val;
1662
}
1663

    
1664
static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1665
{
1666
    PCNetState *d = opaque;
1667
#ifdef PCNET_DEBUG_IO
1668
    printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
1669
#endif
1670
    if (addr & 0x10)
1671
        pcnet_ioport_writel(d, addr & 0x0f, val);
1672
    else {
1673
        addr &= 0x0f;
1674
        pcnet_aprom_writeb(d, addr, val & 0xff);
1675
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1676
        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1677
        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1678
    }
1679
}
1680

    
1681
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) 
1682
{
1683
    PCNetState *d = opaque;
1684
    uint32_t val;
1685
    if (addr & 0x10)
1686
        val = pcnet_ioport_readl(d, addr & 0x0f);
1687
    else {
1688
        addr &= 0x0f;
1689
        val = pcnet_aprom_readb(d, addr+3);
1690
        val <<= 8;
1691
        val |= pcnet_aprom_readb(d, addr+2);
1692
        val <<= 8;
1693
        val |= pcnet_aprom_readb(d, addr+1);
1694
        val <<= 8;
1695
        val |= pcnet_aprom_readb(d, addr);
1696
    }
1697
#ifdef PCNET_DEBUG_IO
1698
    printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
1699
#endif
1700
    return val;
1701
}
1702

    
1703

    
1704
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1705
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1706
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1707
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1708
};
1709

    
1710
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1711
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1712
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1713
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1714
};
1715

    
1716
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, 
1717
                            uint32_t addr, uint32_t size, int type)
1718
{
1719
    PCNetState *d = (PCNetState *)pci_dev;
1720

    
1721
#ifdef PCNET_DEBUG_IO
1722
    printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
1723
#endif
1724

    
1725
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
1726
}
1727

    
1728
void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
1729
{
1730
    PCNetState *d;
1731
    uint8_t *pci_conf;
1732

    
1733
#if 0
1734
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
1735
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1736
#endif
1737

    
1738
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1739
                                          -1, NULL, NULL);
1740
                                          
1741
    pci_conf = d->dev.config;
1742
    
1743
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1744
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);    
1745
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007); 
1746
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1747
    pci_conf[0x08] = 0x10;
1748
    pci_conf[0x09] = 0x00;
1749
    pci_conf[0x0a] = 0x00; // ethernet network controller 
1750
    pci_conf[0x0b] = 0x02;
1751
    pci_conf[0x0e] = 0x00; // header_type
1752
    
1753
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1754
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1755
    
1756
    pci_conf[0x3d] = 1; // interrupt pin 0
1757
    pci_conf[0x3e] = 0x06;
1758
    pci_conf[0x3f] = 0xff;
1759

    
1760
    /* Handler for memory-mapped I/O */
1761
    d->mmio_io_addr =
1762
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1763

    
1764
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, 
1765
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1766
                           
1767
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 
1768
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
1769
                           
1770
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1771

    
1772
    d->nd = nd;
1773

    
1774
    d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
1775
                                 pcnet_can_receive, d);
1776
    
1777
    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1778
             "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1779
             d->nd->macaddr[0],
1780
             d->nd->macaddr[1],
1781
             d->nd->macaddr[2],
1782
             d->nd->macaddr[3],
1783
             d->nd->macaddr[4],
1784
             d->nd->macaddr[5]);
1785

    
1786
    pcnet_h_reset(d);
1787
}