Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 3b46e624

History | View | Annotate | Download (62.5 kB)

1
/*
2
 * QEMU AMD PC-Net II (Am79C970A) emulation
3
 *
4
 * Copyright (c) 2004 Antony T Curtis
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
/* This software was written to be compatible with the specification:
26
 * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
27
 * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
28
 */
29

    
30
/*
31
 * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
32
 * produced as NCR89C100. See
33
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
34
 * and
35
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
36
 */
37

    
38
#include "vl.h"
39

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

    
48

    
49
#define PCNET_IOPORT_SIZE       0x20
50
#define PCNET_PNPMMIO_SIZE      0x20
51

    
52

    
53
typedef struct PCNetState_st PCNetState;
54

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

    
78
struct qemu_ether_header {
79
    uint8_t ether_dhost[6];
80
    uint8_t ether_shost[6];
81
    uint16_t ether_type;
82
};
83

    
84
/* BUS CONFIGURATION REGISTERS */
85
#define BCR_MSRDA    0
86
#define BCR_MSWRA    1
87
#define BCR_MC       2
88
#define BCR_LNKST    4
89
#define BCR_LED1     5
90
#define BCR_LED2     6
91
#define BCR_LED3     7
92
#define BCR_FDC      9
93
#define BCR_BSBC     18
94
#define BCR_EECAS    19
95
#define BCR_SWS      20
96
#define BCR_PLAT     22
97

    
98
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
99
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
100
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
101

    
102
#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
103
#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
104
#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
105
#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
106
#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
107
#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
108
#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
109
#define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
110
#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
111
#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
112
#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
113
#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
114
#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
115
#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
116
#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
117
#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
118
#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
119
#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
120
#define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
121
#define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
122
#define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
123

    
124
#define CSR_CRBC(S)      ((S)->csr[40])
125
#define CSR_CRST(S)      ((S)->csr[41])
126
#define CSR_CXBC(S)      ((S)->csr[42])
127
#define CSR_CXST(S)      ((S)->csr[43])
128
#define CSR_NRBC(S)      ((S)->csr[44])
129
#define CSR_NRST(S)      ((S)->csr[45])
130
#define CSR_POLL(S)      ((S)->csr[46])
131
#define CSR_PINT(S)      ((S)->csr[47])
132
#define CSR_RCVRC(S)     ((S)->csr[72])
133
#define CSR_XMTRC(S)     ((S)->csr[74])
134
#define CSR_RCVRL(S)     ((S)->csr[76])
135
#define CSR_XMTRL(S)     ((S)->csr[78])
136
#define CSR_MISSC(S)     ((S)->csr[112])
137

    
138
#define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
139
#define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
140
#define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
141
#define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
142
#define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
143
#define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
144
#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
145
#define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
146
#define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
147
#define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
148
#define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
149
#define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
150
#define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
151
#define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
152

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

    
156
struct pcnet_initblk16 {
157
    uint16_t mode;
158
    uint16_t padr[3];
159
    uint16_t ladrf[4];
160
    uint32_t rdra;
161
    uint32_t tdra;
162
};
163

    
164
struct pcnet_initblk32 {
165
    uint16_t mode;
166
    uint8_t rlen;
167
    uint8_t tlen;
168
    uint16_t padr[3];
169
    uint16_t _res;
170
    uint16_t ladrf[4];
171
    uint32_t rdra;
172
    uint32_t tdra;
173
};
174

    
175
struct pcnet_TMD {
176
    uint32_t tbadr;
177
    int16_t length;
178
    int16_t status;
179
    uint32_t misc;
180
    uint32_t res;
181
};
182

    
183
#define TMDL_BCNT_MASK  0x0fff
184
#define TMDL_BCNT_SH    0
185
#define TMDL_ONES_MASK  0xf000
186
#define TMDL_ONES_SH    12
187

    
188
#define TMDS_BPE_MASK   0x0080
189
#define TMDS_BPE_SH     7
190
#define TMDS_ENP_MASK   0x0100
191
#define TMDS_ENP_SH     8
192
#define TMDS_STP_MASK   0x0200
193
#define TMDS_STP_SH     9
194
#define TMDS_DEF_MASK   0x0400
195
#define TMDS_DEF_SH     10
196
#define TMDS_ONE_MASK   0x0800
197
#define TMDS_ONE_SH     11
198
#define TMDS_LTINT_MASK 0x1000
199
#define TMDS_LTINT_SH   12
200
#define TMDS_NOFCS_MASK 0x2000
201
#define TMDS_NOFCS_SH   13
202
#define TMDS_ERR_MASK   0x4000
203
#define TMDS_ERR_SH     14
204
#define TMDS_OWN_MASK   0x8000
205
#define TMDS_OWN_SH     15
206

    
207
#define TMDM_TRC_MASK   0x0000000f
208
#define TMDM_TRC_SH     0
209
#define TMDM_TDR_MASK   0x03ff0000
210
#define TMDM_TDR_SH     16
211
#define TMDM_RTRY_MASK  0x04000000
212
#define TMDM_RTRY_SH    26
213
#define TMDM_LCAR_MASK  0x08000000
214
#define TMDM_LCAR_SH    27
215
#define TMDM_LCOL_MASK  0x10000000
216
#define TMDM_LCOL_SH    28
217
#define TMDM_EXDEF_MASK 0x20000000
218
#define TMDM_EXDEF_SH   29
219
#define TMDM_UFLO_MASK  0x40000000
220
#define TMDM_UFLO_SH    30
221
#define TMDM_BUFF_MASK  0x80000000
222
#define TMDM_BUFF_SH    31
223

    
224
struct pcnet_RMD {
225
    uint32_t rbadr;
226
    int16_t buf_length;
227
    int16_t status;
228
    uint32_t msg_length;
229
    uint32_t res;
230
};
231

    
232
#define RMDL_BCNT_MASK  0x0fff
233
#define RMDL_BCNT_SH    0
234
#define RMDL_ONES_MASK  0xf000
235
#define RMDL_ONES_SH    12
236

    
237
#define RMDS_BAM_MASK   0x0010
238
#define RMDS_BAM_SH     4
239
#define RMDS_LFAM_MASK  0x0020
240
#define RMDS_LFAM_SH    5
241
#define RMDS_PAM_MASK   0x0040
242
#define RMDS_PAM_SH     6
243
#define RMDS_BPE_MASK   0x0080
244
#define RMDS_BPE_SH     7
245
#define RMDS_ENP_MASK   0x0100
246
#define RMDS_ENP_SH     8
247
#define RMDS_STP_MASK   0x0200
248
#define RMDS_STP_SH     9
249
#define RMDS_BUFF_MASK  0x0400
250
#define RMDS_BUFF_SH    10
251
#define RMDS_CRC_MASK   0x0800
252
#define RMDS_CRC_SH     11
253
#define RMDS_OFLO_MASK  0x1000
254
#define RMDS_OFLO_SH    12
255
#define RMDS_FRAM_MASK  0x2000
256
#define RMDS_FRAM_SH    13
257
#define RMDS_ERR_MASK   0x4000
258
#define RMDS_ERR_SH     14
259
#define RMDS_OWN_MASK   0x8000
260
#define RMDS_OWN_SH     15
261

    
262
#define RMDM_MCNT_MASK  0x00000fff
263
#define RMDM_MCNT_SH    0
264
#define RMDM_ZEROS_MASK 0x0000f000
265
#define RMDM_ZEROS_SH   12
266
#define RMDM_RPC_MASK   0x00ff0000
267
#define RMDM_RPC_SH     16
268
#define RMDM_RCC_MASK   0xff000000
269
#define RMDM_RCC_SH     24
270

    
271
#define SET_FIELD(regp, name, field, value)             \
272
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
273
             | ((value) << name ## _ ## field ## _SH))
274

    
275
#define GET_FIELD(reg, name, field)                     \
276
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
277

    
278
#define PRINT_TMD(T) printf(                            \
279
        "TMD0 : TBADR=0x%08x\n"                         \
280
        "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
281
        "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
282
        "       BPE=%d, BCNT=%d\n"                      \
283
        "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
284
        "LCA=%d, RTR=%d,\n"                             \
285
        "       TDR=%d, TRC=%d\n",                      \
286
        (T)->tbadr,                                     \
287
        GET_FIELD((T)->status, TMDS, OWN),              \
288
        GET_FIELD((T)->status, TMDS, ERR),              \
289
        GET_FIELD((T)->status, TMDS, NOFCS),            \
290
        GET_FIELD((T)->status, TMDS, LTINT),            \
291
        GET_FIELD((T)->status, TMDS, ONE),              \
292
        GET_FIELD((T)->status, TMDS, DEF),              \
293
        GET_FIELD((T)->status, TMDS, STP),              \
294
        GET_FIELD((T)->status, TMDS, ENP),              \
295
        GET_FIELD((T)->status, TMDS, BPE),              \
296
        4096-GET_FIELD((T)->length, TMDL, BCNT),        \
297
        GET_FIELD((T)->misc, TMDM, BUFF),               \
298
        GET_FIELD((T)->misc, TMDM, UFLO),               \
299
        GET_FIELD((T)->misc, TMDM, EXDEF),              \
300
        GET_FIELD((T)->misc, TMDM, LCOL),               \
301
        GET_FIELD((T)->misc, TMDM, LCAR),               \
302
        GET_FIELD((T)->misc, TMDM, RTRY),               \
303
        GET_FIELD((T)->misc, TMDM, TDR),                \
304
        GET_FIELD((T)->misc, TMDM, TRC))
