Revision e3c2613f

b/Makefile.target
329 329
VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
330 330

  
331 331
# PCI network cards
332
VL_OBJS+= ne2000.o rtl8139.o
332
VL_OBJS+= ne2000.o rtl8139.o pcnet.o
333 333

  
334 334
ifeq ($(TARGET_BASE_ARCH), i386)
335 335
# Hardware support
b/hw/pci.c
493 493
        pci_ne2000_init(bus, nd);
494 494
    } else if (strcmp(nd->model, "rtl8139") == 0) {
495 495
        pci_rtl8139_init(bus, nd);
496
    } else if (strcmp(nd->model, "pcnet") == 0) {
497
        pci_pcnet_init(bus, nd);
496 498
    } else {
497 499
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
498 500
        exit (1);
b/hw/pcnet.c
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
/* XXX: suppress those headers */
33
#include <sys/times.h>
34
#include <arpa/inet.h>
35
#include <net/ethernet.h>
36

  
37
//#define PCNET_DEBUG
38
//#define PCNET_DEBUG_IO
39
//#define PCNET_DEBUG_BCR
40
//#define PCNET_DEBUG_CSR
41
//#define PCNET_DEBUG_RMD
42
//#define PCNET_DEBUG_TMD
43
//#define PCNET_DEBUG_MATCH
44

  
45

  
46
#define PCNET_IOPORT_SIZE       0x20
47
#define PCNET_PNPMMIO_SIZE      0x20
48

  
49

  
50
typedef struct PCNetState_st PCNetState;
51

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

  
67
#ifdef __GNUC__
68
#define PACKED(A) A __attribute__ ((packed))
69
#else
70
#error FixMe
71
#endif
72

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

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

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

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

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

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

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

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

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

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

  
217

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

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

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

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

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

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

  
359

  
360
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
361

  
362
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
363

  
364
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
365

  
366
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
367

  
368
#if 1
369

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

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

  
383
#else
384

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

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

  
441
#endif
442

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

  
456
#define MULTICAST_FILTER_LEN 8
457

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

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

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

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

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

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

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

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

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

  
612
static void pcnet_poll(PCNetState *s);
613
static void pcnet_poll_timer(void *opaque);
614

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

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

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

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

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

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

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

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

  
762
#undef PCNET_INIT
763

  
764
    CSR_RCVRC(s) = CSR_RCVRL(s);
765
    CSR_XMTRC(s) = CSR_XMTRL(s);
766

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

  
773
    s->csr[0] |= 0x0101;    
774
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
775
}
776

  
777
static void pcnet_start(PCNetState *s)
778
{
779
#ifdef PCNET_DEBUG
780
    printf("pcnet_start\n");
781
#endif
782

  
783
    if (!CSR_DTX(s))
784
        s->csr[0] |= 0x0010;    /* set TXON */
785
        
786
    if (!CSR_DRX(s))
787
        s->csr[0] |= 0x0020;    /* set RXON */
788

  
789
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
790
    s->csr[0] |= 0x0002;
791
}
792

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

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

  
828
        CHECK_RMD(PHYSADDR(s,crda), bad);
829
        if (!bad) {
830
            CHECK_RMD(PHYSADDR(s,nrda), bad);
831
            if (bad || (nrda == crda)) nrda = 0;
832
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
833
            if (bad || (nnrd == crda)) nnrd = 0;
834

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

  
876
}
877

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

  
903
    if (CSR_CXDA(s)) {
904
        struct pcnet_TMD tmd;
905

  
906
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
907

  
908
        CSR_CXBC(s) = tmd.tmd1.bcnt;
909
        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
910
    } else {
911
        CSR_CXBC(s) = CSR_CXST(s) = 0;
912
    }
913
    
914
    return !!(CSR_CXST(s) & 0x8000);