305

    
306
#define PRINT_RMD(R) printf(                            \
307
        "RMD0 : RBADR=0x%08x\n"                         \
308
        "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
309
        "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
310
        "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
311
        "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
312
        (R)->rbadr,                                     \
313
        GET_FIELD((R)->status, RMDS, OWN),              \
314
        GET_FIELD((R)->status, RMDS, ERR),              \
315
        GET_FIELD((R)->status, RMDS, FRAM),             \
316
        GET_FIELD((R)->status, RMDS, OFLO),             \
317
        GET_FIELD((R)->status, RMDS, CRC),              \
318
        GET_FIELD((R)->status, RMDS, BUFF),             \
319
        GET_FIELD((R)->status, RMDS, STP),              \
320
        GET_FIELD((R)->status, RMDS, ENP),              \
321
        GET_FIELD((R)->status, RMDS, BPE),              \
322
        GET_FIELD((R)->status, RMDS, PAM),              \
323
        GET_FIELD((R)->status, RMDS, LFAM),             \
324
        GET_FIELD((R)->status, RMDS, BAM),              \
325
        GET_FIELD((R)->buf_length, RMDL, ONES),         \
326
        4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
327
        GET_FIELD((R)->msg_length, RMDM, RCC),          \
328
        GET_FIELD((R)->msg_length, RMDM, RPC),          \