915
}
916

  
917
static int pcnet_can_receive(void *opaque)
918
{
919
    PCNetState *s = opaque;
920
    if (CSR_STOP(s) || CSR_SPND(s))
921
        return 0;
922
        
923
    if (s->recv_pos > 0)
924
        return 0;
925

  
926
    return sizeof(s->buffer)-16;
927
}
928

  
929
#define MIN_BUF_SIZE 60
930

  
931
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
932
{
933
    PCNetState *s = opaque;
934
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
935
    uint8_t buf1[60];
936

  
937
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
938
        return;
939

  
940
#ifdef PCNET_DEBUG
941
    printf("pcnet_receive size=%d\n", size);
942
#endif
943

  
944
    /* if too small buffer, then expand it */
945
    if (size < MIN_BUF_SIZE) {
946
        memcpy(buf1, buf, size);
947
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
948
        buf = buf1;
949
        size = MIN_BUF_SIZE;
950
    }
951

  
952
    if (CSR_PROM(s) 
953
        || (is_padr=padr_match(s, buf, size)) 
954
        || (is_bcast=padr_bcast(s, buf, size))
955
        || (is_ladr=ladr_match(s, buf, size))) {
956

  
957
        pcnet_rdte_poll(s);
958

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

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

  
994
            memcpy(src, buf, size);
995
            
996
            /* XXX: avoid CRC generation */
997
            if (!CSR_ASTRP_RCV(s)) {
998
                uint32_t fcs = ~0;
999
#if 0            
1000
                uint8_t *p = s->buffer;
1001
                
1002
                ((uint32_t *)p)[0] = ((uint32_t *)p)[1] = 0xaaaaaaaa;
1003
                p[7] = 0xab;
1004
#else
1005
                uint8_t *p = src;
1006
#endif
1007

  
1008
                while (size < 46) {
1009
                    src[size++] = 0;
1010
                }
1011
                
1012
                while (p != &src[size]) {
1013
                    CRC(fcs, *p++);
1014
                }
1015
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1016
                size += 4; /* FCS at end of packet */
1017
            } else size += 4;
1018

  
1019
#ifdef PCNET_DEBUG_MATCH
1020
            PRINT_PKTHDR(buf);
1021
#endif
1022

  
1023
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1024
            /*if (!CSR_LAPPEN(s))*/
1025
                rmd.rmd1.stp = 1;
1026

  
1027
#define PCNET_RECV_STORE() do {                                 \
1028
    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
1029
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
1030
    cpu_physical_memory_write(rbadr, src, count);               \
1031
    src += count; size -= count;                                \
1032
    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
1033
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1034
    pktcount++;                                                 \
1035
} while (0)
1036

  
1037
            PCNET_RECV_STORE();
1038
            if ((size > 0) && CSR_NRDA(s)) {
1039
                target_phys_addr_t nrda = CSR_NRDA(s);
1040
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1041
                if (rmd.rmd1.own) {
1042
                    crda = nrda;
1043
                    PCNET_RECV_STORE();
1044
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1045
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1046
                        if (rmd.rmd1.own) {
1047
                            crda = nrda;
1048
                            PCNET_RECV_STORE();
1049
                        }
1050
                    }
1051
                }                
1052
            }
1053

  
1054
#undef PCNET_RECV_STORE
1055

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

  
1070
#ifdef PCNET_DEBUG
1071
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1072
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1073
#endif
1074
#ifdef PCNET_DEBUG_RMD
1075
            PRINT_RMD(&rmd);
1076
#endif        
1077

  
1078
            while (pktcount--) {
1079
                if (CSR_RCVRC(s) <= 1)
1080
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1081
                else
1082
                    CSR_RCVRC(s)--;            
1083
            }
1084
            
1085
            pcnet_rdte_poll(s);
1086

  
1087
        }        
1088
    }
1089

  
1090
    pcnet_poll(s);
1091
    pcnet_update_irq(s);    