329
        GET_FIELD((R)->msg_length, RMDM, MCNT),         \
330
        GET_FIELD((R)->msg_length, RMDM, ZEROS))
331

    
332
static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
333
                                  target_phys_addr_t addr)
334
{
335
    if (!BCR_SSIZE32(s)) {
336
        struct {
337
            uint32_t tbadr;
338
            int16_t length;
339
            int16_t status;
340
        } xda;
341
        s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
342
        tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
343
        tmd->length = le16_to_cpu(xda.length);
344
        tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
345
        tmd->misc = le16_to_cpu(xda.status) << 16;
346
        tmd->res = 0;
347
    } else {
348
        s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
349
        le32_to_cpus(&tmd->tbadr);
350
        le16_to_cpus(&tmd->length);
351
        le16_to_cpus(&tmd->status);
352
        le32_to_cpus(&tmd->misc);
353
        le32_to_cpus(&tmd->res);
354
        if (BCR_SWSTYLE(s) == 3) {
355
            uint32_t tmp = tmd->tbadr;
356
            tmd->tbadr = tmd->misc;
357
            tmd->misc = tmp;
358
        }
359
    }
360
}
361

    
362
static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
363
                                   target_phys_addr_t addr)
364
{
365
    if (!BCR_SSIZE32(s)) {
366
        struct {
367
            uint32_t tbadr;
368
            int16_t length;
369
            int16_t status;
370
        } xda;
371
        xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
372
                                ((tmd->status & 0xff00) << 16));
373
        xda.length = cpu_to_le16(tmd->length);
374
        xda.status = cpu_to_le16(tmd->misc >> 16);
375
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
376
    } else {
377
        struct {
378
            uint32_t tbadr;
379
            int16_t length;
380
            int16_t status;
381
            uint32_t misc;
382
            uint32_t res;
383
        } xda;
384
        xda.tbadr = cpu_to_le32(tmd->tbadr);
385
        xda.length = cpu_to_le16(tmd->length);
386
        xda.status = cpu_to_le16(tmd->status);
387
        xda.misc = cpu_to_le32(tmd->misc);
388
        xda.res = cpu_to_le32(tmd->res);
389
        if (BCR_SWSTYLE(s) == 3) {
390
            uint32_t tmp = xda.tbadr;
391
            xda.tbadr = xda.misc;
392
            xda.misc = tmp;
393
        }
394
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
395
    }
396
}
397

    
398
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
399
                                  target_phys_addr_t addr)
400
{
401
    if (!BCR_SSIZE32(s)) {
402
        struct {
403
            uint32_t rbadr;
404
            int16_t buf_length;
405
            int16_t msg_length;
406
        } rda;
407
        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
408
        rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
409
        rmd->buf_length = le16_to_cpu(rda.buf_length);
410
        rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
411
        rmd->msg_length = le16_to_cpu(rda.msg_length);
412
        rmd->res = 0;
413
    } else {
414
        s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
415
        le32_to_cpus(&rmd->rbadr);
416
        le16_to_cpus(&rmd->buf_length);
417
        le16_to_cpus(&rmd->status);
418
        le32_to_cpus(&rmd->msg_length);
419
        le32_to_cpus(&rmd->res);
420
        if (BCR_SWSTYLE(s) == 3) {
421
            uint32_t tmp = rmd->rbadr;
422
            rmd->rbadr = rmd->msg_length;
423
            rmd->msg_length = tmp;
424
        }
425
    }
426
}
427

    
428
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
429
                                   target_phys_addr_t addr)
430
{
431
    if (!BCR_SSIZE32(s)) {
432
        struct {
433
            uint32_t rbadr;
434
            int16_t buf_length;
435
            int16_t msg_length;
436
        } rda;
437
        rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
438
                                ((rmd->status & 0xff00) << 16));
439
        rda.buf_length = cpu_to_le16(rmd->buf_length);
440
        rda.msg_length = cpu_to_le16(rmd->msg_length);
441
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
442
    } else {
443
        struct {
444
            uint32_t rbadr;
445
            int16_t buf_length;
446
            int16_t status;
447
            uint32_t msg_length;
448
            uint32_t res;
449
        } rda;
450
        rda.rbadr = cpu_to_le32(rmd->rbadr);
451
        rda.buf_length = cpu_to_le16(rmd->buf_length);
452
        rda.status = cpu_to_le16(rmd->status);
453
        rda.msg_length = cpu_to_le32(rmd->msg_length);
454
        rda.res = cpu_to_le32(rmd->res);
455
        if (BCR_SWSTYLE(s) == 3) {
456
            uint32_t tmp = rda.rbadr;
457
            rda.rbadr = rda.msg_length;
458
            rda.msg_length = tmp;
459
        }
460
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
461
    }
462
}
463

    
464

    
465
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
466

    
467
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
468

    
469
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
470

    
471
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
472

    
473
#if 1
474

    
475
#define CHECK_RMD(ADDR,RES) do {                \
476
    struct pcnet_RMD rmd;                       \
477
    RMDLOAD(&rmd,(ADDR));                       \
478
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
479
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
480
} while (0)
481

    
482
#define CHECK_TMD(ADDR,RES) do {                \
483
    struct pcnet_TMD tmd;                       \
484
    TMDLOAD(&tmd,(ADDR));                       \
485
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
486
} while (0)
487

    
488
#else
489

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

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

    
546
#endif
547

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

    
560
#define MULTICAST_FILTER_LEN 8
561

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

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

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

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

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

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

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

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

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

    
716
static void pcnet_poll(PCNetState *s);
717
static void pcnet_poll_timer(void *opaque);
718

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

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

    
730
    s->lnkst = 0x40;
731
    s->rdra = 0;
732
    s->tdra = 0;
733
    s->rap = 0;
734

    
735
    s->bcr[BCR_BSBC] &= ~0x0080;
736

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

    
766
    s->tx_busy = 0;
767
}
768

    
769
static void pcnet_update_irq(PCNetState *s)
770
{
771
    int isr = 0;
772
    s->csr[0] &= ~0x0080;
773

    
774
#if 1
775
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
776
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
777
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
778
#else
779
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
780
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
781
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
782
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
783
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
784
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
785
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
786
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
787
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
788
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
789
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
790
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
791
#endif
792
    {
793

    
794
        isr = CSR_INEA(s);
795
        s->csr[0] |= 0x0080;
796
    }
797

    
798
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
799
        s->csr[4] &= ~0x0080;
800
        s->csr[4] |= 0x0040;
801
        s->csr[0] |= 0x0080;
802
        isr = 1;
803
#ifdef PCNET_DEBUG
804
        printf("pcnet user int\n");
805
#endif
806
    }
807

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

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

    
828
static void pcnet_init(PCNetState *s)
829
{
830
    int rlen, tlen;
831
    uint16_t padr[3], ladrf[4], mode;
832
    uint32_t rdra, tdra;
833

    
834
#ifdef PCNET_DEBUG
835
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
836
#endif
837

    
838
    if (BCR_SSIZE32(s)) {
839
        struct pcnet_initblk32 initblk;
840
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
841
                (uint8_t *)&initblk, sizeof(initblk), 0);
842
        mode = le16_to_cpu(initblk.mode);
843
        rlen = initblk.rlen >> 4;
844
        tlen = initblk.tlen >> 4;
845
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
846
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
847
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
848
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
849
        padr[0] = le16_to_cpu(initblk.padr[0]);
850
        padr[1] = le16_to_cpu(initblk.padr[1]);
851
        padr[2] = le16_to_cpu(initblk.padr[2]);
852
        rdra = le32_to_cpu(initblk.rdra);
853
        tdra = le32_to_cpu(initblk.tdra);
854
    } else {
855
        struct pcnet_initblk16 initblk;
856
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
857
                (uint8_t *)&initblk, sizeof(initblk), 0);
858
        mode = le16_to_cpu(initblk.mode);
859
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
860
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
861
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
862
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
863
        padr[0] = le16_to_cpu(initblk.padr[0]);
864
        padr[1] = le16_to_cpu(initblk.padr[1]);
865
        padr[2] = le16_to_cpu(initblk.padr[2]);
866
        rdra = le32_to_cpu(initblk.rdra);
867
        tdra = le32_to_cpu(initblk.tdra);
868
        rlen = rdra >> 29;
869
        tlen = tdra >> 29;
870
        rdra &= 0x00ffffff;
871
        tdra &= 0x00ffffff;
872
    }
873

    
874
#if defined(PCNET_DEBUG)
875
    printf("rlen=%d tlen=%d\n", rlen, tlen);
876
#endif
877

    
878
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
879
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
880
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
881
    s->csr[15] = mode;
882
    s->csr[ 8] = ladrf[0];
883
    s->csr[ 9] = ladrf[1];
884
    s->csr[10] = ladrf[2];
885
    s->csr[11] = ladrf[3];
886
    s->csr[12] = padr[0];
887
    s->csr[13] = padr[1];
888
    s->csr[14] = padr[2];
889
    s->rdra = PHYSADDR(s, rdra);
890
    s->tdra = PHYSADDR(s, tdra);
891

    
892
    CSR_RCVRC(s) = CSR_RCVRL(s);
893
    CSR_XMTRC(s) = CSR_XMTRL(s);
894

    
895
#ifdef PCNET_DEBUG
896
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
897
        BCR_SSIZE32(s),
898
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
899
#endif
900

    
901
    s->csr[0] |= 0x0101;
902
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
903
}
904

    
905
static void pcnet_start(PCNetState *s)
906
{
907
#ifdef PCNET_DEBUG
908
    printf("pcnet_start\n");
909
#endif
910

    
911
    if (!CSR_DTX(s))
912
        s->csr[0] |= 0x0010;    /* set TXON */
913

    
914
    if (!CSR_DRX(s))
915
        s->csr[0] |= 0x0020;    /* set RXON */
916

    
917
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
918
    s->csr[0] |= 0x0002;
919
}
920

    
921
static void pcnet_stop(PCNetState *s)
922
{
923
#ifdef PCNET_DEBUG
924
    printf("pcnet_stop\n");
925
#endif
926
    s->csr[0] &= ~0x7feb;
927
    s->csr[0] |= 0x0014;
928
    s->csr[4] &= ~0x02c2;
929
    s->csr[5] &= ~0x0011;
930
    pcnet_poll_timer(s);
931
}
932

    
933
static void pcnet_rdte_poll(PCNetState *s)
934
{
935
    s->csr[28] = s->csr[29] = 0;
936
    if (s->rdra) {
937
        int bad = 0;
938
#if 1
939
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
940
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
941
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
942
#else
943
        target_phys_addr_t crda = s->rdra +
944
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
945
            (BCR_SWSTYLE(s) ? 16 : 8 );
946
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
947
        target_phys_addr_t nrda = s->rdra +
948
            (CSR_RCVRL(s) - nrdc) *
949
            (BCR_SWSTYLE(s) ? 16 : 8 );
950
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
951
        target_phys_addr_t nnrd = s->rdra +
952
            (CSR_RCVRL(s) - nnrc) *
953
            (BCR_SWSTYLE(s) ? 16 : 8 );
954
#endif
955

    
956
        CHECK_RMD(PHYSADDR(s,crda), bad);
957
        if (!bad) {
958
            CHECK_RMD(PHYSADDR(s,nrda), bad);
959
            if (bad || (nrda == crda)) nrda = 0;
960
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
961
            if (bad || (nnrd == crda)) nnrd = 0;
962

    
963
            s->csr[28] = crda & 0xffff;
964
            s->csr[29] = crda >> 16;
965
            s->csr[26] = nrda & 0xffff;
966
            s->csr[27] = nrda >> 16;
967
            s->csr[36] = nnrd & 0xffff;
968
            s->csr[37] = nnrd >> 16;
969
#ifdef PCNET_DEBUG
970
            if (bad) {
971
                printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
972
                       PHYSADDR(s,crda));
973
            }
974
        } else {
975
            printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
976
#endif
977
        }
978
    }
979

    
980
    if (CSR_CRDA(s)) {
981
        struct pcnet_RMD rmd;
982
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
983
        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
984
        CSR_CRST(s) = rmd.status;
985
#ifdef PCNET_DEBUG_RMD_X
986
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
987
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
988
                rmd.buf_length, rmd.status, rmd.msg_length);
989
        PRINT_RMD(&rmd);
990
#endif
991
    } else {
992
        CSR_CRBC(s) = CSR_CRST(s) = 0;
993
    }
994

    
995
    if (CSR_NRDA(s)) {
996
        struct pcnet_RMD rmd;
997
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
998
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
999
        CSR_NRST(s) = rmd.status;
1000
    } else {
1001
        CSR_NRBC(s) = CSR_NRST(s) = 0;
1002
    }
1003

    
1004
}
1005

    
1006
static int pcnet_tdte_poll(PCNetState *s)
1007
{
1008
    s->csr[34] = s->csr[35] = 0;
1009
    if (s->tdra) {
1010
        target_phys_addr_t cxda = s->tdra +
1011
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
1012
            (BCR_SWSTYLE(s) ? 16 : 8);
1013
        int bad = 0;
1014
        CHECK_TMD(PHYSADDR(s, cxda),bad);
1015
        if (!bad) {
1016
            if (CSR_CXDA(s) != cxda) {
1017
                s->csr[60] = s->csr[34];
1018
                s->csr[61] = s->csr[35];
1019
                s->csr[62] = CSR_CXBC(s);
1020
                s->csr[63] = CSR_CXST(s);
1021
            }
1022
            s->csr[34] = cxda & 0xffff;
1023
            s->csr[35] = cxda >> 16;
1024
#ifdef PCNET_DEBUG_X
1025
            printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
1026
#endif
1027
        }
1028
    }
1029

    
1030
    if (CSR_CXDA(s)) {
1031
        struct pcnet_TMD tmd;
1032

    
1033
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1034

    
1035
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1036
        CSR_CXST(s) = tmd.status;
1037
    } else {
1038
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1039
    }
1040

    
1041
    return !!(CSR_CXST(s) & 0x8000);
1042
}
1043

    
1044
static int pcnet_can_receive(void *opaque)
1045
{
1046
    PCNetState *s = opaque;
1047
    if (CSR_STOP(s) || CSR_SPND(s))
1048
        return 0;
1049

    
1050
    if (s->recv_pos > 0)
1051
        return 0;
1052

    
1053
    return sizeof(s->buffer)-16;
1054
}
1055

    
1056
#define MIN_BUF_SIZE 60
1057

    
1058
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
1059
{
1060
    PCNetState *s = opaque;
1061
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1062
    uint8_t buf1[60];
1063

    
1064
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1065
        return;
1066

    
1067
#ifdef PCNET_DEBUG
1068
    printf("pcnet_receive size=%d\n", size);
1069
#endif
1070

    
1071
    /* if too small buffer, then expand it */
1072
    if (size < MIN_BUF_SIZE) {
1073
        memcpy(buf1, buf, size);
1074
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1075
        buf = buf1;
1076
        size = MIN_BUF_SIZE;
1077
    }
1078

    
1079
    if (CSR_PROM(s)
1080
        || (is_padr=padr_match(s, buf, size))
1081
        || (is_bcast=padr_bcast(s, buf, size))
1082
        || (is_ladr=ladr_match(s, buf, size))) {
1083

    
1084
        pcnet_rdte_poll(s);
1085

    
1086
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1087
            struct pcnet_RMD rmd;
1088
            int rcvrc = CSR_RCVRC(s)-1,i;
1089
            target_phys_addr_t nrda;
1090
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1091
                if (rcvrc <= 1)
1092
                    rcvrc = CSR_RCVRL(s);
1093
                nrda = s->rdra +
1094
                    (CSR_RCVRL(s) - rcvrc) *
1095
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1096
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1097
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1098
#ifdef PCNET_DEBUG_RMD
1099
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1100
                                rcvrc, CSR_RCVRC(s));
1101
#endif
1102
                    CSR_RCVRC(s) = rcvrc;
1103
                    pcnet_rdte_poll(s);
1104
                    break;
1105
                }