1092
}
1093

  
1094
static void pcnet_transmit(PCNetState *s)
1095
{
1096
    target_phys_addr_t xmit_cxda = 0;
1097
    int count = CSR_XMTRL(s)-1;
1098
    s->xmit_pos = -1;
1099
    
1100
    if (!CSR_TXON(s)) {
1101
        s->csr[0] &= ~0x0008;
1102
        return;
1103
    }
1104
    
1105
    txagain:
1106
    if (pcnet_tdte_poll(s)) {
1107
        struct pcnet_TMD tmd;
1108

  
1109
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1110

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

  
1136
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1137
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1138
            s->xmit_pos = -1;
1139
        }
1140

  
1141
        tmd.tmd1.own = 0;
1142
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1143
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
1144
            s->csr[0] |= 0x0200;    /* set TINT */
1145

  
1146
        if (CSR_XMTRC(s)<=1)
1147
            CSR_XMTRC(s) = CSR_XMTRL(s);
1148
        else
1149
            CSR_XMTRC(s)--;
1150
        if (count--)
1151
            goto txagain;
1152

  
1153
    } else 
1154
    if (s->xmit_pos >= 0) {
1155
        struct pcnet_TMD tmd;
1156
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
1157
        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
1158
        tmd.tmd1.own = 0;
1159
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1160
        s->csr[0] |= 0x0200;    /* set TINT */
1161
        if (!CSR_DXSUFLO(s)) {
1162
            s->csr[0] &= ~0x0010;
1163
        } else
1164
        if (count--)
1165
          goto txagain;
1166
    }