1106
            }
1107
        }
1108

    
1109
        if (!(CSR_CRST(s) & 0x8000)) {
1110
#ifdef PCNET_DEBUG_RMD
1111
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1112
#endif
1113
            s->csr[0] |= 0x1000; /* Set MISS flag */
1114
            CSR_MISSC(s)++;
1115
        } else {
1116
            uint8_t *src = &s->buffer[8];
1117
            target_phys_addr_t crda = CSR_CRDA(s);
1118
            struct pcnet_RMD rmd;
1119
            int pktcount = 0;
1120

    
1121
            memcpy(src, buf, size);
1122

    
1123
#if 1
1124
            /* no need to compute the CRC */
1125
            src[size] = 0;
1126
            src[size + 1] = 0;
1127
            src[size + 2] = 0;
1128
            src[size + 3] = 0;
1129
            size += 4;
1130
#else
1131
            /* XXX: avoid CRC generation */
1132
            if (!CSR_ASTRP_RCV(s)) {
1133
                uint32_t fcs = ~0;
1134
                uint8_t *p = src;
1135

    
1136
                while (size < 46) {
1137
                    src[size++] = 0;
1138
                }
1139

    
1140
                while (p != &src[size]) {
1141
                    CRC(fcs, *p++);
1142
                }
1143
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1144
                size += 4; /* FCS at end of packet */
1145
            } else size += 4;
1146
#endif
1147

    
1148
#ifdef PCNET_DEBUG_MATCH
1149
            PRINT_PKTHDR(buf);
1150
#endif
1151

    
1152
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1153
            /*if (!CSR_LAPPEN(s))*/
1154
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1155

    
1156
#define PCNET_RECV_STORE() do {                                 \
1157
    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),size); \
1158
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \
1159
    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
1160
    src += count; size -= count;                                \
1161
    SET_FIELD(&rmd.msg_length, RMDM, MCNT, count);              \
1162
    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
1163
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1164
    pktcount++;                                                 \
1165
} while (0)
1166

    
1167
            PCNET_RECV_STORE();
1168
            if ((size > 0) && CSR_NRDA(s)) {
1169
                target_phys_addr_t nrda = CSR_NRDA(s);
1170
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1171
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1172
                    crda = nrda;
1173
                    PCNET_RECV_STORE();
1174
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1175
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1176
                        if (GET_FIELD(rmd.status, RMDS, OWN)) {
1177
                            crda = nrda;
1178
                            PCNET_RECV_STORE();
1179
                        }
1180
                    }
1181
                }
1182
            }
1183

    
1184
#undef PCNET_RECV_STORE
1185

    
1186
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1187
            if (size == 0) {
1188
                SET_FIELD(&rmd.status, RMDS, ENP, 1);
1189
                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
1190
                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
1191
                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
1192
            } else {
1193
                SET_FIELD(&rmd.status, RMDS, OFLO, 1);
1194
                SET_FIELD(&rmd.status, RMDS, BUFF, 1);
1195
                SET_FIELD(&rmd.status, RMDS, ERR, 1);
1196
            }
1197
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1198
            s->csr[0] |= 0x0400;
1199

    
1200
#ifdef PCNET_DEBUG
1201
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1202
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1203
#endif
1204
#ifdef PCNET_DEBUG_RMD
1205
            PRINT_RMD(&rmd);
1206
#endif
1207

    
1208
            while (pktcount--) {
1209
                if (CSR_RCVRC(s) <= 1)
1210
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1211
                else
1212
                    CSR_RCVRC(s)--;
1213
            }
1214

    
1215
            pcnet_rdte_poll(s);
1216

    
1217
        }
1218
    }
1219

    
1220
    pcnet_poll(s);
1221
    pcnet_update_irq(s);
1222
}
1223

    
1224
static void pcnet_transmit(PCNetState *s)
1225
{
1226
    target_phys_addr_t xmit_cxda = 0;
1227
    int count = CSR_XMTRL(s)-1;
1228
    s->xmit_pos = -1;
1229

    
1230
    if (!CSR_TXON(s)) {
1231
        s->csr[0] &= ~0x0008;
1232
        return;
1233
    }
1234

    
1235
    s->tx_busy = 1;
1236

    
1237
    txagain:
1238
    if (pcnet_tdte_poll(s)) {
1239
        struct pcnet_TMD tmd;
1240

    
1241
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1242

    
1243
#ifdef PCNET_DEBUG_TMD
1244
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1245
        PRINT_TMD(&tmd);
1246
#endif
1247
        if (GET_FIELD(tmd.status, TMDS, STP)) {
1248
            s->xmit_pos = 0;
1249
            if (!GET_FIELD(tmd.status, TMDS, ENP)) {
1250
                int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1251
                s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1252
                                 s->buffer, bcnt, CSR_BSWP(s));
1253
                s->xmit_pos += bcnt;
1254
            }
1255
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1256
        }
1257
        if (GET_FIELD(tmd.status, TMDS, ENP) && (s->xmit_pos >= 0)) {
1258
            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1259
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1260
                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1261
            s->xmit_pos += bcnt;
1262
#ifdef PCNET_DEBUG
1263
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1264
#endif
1265
            if (CSR_LOOP(s))
1266
                pcnet_receive(s, s->buffer, s->xmit_pos);
1267
            else
1268
                if (s->vc)
1269
                    qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1270

    
1271
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1272
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1273
            s->xmit_pos = -1;
1274
        }
1275

    
1276
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1277
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1278
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
1279
            s->csr[0] |= 0x0200;    /* set TINT */
1280

    
1281
        if (CSR_XMTRC(s)<=1)
1282
            CSR_XMTRC(s) = CSR_XMTRL(s);
1283
        else
1284
            CSR_XMTRC(s)--;
1285
        if (count--)
1286
            goto txagain;
1287

    
1288
    } else
1289
    if (s->xmit_pos >= 0) {
1290
        struct pcnet_TMD tmd;
1291
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
1292
        SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
1293
        SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
1294
        SET_FIELD(&tmd.status, TMDS, ERR, 1);
1295
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1296
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1297
        s->csr[0] |= 0x0200;    /* set TINT */
1298
        if (!CSR_DXSUFLO(s)) {
1299
            s->csr[0] &= ~0x0010;
1300
        } else
1301
        if (count--)
1302
          goto txagain;
1303
    }
1304

    
1305
    s->tx_busy = 0;
1306
}
1307

    
1308
static void pcnet_poll(PCNetState *s)
1309
{
1310
    if (CSR_RXON(s)) {
1311
        pcnet_rdte_poll(s);
1312
    }
1313

    
1314
    if (CSR_TDMD(s) ||
1315
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1316
    {
1317
        /* prevent recursion */
1318
        if (s->tx_busy)
1319
            return;
1320

    
1321
        pcnet_transmit(s);
1322
    }
1323
}
1324

    
1325
static void pcnet_poll_timer(void *opaque)
1326
{
1327
    PCNetState *s = opaque;
1328

    
1329
    qemu_del_timer(s->poll_timer);
1330

    
1331
    if (CSR_TDMD(s)) {
1332
        pcnet_transmit(s);
1333
    }
1334

    
1335
    pcnet_update_irq(s);
1336

    
1337
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1338
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1339
        if (!s->timer || !now)
1340
            s->timer = now;
1341
        else {
1342
            uint64_t t = now - s->timer + CSR_POLL(s);
1343
            if (t > 0xffffLL) {
1344
                pcnet_poll(s);
1345
                CSR_POLL(s) = CSR_PINT(s);
1346
            } else
1347
                CSR_POLL(s) = t;
1348
        }
1349
        qemu_mod_timer(s->poll_timer,
1350
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1351
    }
1352
}
1353

    
1354

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

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

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

    
1369
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1370
        if ((val&7) == 7)
1371
          val &= ~3;
1372

    
1373
        if (!CSR_STOP(s) && (val & 4))
1374
            pcnet_stop(s);
1375

    
1376
        if (!CSR_INIT(s) && (val & 1))
1377
            pcnet_init(s);
1378

    
1379
        if (!CSR_STRT(s) && (val & 2))
1380
            pcnet_start(s);
1381

    
1382
        if (CSR_TDMD(s))
1383
            pcnet_transmit(s);
1384

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

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

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

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

    
1556
static void pcnet_h_reset(void *opaque)
1557
{
1558
    PCNetState *s = opaque;
1559
    int i;
1560
    uint16_t checksum;
1561

    
1562
    /* Initialize the PROM */
1563

    
1564
    if (s->nd)
1565
        memcpy(s->prom, s->nd->macaddr, 6);
1566
    s->prom[12] = s->prom[13] = 0x00;
1567
    s->prom[14] = s->prom[15] = 0x57;
1568

    
1569
    for (i = 0,checksum = 0; i < 16; i++)
1570
        checksum += s->prom[i];
1571
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1572

    
1573

    
1574
    s->bcr[BCR_MSRDA] = 0x0005;
1575
    s->bcr[BCR_MSWRA] = 0x0005;
1576
    s->bcr[BCR_MC   ] = 0x0002;
1577
    s->bcr[BCR_LNKST] = 0x00c0;
1578
    s->bcr[BCR_LED1 ] = 0x0084;
1579
    s->bcr[BCR_LED2 ] = 0x0088;
1580
    s->bcr[BCR_LED3 ] = 0x0090;
1581
    s->bcr[BCR_FDC  ] = 0x0000;
1582
    s->bcr[BCR_BSBC ] = 0x9001;
1583
    s->bcr[BCR_EECAS] = 0x0002;
1584
    s->bcr[BCR_SWS  ] = 0x0200;
1585
    s->bcr[BCR_PLAT ] = 0xff06;
1586

    
1587
    pcnet_s_reset(s);
1588
}
1589

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

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

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

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

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

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

    
1722
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1723
                             uint32_t addr, uint32_t size, int type)
1724
{
1725
    PCNetState *d = (PCNetState *)pci_dev;
1726

    
1727
#ifdef PCNET_DEBUG_IO
1728
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1729
#endif
1730

    
1731
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1732
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1733

    
1734
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1735
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1736
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1737
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1738
}
1739

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

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

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

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

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

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

    
1834

    
1835
static void pcnet_save(QEMUFile *f, void *opaque)
1836
{
1837
    PCNetState *s = opaque;
1838
    unsigned int i;
1839

    
1840
    if (s->pci_dev)
1841
        pci_device_save(s->pci_dev, f);
1842

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

    
1861
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1862
{
1863
    PCNetState *s = opaque;
1864
    int i, ret;
1865

    
1866
    if (version_id != 2)
1867
        return -EINVAL;
1868

    
1869
    if (s->pci_dev) {
1870
        ret = pci_device_load(s->pci_dev, f);
1871
        if (ret < 0)
1872
            return ret;
1873
    }
1874

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

    
1892
    return 0;
1893
}
1894

    
1895
static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
1896
{
1897
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1898

    
1899
    d->nd = nd;
1900

    
1901
    if (nd && nd->vlan) {
1902
        d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
1903
                                     pcnet_can_receive, d);
1904

    
1905
        snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1906
                 "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1907
                 d->nd->macaddr[0],
1908
                 d->nd->macaddr[1],
1909
                 d->nd->macaddr[2],
1910
                 d->nd->macaddr[3],
1911
                 d->nd->macaddr[4],
1912
                 d->nd->macaddr[5]);
1913
    } else {
1914
        d->vc = NULL;
1915
    }
1916
    pcnet_h_reset(d);
1917
    register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
1918
}
1919

    
1920
/* PCI interface */
1921

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

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

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

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

    
1943
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1944
}
1945

    
1946
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1947
                                      uint8_t *buf, int len, int do_bswap)
1948
{
1949
    cpu_physical_memory_write(addr, buf, len);
1950
}
1951

    
1952
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1953
                                     uint8_t *buf, int len, int do_bswap)
1954
{
1955
    cpu_physical_memory_read(addr, buf, len);
1956
}
1957

    
1958
void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
1959
{
1960
    PCNetState *d;
1961
    uint8_t *pci_conf;
1962

    
1963
#if 0
1964
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
1965
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1966
#endif
1967

    
1968
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1969
                                          devfn, NULL, NULL);
1970

    
1971
    pci_conf = d->dev.config;
1972

    
1973
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1974
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
1975
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
1976
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1977
    pci_conf[0x08] = 0x10;
1978
    pci_conf[0x09] = 0x00;
1979
    pci_conf[0x0a] = 0x00; // ethernet network controller
1980
    pci_conf[0x0b] = 0x02;
1981
    pci_conf[0x0e] = 0x00; // header_type
1982

    
1983
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1984
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1985

    
1986
    pci_conf[0x3d] = 1; // interrupt pin 0
1987
    pci_conf[0x3e] = 0x06;
1988
    pci_conf[0x3f] = 0xff;
1989

    
1990
    /* Handler for memory-mapped I/O */
1991
    d->mmio_index =
1992
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1993

    
1994
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
1995
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1996

    
1997
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
1998
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
1999

    
2000
    d->irq = d->dev.irq[0];
2001
    d->phys_mem_read = pci_physical_memory_read;
2002
    d->phys_mem_write = pci_physical_memory_write;
2003
    d->pci_dev = &d->dev;
2004

    
2005
    pcnet_common_init(d, nd, "pcnet");
2006
}
2007

    
2008
/* SPARC32 interface */
2009

    
2010
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2011

    
2012
static void parent_lance_reset(void *opaque, int irq, int level)
2013
{
2014
    if (level)
2015
        pcnet_h_reset(opaque);
2016
}
2017

    
2018
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2019
                             uint32_t val)
2020
{
2021
#ifdef PCNET_DEBUG_IO
2022
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2023
           val & 0xffff);
2024
#endif
2025
    pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
2026
}
2027

    
2028
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2029
{
2030
    uint32_t val;
2031

    
2032
    val = pcnet_ioport_readw(opaque, addr & 7);
2033
#ifdef PCNET_DEBUG_IO
2034
    printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2035
           val & 0xffff);
2036
#endif
2037

    
2038
    return val & 0xffff;
2039
}
2040

    
2041
static CPUReadMemoryFunc *lance_mem_read[3] = {
2042
    lance_mem_readw,
2043
    lance_mem_readw,
2044
    lance_mem_readw,
2045
};
2046

    
2047
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2048
    lance_mem_writew,
2049
    lance_mem_writew,
2050
    lance_mem_writew,
2051
};
2052

    
2053
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
2054
                qemu_irq irq, qemu_irq *reset)
2055
{
2056
    PCNetState *d;
2057
    int lance_io_memory;
2058

    
2059
    d = qemu_mallocz(sizeof(PCNetState));
2060
    if (!d)
2061
        return;
2062

    
2063
    lance_io_memory =
2064
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2065

    
2066
    d->dma_opaque = dma_opaque;
2067

    
2068
    *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
2069

    
2070
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
2071

    
2072
    d->irq = irq;
2073
    d->phys_mem_read = ledma_memory_read;
2074
    d->phys_mem_write = ledma_memory_write;
2075

    
2076
    pcnet_common_init(d, nd, "lance");
2077
}
2078
#endif /* TARGET_SPARC */