1167
}
1168

  
1169
static void pcnet_poll(PCNetState *s)
1170
{
1171
    if (CSR_RXON(s)) {
1172
        pcnet_rdte_poll(s);
1173
    }
1174

  
1175
    if (CSR_TDMD(s) || 
1176
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1177
        pcnet_transmit(s);
1178
}
1179

  
1180
static void pcnet_poll_timer(void *opaque)
1181
{
1182
    PCNetState *s = opaque;
1183

  
1184
    qemu_del_timer(s->poll_timer);
1185

  
1186
    if (CSR_TDMD(s)) {
1187
        pcnet_transmit(s);
1188
    }
1189

  
1190
    pcnet_update_irq(s);    
1191

  
1192
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1193
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1194
        if (!s->timer || !now)
1195
            s->timer = now;
1196
        else {
1197
            uint64_t t = now - s->timer + CSR_POLL(s);
1198
            if (t > 0xffffLL) {
1199
                pcnet_poll(s);
1200
                CSR_POLL(s) = CSR_PINT(s);
1201
            } else
1202
                CSR_POLL(s) = t;
1203
        }
1204
        qemu_mod_timer(s->poll_timer, 
1205
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1206
    }
1207
}
1208

  
1209

  
1210
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1211
{
1212
    uint16_t val = new_value;
1213
#ifdef PCNET_DEBUG_CSR
1214
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1215
#endif
1216
    switch (rap) {
1217
    case 0:
1218
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1219

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

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

  
1224
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1225
        if ((val&7) == 7)
1226
          val &= ~3;
1227

  
1228
        if (!CSR_STOP(s) && (val & 4))
1229
            pcnet_stop(s);
1230

  
1231
        if (!CSR_INIT(s) && (val & 1))
1232
            pcnet_init(s);
1233

  
1234
        if (!CSR_STRT(s) && (val & 2))
1235
            pcnet_start(s);
1236

  
1237
        if (CSR_TDMD(s)) 
1238
            pcnet_transmit(s);
1239

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

  
1314
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1315
{
1316
    uint32_t val;
1317
    switch (rap) {
1318
    case 0:
1319
        pcnet_update_irq(s);
1320
        val = s->csr[0];
1321
        val |= (val & 0x7800) ? 0x8000 : 0;
1322
        break;
1323
    case 16:
1324
        return pcnet_csr_readw(s,1);
1325
    case 17:
1326
        return pcnet_csr_readw(s,2);
1327
    case 58:
1328
        return pcnet_bcr_readw(s,BCR_SWS);
1329
    case 88:
1330
        val = s->csr[89];
1331
        val <<= 16;
1332
        val |= s->csr[88];
1333
        break;
1334
    default:
1335
        val = s->csr[rap];
1336
    }
1337
#ifdef PCNET_DEBUG_CSR
1338
    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1339
#endif
1340
    return val;
1341
}
1342

  
1343
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1344
{
1345
    rap &= 127;
1346
#ifdef PCNET_DEBUG_BCR
1347
    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1348
#endif
1349
    switch (rap) {
1350
    case BCR_SWS:
1351
        if (!(CSR_STOP(s) || CSR_SPND(s)))
1352
            return;
1353
        val &= ~0x0300;
1354
        switch (val & 0x00ff) {
1355
        case 0:
1356
            val |= 0x0200;
1357
            break;
1358
        case 1:
1359
            val |= 0x0100;
1360
            break;
1361
        case 2:
1362
        case 3:
1363
            val |= 0x0300;
1364
            break;
1365
        default:
1366
            printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1367
            val = 0x0200;
1368
            break;
1369
        }
1370
#ifdef PCNET_DEBUG
1371
       printf("BCR_SWS=0x%04x\n", val);
1372
#endif
1373
    case BCR_LNKST:
1374
    case BCR_LED1:
1375
    case BCR_LED2:
1376
    case BCR_LED3:
1377
    case BCR_MC:
1378
    case BCR_FDC:
1379
    case BCR_BSBC:
1380
    case BCR_EECAS:
1381
    case BCR_PLAT:
1382
        s->bcr[rap] = val;
1383
        break;
1384
    default:
1385
        break;
1386
    }
1387
}
1388

  
1389
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1390
{
1391
    uint32_t val;
1392
    rap &= 127;
1393
    switch (rap) {
1394
    case BCR_LNKST:
1395
    case BCR_LED1:
1396
    case BCR_LED2:
1397
    case BCR_LED3:
1398
        val = s->bcr[rap] & ~0x8000;
1399
        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1400
        break;
1401
    default:
1402
        val = rap < 32 ? s->bcr[rap] : 0;
1403
        break;
1404
    }
1405
#ifdef PCNET_DEBUG_BCR
1406
    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1407
#endif
1408
    return val;
1409
}
1410

  
1411
static void pcnet_h_reset(PCNetState *s)
1412
{
1413
    int i;
1414
    uint16_t checksum;
1415

  
1416
    /* Initialize the PROM */
1417

  
1418
    memcpy(s->prom, s->nd->macaddr, 6);
1419
    s->prom[12] = s->prom[13] = 0x00;
1420
    s->prom[14] = s->prom[15] = 0x57;
1421

  
1422
    for (i = 0,checksum = 0; i < 16; i++)
1423
        checksum += s->prom[i];
1424
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1425

  
1426

  
1427
    s->bcr[BCR_MSRDA] = 0x0005;
1428
    s->bcr[BCR_MSWRA] = 0x0005;
1429
    s->bcr[BCR_MC   ] = 0x0002;
1430
    s->bcr[BCR_LNKST] = 0x00c0;
1431
    s->bcr[BCR_LED1 ] = 0x0084;
1432
    s->bcr[BCR_LED2 ] = 0x0088;
1433
    s->bcr[BCR_LED3 ] = 0x0090;
1434
    s->bcr[BCR_FDC  ] = 0x0000;
1435
    s->bcr[BCR_BSBC ] = 0x9001;
1436
    s->bcr[BCR_EECAS] = 0x0002;
1437
    s->bcr[BCR_SWS  ] = 0x0200;
1438
    s->bcr[BCR_PLAT ] = 0xff06;
1439

  
1440
    pcnet_s_reset(s);
1441
}
1442

  
1443
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1444
{
1445
    PCNetState *s = opaque;
1446
#ifdef PCNET_DEBUG
1447
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1448
#endif    
1449
    /* Check APROMWE bit to enable write access */
1450
    if (pcnet_bcr_readw(s,2) & 0x80)
1451
        s->prom[addr & 15] = val;
1452
}       
1453

  
1454
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1455
{
1456
    PCNetState *s = opaque;
1457
    uint32_t val = s->prom[addr &= 15];
1458
#ifdef PCNET_DEBUG
1459
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1460
#endif
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff