Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 366c9332

History | View | Annotate | Download (54.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 "qdev.h"
39
#include "net.h"
40
#include "qemu-timer.h"
41
#include "qemu_socket.h"
42
#include "sysemu.h"
43

    
44
#include "pcnet.h"
45

    
46
//#define PCNET_DEBUG
47
//#define PCNET_DEBUG_IO
48
//#define PCNET_DEBUG_BCR
49
//#define PCNET_DEBUG_CSR
50
//#define PCNET_DEBUG_RMD
51
//#define PCNET_DEBUG_TMD
52
//#define PCNET_DEBUG_MATCH
53

    
54

    
55
struct qemu_ether_header {
56
    uint8_t ether_dhost[6];
57
    uint8_t ether_shost[6];
58
    uint16_t ether_type;
59
};
60

    
61
/* BUS CONFIGURATION REGISTERS */
62
#define BCR_MSRDA    0
63
#define BCR_MSWRA    1
64
#define BCR_MC       2
65
#define BCR_LNKST    4
66
#define BCR_LED1     5
67
#define BCR_LED2     6
68
#define BCR_LED3     7
69
#define BCR_FDC      9
70
#define BCR_BSBC     18
71
#define BCR_EECAS    19
72
#define BCR_SWS      20
73
#define BCR_PLAT     22
74

    
75
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
76
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
77
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
78

    
79
#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
80
#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
81
#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
82
#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
83
#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
84
#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
85
#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
86
#define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
87
#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
88
#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
89
#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
90
#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
91
#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
92
#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
93
#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
94
#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
95
#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
96
#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
97
#define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
98
#define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
99
#define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
100
#define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
101

    
102
#define CSR_CRBC(S)      ((S)->csr[40])
103
#define CSR_CRST(S)      ((S)->csr[41])
104
#define CSR_CXBC(S)      ((S)->csr[42])
105
#define CSR_CXST(S)      ((S)->csr[43])
106
#define CSR_NRBC(S)      ((S)->csr[44])
107
#define CSR_NRST(S)      ((S)->csr[45])
108
#define CSR_POLL(S)      ((S)->csr[46])
109
#define CSR_PINT(S)      ((S)->csr[47])
110
#define CSR_RCVRC(S)     ((S)->csr[72])
111
#define CSR_XMTRC(S)     ((S)->csr[74])
112
#define CSR_RCVRL(S)     ((S)->csr[76])
113
#define CSR_XMTRL(S)     ((S)->csr[78])
114
#define CSR_MISSC(S)     ((S)->csr[112])
115

    
116
#define CSR_IADR(S)      ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16))
117
#define CSR_CRBA(S)      ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16))
118
#define CSR_CXBA(S)      ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16))
119
#define CSR_NRBA(S)      ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16))
120
#define CSR_BADR(S)      ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16))
121
#define CSR_NRDA(S)      ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16))
122
#define CSR_CRDA(S)      ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16))
123
#define CSR_BADX(S)      ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16))
124
#define CSR_NXDA(S)      ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16))
125
#define CSR_CXDA(S)      ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16))
126
#define CSR_NNRD(S)      ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16))
127
#define CSR_NNXD(S)      ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16))
128
#define CSR_PXDA(S)      ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16))
129
#define CSR_NXBA(S)      ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16))
130

    
131
#define PHYSADDR(S,A) \
132
  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
133

    
134
struct pcnet_initblk16 {
135
    uint16_t mode;
136
    uint16_t padr[3];
137
    uint16_t ladrf[4];
138
    uint32_t rdra;
139
    uint32_t tdra;
140
};
141

    
142
struct pcnet_initblk32 {
143
    uint16_t mode;
144
    uint8_t rlen;
145
    uint8_t tlen;
146
    uint16_t padr[3];
147
    uint16_t _res;
148
    uint16_t ladrf[4];
149
    uint32_t rdra;
150
    uint32_t tdra;
151
};
152

    
153
struct pcnet_TMD {
154
    uint32_t tbadr;
155
    int16_t length;
156
    int16_t status;
157
    uint32_t misc;
158
    uint32_t res;
159
};
160

    
161
#define TMDL_BCNT_MASK  0x0fff
162
#define TMDL_BCNT_SH    0
163
#define TMDL_ONES_MASK  0xf000
164
#define TMDL_ONES_SH    12
165

    
166
#define TMDS_BPE_MASK   0x0080
167
#define TMDS_BPE_SH     7
168
#define TMDS_ENP_MASK   0x0100
169
#define TMDS_ENP_SH     8
170
#define TMDS_STP_MASK   0x0200
171
#define TMDS_STP_SH     9
172
#define TMDS_DEF_MASK   0x0400
173
#define TMDS_DEF_SH     10
174
#define TMDS_ONE_MASK   0x0800
175
#define TMDS_ONE_SH     11
176
#define TMDS_LTINT_MASK 0x1000
177
#define TMDS_LTINT_SH   12
178
#define TMDS_NOFCS_MASK 0x2000
179
#define TMDS_NOFCS_SH   13
180
#define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
181
#define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
182
#define TMDS_ERR_MASK   0x4000
183
#define TMDS_ERR_SH     14
184
#define TMDS_OWN_MASK   0x8000
185
#define TMDS_OWN_SH     15
186

    
187
#define TMDM_TRC_MASK   0x0000000f
188
#define TMDM_TRC_SH     0
189
#define TMDM_TDR_MASK   0x03ff0000
190
#define TMDM_TDR_SH     16
191
#define TMDM_RTRY_MASK  0x04000000
192
#define TMDM_RTRY_SH    26
193
#define TMDM_LCAR_MASK  0x08000000
194
#define TMDM_LCAR_SH    27
195
#define TMDM_LCOL_MASK  0x10000000
196
#define TMDM_LCOL_SH    28
197
#define TMDM_EXDEF_MASK 0x20000000
198
#define TMDM_EXDEF_SH   29
199
#define TMDM_UFLO_MASK  0x40000000
200
#define TMDM_UFLO_SH    30
201
#define TMDM_BUFF_MASK  0x80000000
202
#define TMDM_BUFF_SH    31
203

    
204
struct pcnet_RMD {
205
    uint32_t rbadr;
206
    int16_t buf_length;
207
    int16_t status;
208
    uint32_t msg_length;
209
    uint32_t res;
210
};
211

    
212
#define RMDL_BCNT_MASK  0x0fff
213
#define RMDL_BCNT_SH    0
214
#define RMDL_ONES_MASK  0xf000
215
#define RMDL_ONES_SH    12
216

    
217
#define RMDS_BAM_MASK   0x0010
218
#define RMDS_BAM_SH     4
219
#define RMDS_LFAM_MASK  0x0020
220
#define RMDS_LFAM_SH    5
221
#define RMDS_PAM_MASK   0x0040
222
#define RMDS_PAM_SH     6
223
#define RMDS_BPE_MASK   0x0080
224
#define RMDS_BPE_SH     7
225
#define RMDS_ENP_MASK   0x0100
226
#define RMDS_ENP_SH     8
227
#define RMDS_STP_MASK   0x0200
228
#define RMDS_STP_SH     9
229
#define RMDS_BUFF_MASK  0x0400
230
#define RMDS_BUFF_SH    10
231
#define RMDS_CRC_MASK   0x0800
232
#define RMDS_CRC_SH     11
233
#define RMDS_OFLO_MASK  0x1000
234
#define RMDS_OFLO_SH    12
235
#define RMDS_FRAM_MASK  0x2000
236
#define RMDS_FRAM_SH    13
237
#define RMDS_ERR_MASK   0x4000
238
#define RMDS_ERR_SH     14
239
#define RMDS_OWN_MASK   0x8000
240
#define RMDS_OWN_SH     15
241

    
242
#define RMDM_MCNT_MASK  0x00000fff
243
#define RMDM_MCNT_SH    0
244
#define RMDM_ZEROS_MASK 0x0000f000
245
#define RMDM_ZEROS_SH   12
246
#define RMDM_RPC_MASK   0x00ff0000
247
#define RMDM_RPC_SH     16
248
#define RMDM_RCC_MASK   0xff000000
249
#define RMDM_RCC_SH     24
250

    
251
#define SET_FIELD(regp, name, field, value)             \
252
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
253
             | ((value) << name ## _ ## field ## _SH))
254

    
255
#define GET_FIELD(reg, name, field)                     \
256
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
257

    
258
#define PRINT_TMD(T) printf(                            \
259
        "TMD0 : TBADR=0x%08x\n"                         \
260
        "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
261
        "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
262
        "       BPE=%d, BCNT=%d\n"                      \
263
        "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
264
        "LCA=%d, RTR=%d,\n"                             \
265
        "       TDR=%d, TRC=%d\n",                      \
266
        (T)->tbadr,                                     \
267
        GET_FIELD((T)->status, TMDS, OWN),              \
268
        GET_FIELD((T)->status, TMDS, ERR),              \
269
        GET_FIELD((T)->status, TMDS, NOFCS),            \
270
        GET_FIELD((T)->status, TMDS, LTINT),            \
271
        GET_FIELD((T)->status, TMDS, ONE),              \
272
        GET_FIELD((T)->status, TMDS, DEF),              \
273
        GET_FIELD((T)->status, TMDS, STP),              \
274
        GET_FIELD((T)->status, TMDS, ENP),              \
275
        GET_FIELD((T)->status, TMDS, BPE),              \
276
        4096-GET_FIELD((T)->length, TMDL, BCNT),        \
277
        GET_FIELD((T)->misc, TMDM, BUFF),               \
278
        GET_FIELD((T)->misc, TMDM, UFLO),               \
279
        GET_FIELD((T)->misc, TMDM, EXDEF),              \
280
        GET_FIELD((T)->misc, TMDM, LCOL),               \
281
        GET_FIELD((T)->misc, TMDM, LCAR),               \
282
        GET_FIELD((T)->misc, TMDM, RTRY),               \
283
        GET_FIELD((T)->misc, TMDM, TDR),                \
284
        GET_FIELD((T)->misc, TMDM, TRC))
285

    
286
#define PRINT_RMD(R) printf(                            \
287
        "RMD0 : RBADR=0x%08x\n"                         \
288
        "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
289
        "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
290
        "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
291
        "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
292
        (R)->rbadr,                                     \
293
        GET_FIELD((R)->status, RMDS, OWN),              \
294
        GET_FIELD((R)->status, RMDS, ERR),              \
295
        GET_FIELD((R)->status, RMDS, FRAM),             \
296
        GET_FIELD((R)->status, RMDS, OFLO),             \
297
        GET_FIELD((R)->status, RMDS, CRC),              \
298
        GET_FIELD((R)->status, RMDS, BUFF),             \
299
        GET_FIELD((R)->status, RMDS, STP),              \
300
        GET_FIELD((R)->status, RMDS, ENP),              \
301
        GET_FIELD((R)->status, RMDS, BPE),              \
302
        GET_FIELD((R)->status, RMDS, PAM),              \
303
        GET_FIELD((R)->status, RMDS, LFAM),             \
304
        GET_FIELD((R)->status, RMDS, BAM),              \
305
        GET_FIELD((R)->buf_length, RMDL, ONES),         \
306
        4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
307
        GET_FIELD((R)->msg_length, RMDM, RCC),          \
308
        GET_FIELD((R)->msg_length, RMDM, RPC),          \
309
        GET_FIELD((R)->msg_length, RMDM, MCNT),         \
310
        GET_FIELD((R)->msg_length, RMDM, ZEROS))
311

    
312
static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
313
                                  target_phys_addr_t addr)
314
{
315
    if (!BCR_SSIZE32(s)) {
316
        struct {
317
            uint32_t tbadr;
318
            int16_t length;
319
            int16_t status;
320
        } xda;
321
        s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
322
        tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
323
        tmd->length = le16_to_cpu(xda.length);
324
        tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
325
        tmd->misc = le16_to_cpu(xda.status) << 16;
326
        tmd->res = 0;
327
    } else {
328
        s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
329
        le32_to_cpus(&tmd->tbadr);
330
        le16_to_cpus((uint16_t *)&tmd->length);
331
        le16_to_cpus((uint16_t *)&tmd->status);
332
        le32_to_cpus(&tmd->misc);
333
        le32_to_cpus(&tmd->res);
334
        if (BCR_SWSTYLE(s) == 3) {
335
            uint32_t tmp = tmd->tbadr;
336
            tmd->tbadr = tmd->misc;
337
            tmd->misc = tmp;
338
        }
339
    }
340
}
341

    
342
static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
343
                                   target_phys_addr_t addr)
344
{
345
    if (!BCR_SSIZE32(s)) {
346
        struct {
347
            uint32_t tbadr;
348
            int16_t length;
349
            int16_t status;
350
        } xda;
351
        xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
352
                                ((tmd->status & 0xff00) << 16));
353
        xda.length = cpu_to_le16(tmd->length);
354
        xda.status = cpu_to_le16(tmd->misc >> 16);
355
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
356
    } else {
357
        struct {
358
            uint32_t tbadr;
359
            int16_t length;
360
            int16_t status;
361
            uint32_t misc;
362
            uint32_t res;
363
        } xda;
364
        xda.tbadr = cpu_to_le32(tmd->tbadr);
365
        xda.length = cpu_to_le16(tmd->length);
366
        xda.status = cpu_to_le16(tmd->status);
367
        xda.misc = cpu_to_le32(tmd->misc);
368
        xda.res = cpu_to_le32(tmd->res);
369
        if (BCR_SWSTYLE(s) == 3) {
370
            uint32_t tmp = xda.tbadr;
371
            xda.tbadr = xda.misc;
372
            xda.misc = tmp;
373
        }
374
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
375
    }
376
}
377

    
378
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
379
                                  target_phys_addr_t addr)
380
{
381
    if (!BCR_SSIZE32(s)) {
382
        struct {
383
            uint32_t rbadr;
384
            int16_t buf_length;
385
            int16_t msg_length;
386
        } rda;
387
        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
388
        rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
389
        rmd->buf_length = le16_to_cpu(rda.buf_length);
390
        rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
391
        rmd->msg_length = le16_to_cpu(rda.msg_length);
392
        rmd->res = 0;
393
    } else {
394
        s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
395
        le32_to_cpus(&rmd->rbadr);
396
        le16_to_cpus((uint16_t *)&rmd->buf_length);
397
        le16_to_cpus((uint16_t *)&rmd->status);
398
        le32_to_cpus(&rmd->msg_length);
399
        le32_to_cpus(&rmd->res);
400
        if (BCR_SWSTYLE(s) == 3) {
401
            uint32_t tmp = rmd->rbadr;
402
            rmd->rbadr = rmd->msg_length;
403
            rmd->msg_length = tmp;
404
        }
405
    }
406
}
407

    
408
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
409
                                   target_phys_addr_t addr)
410
{
411
    if (!BCR_SSIZE32(s)) {
412
        struct {
413
            uint32_t rbadr;
414
            int16_t buf_length;
415
            int16_t msg_length;
416
        } rda;
417
        rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
418
                                ((rmd->status & 0xff00) << 16));
419
        rda.buf_length = cpu_to_le16(rmd->buf_length);
420
        rda.msg_length = cpu_to_le16(rmd->msg_length);
421
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
422
    } else {
423
        struct {
424
            uint32_t rbadr;
425
            int16_t buf_length;
426
            int16_t status;
427
            uint32_t msg_length;
428
            uint32_t res;
429
        } rda;
430
        rda.rbadr = cpu_to_le32(rmd->rbadr);
431
        rda.buf_length = cpu_to_le16(rmd->buf_length);
432
        rda.status = cpu_to_le16(rmd->status);
433
        rda.msg_length = cpu_to_le32(rmd->msg_length);
434
        rda.res = cpu_to_le32(rmd->res);
435
        if (BCR_SWSTYLE(s) == 3) {
436
            uint32_t tmp = rda.rbadr;
437
            rda.rbadr = rda.msg_length;
438
            rda.msg_length = tmp;
439
        }
440
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
441
    }
442
}
443

    
444

    
445
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
446

    
447
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
448

    
449
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
450

    
451
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
452

    
453
#if 1
454

    
455
#define CHECK_RMD(ADDR,RES) do {                \
456
    struct pcnet_RMD rmd;                       \
457
    RMDLOAD(&rmd,(ADDR));                       \
458
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
459
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
460
} while (0)
461

    
462
#define CHECK_TMD(ADDR,RES) do {                \
463
    struct pcnet_TMD tmd;                       \
464
    TMDLOAD(&tmd,(ADDR));                       \
465
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
466
} while (0)
467

    
468
#else
469

    
470
#define CHECK_RMD(ADDR,RES) do {                \
471
    switch (BCR_SWSTYLE(s)) {                   \
472
    case 0x00:                                  \
473
        do {                                    \
474
            uint16_t rda[4];                    \
475
            s->phys_mem_read(s->dma_opaque, (ADDR), \
476
                (void *)&rda[0], sizeof(rda), 0); \
477
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
478
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
479
        } while (0);                            \
480
        break;                                  \
481
    case 0x01:                                  \
482
    case 0x02:                                  \
483
        do {                                    \
484
            uint32_t rda[4];                    \
485
            s->phys_mem_read(s->dma_opaque, (ADDR), \
486
                (void *)&rda[0], sizeof(rda), 0); \
487
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
488
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
489
        } while (0);                            \
490
        break;                                  \
491
    case 0x03:                                  \
492
        do {                                    \
493
            uint32_t rda[4];                    \
494
            s->phys_mem_read(s->dma_opaque, (ADDR), \
495
                (void *)&rda[0], sizeof(rda), 0); \
496
            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
497
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
498
        } while (0);                            \
499
        break;                                  \
500
    }                                           \
501
} while (0)
502

    
503
#define CHECK_TMD(ADDR,RES) do {                \
504
    switch (BCR_SWSTYLE(s)) {                   \
505
    case 0x00:                                  \
506
        do {                                    \
507
            uint16_t xda[4];                    \
508
            s->phys_mem_read(s->dma_opaque, (ADDR), \
509
                (void *)&xda[0], sizeof(xda), 0); \
510
            (RES) |= (xda[2] & 0xf000)!=0xf000; \
511
        } while (0);                            \
512
        break;                                  \
513
    case 0x01:                                  \
514
    case 0x02:                                  \
515
    case 0x03:                                  \
516
        do {                                    \
517
            uint32_t xda[4];                    \
518
            s->phys_mem_read(s->dma_opaque, (ADDR), \
519
                (void *)&xda[0], sizeof(xda), 0); \
520
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
521
        } while (0);                            \
522
        break;                                  \
523
    }                                           \
524
} while (0)
525

    
526
#endif
527

    
528
#define PRINT_PKTHDR(BUF) do {                  \
529
    struct qemu_ether_header *hdr = (void *)(BUF); \
530
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
531
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
532
           "type=0x%04x\n",                     \
533
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
534
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
535
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
536
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
537
           be16_to_cpu(hdr->ether_type));       \
538
} while (0)
539

    
540
#define MULTICAST_FILTER_LEN 8
541

    
542
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
543
{
544
#define LNC_POLYNOMIAL          0xEDB88320UL
545
    uint32_t crc = 0xFFFFFFFF;
546
    int idx, bit;
547
    uint8_t data;
548

    
549
    for (idx = 0; idx < 6; idx++) {
550
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
551
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
552
            data >>= 1;
553
        }
554
    }
555
    return crc;
556
#undef LNC_POLYNOMIAL
557
}
558

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

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

    
632
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
633
{
634
    struct qemu_ether_header *hdr = (void *)buf;
635
    uint8_t padr[6] = {
636
        s->csr[12] & 0xff, s->csr[12] >> 8,
637
        s->csr[13] & 0xff, s->csr[13] >> 8,
638
        s->csr[14] & 0xff, s->csr[14] >> 8
639
    };
640
    int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
641
#ifdef PCNET_DEBUG_MATCH
642
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
643
           "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
644
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
645
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
646
           padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
647
    printf("padr_match result=%d\n", result);
648
#endif
649
    return result;
650
}
651

    
652
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
653
{
654
    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
655
    struct qemu_ether_header *hdr = (void *)buf;
656
    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
657
#ifdef PCNET_DEBUG_MATCH
658
    printf("padr_bcast result=%d\n", result);
659
#endif
660
    return result;
661
}
662

    
663
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
664
{
665
    struct qemu_ether_header *hdr = (void *)buf;
666
    if ((*(hdr->ether_dhost)&0x01) &&
667
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
668
        uint8_t ladr[8] = {
669
            s->csr[8] & 0xff, s->csr[8] >> 8,
670
            s->csr[9] & 0xff, s->csr[9] >> 8,
671
            s->csr[10] & 0xff, s->csr[10] >> 8,
672
            s->csr[11] & 0xff, s->csr[11] >> 8
673
        };
674
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
675
        return !!(ladr[index >> 3] & (1 << (index & 7)));
676
    }
677
    return 0;
678
}
679

    
680
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
681
{
682
    while (idx < 1) idx += CSR_RCVRL(s);
683
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
684
}
685

    
686
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
687
{
688
    int64_t next_time = current_time +
689
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
690
                 get_ticks_per_sec(), 33000000L);
691
    if (next_time <= current_time)
692
        next_time = current_time + 1;
693
    return next_time;
694
}
695

    
696
static void pcnet_poll(PCNetState *s);
697
static void pcnet_poll_timer(void *opaque);
698

    
699
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
700
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
701
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
702

    
703
static void pcnet_s_reset(PCNetState *s)
704
{
705
#ifdef PCNET_DEBUG
706
    printf("pcnet_s_reset\n");
707
#endif
708

    
709
    s->lnkst = 0x40;
710
    s->rdra = 0;
711
    s->tdra = 0;
712
    s->rap = 0;
713

    
714
    s->bcr[BCR_BSBC] &= ~0x0080;
715

    
716
    s->csr[0]   = 0x0004;
717
    s->csr[3]   = 0x0000;
718
    s->csr[4]   = 0x0115;
719
    s->csr[5]   = 0x0000;
720
    s->csr[6]   = 0x0000;
721
    s->csr[8]   = 0;
722
    s->csr[9]   = 0;
723
    s->csr[10]  = 0;
724
    s->csr[11]  = 0;
725
    s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
726
    s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
727
    s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
728
    s->csr[15] &= 0x21c4;
729
    s->csr[72]  = 1;
730
    s->csr[74]  = 1;
731
    s->csr[76]  = 1;
732
    s->csr[78]  = 1;
733
    s->csr[80]  = 0x1410;
734
    s->csr[88]  = 0x1003;
735
    s->csr[89]  = 0x0262;
736
    s->csr[94]  = 0x0000;
737
    s->csr[100] = 0x0200;
738
    s->csr[103] = 0x0105;
739
    s->csr[103] = 0x0105;
740
    s->csr[112] = 0x0000;
741
    s->csr[114] = 0x0000;
742
    s->csr[122] = 0x0000;
743
    s->csr[124] = 0x0000;
744

    
745
    s->tx_busy = 0;
746
}
747

    
748
static void pcnet_update_irq(PCNetState *s)
749
{
750
    int isr = 0;
751
    s->csr[0] &= ~0x0080;
752

    
753
#if 1
754
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
755
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
756
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
757
#else
758
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
759
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
760
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
761
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
762
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
763
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
764
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
765
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
766
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
767
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
768
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
769
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
770
#endif
771
    {
772

    
773
        isr = CSR_INEA(s);
774
        s->csr[0] |= 0x0080;
775
    }
776

    
777
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
778
        s->csr[4] &= ~0x0080;
779
        s->csr[4] |= 0x0040;
780
        s->csr[0] |= 0x0080;
781
        isr = 1;
782
#ifdef PCNET_DEBUG
783
        printf("pcnet user int\n");
784
#endif
785
    }
786

    
787
#if 1
788
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
789
#else
790
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
791
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
792
#endif
793
    {
794
        isr = 1;
795
        s->csr[0] |= 0x0080;
796
    }
797

    
798
    if (isr != s->isr) {
799
#ifdef PCNET_DEBUG
800
        printf("pcnet: INTA=%d\n", isr);
801
#endif
802
    }
803
    qemu_set_irq(s->irq, isr);
804
    s->isr = isr;
805
}
806

    
807
static void pcnet_init(PCNetState *s)
808
{
809
    int rlen, tlen;
810
    uint16_t padr[3], ladrf[4], mode;
811
    uint32_t rdra, tdra;
812

    
813
#ifdef PCNET_DEBUG
814
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
815
#endif
816

    
817
    if (BCR_SSIZE32(s)) {
818
        struct pcnet_initblk32 initblk;
819
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
820
                (uint8_t *)&initblk, sizeof(initblk), 0);
821
        mode = le16_to_cpu(initblk.mode);
822
        rlen = initblk.rlen >> 4;
823
        tlen = initblk.tlen >> 4;
824
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
825
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
826
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
827
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
828
        padr[0] = le16_to_cpu(initblk.padr[0]);
829
        padr[1] = le16_to_cpu(initblk.padr[1]);
830
        padr[2] = le16_to_cpu(initblk.padr[2]);
831
        rdra = le32_to_cpu(initblk.rdra);
832
        tdra = le32_to_cpu(initblk.tdra);
833
    } else {
834
        struct pcnet_initblk16 initblk;
835
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
836
                (uint8_t *)&initblk, sizeof(initblk), 0);
837
        mode = le16_to_cpu(initblk.mode);
838
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
839
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
840
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
841
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
842
        padr[0] = le16_to_cpu(initblk.padr[0]);
843
        padr[1] = le16_to_cpu(initblk.padr[1]);
844
        padr[2] = le16_to_cpu(initblk.padr[2]);
845
        rdra = le32_to_cpu(initblk.rdra);
846
        tdra = le32_to_cpu(initblk.tdra);
847
        rlen = rdra >> 29;
848
        tlen = tdra >> 29;
849
        rdra &= 0x00ffffff;
850
        tdra &= 0x00ffffff;
851
    }
852

    
853
#if defined(PCNET_DEBUG)
854
    printf("rlen=%d tlen=%d\n", rlen, tlen);
855
#endif
856

    
857
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
858
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
859
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
860
    s->csr[15] = mode;
861
    s->csr[ 8] = ladrf[0];
862
    s->csr[ 9] = ladrf[1];
863
    s->csr[10] = ladrf[2];
864
    s->csr[11] = ladrf[3];
865
    s->csr[12] = padr[0];
866
    s->csr[13] = padr[1];
867
    s->csr[14] = padr[2];
868
    s->rdra = PHYSADDR(s, rdra);
869
    s->tdra = PHYSADDR(s, tdra);
870

    
871
    CSR_RCVRC(s) = CSR_RCVRL(s);
872
    CSR_XMTRC(s) = CSR_XMTRL(s);
873

    
874
#ifdef PCNET_DEBUG
875
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
876
        BCR_SSIZE32(s),
877
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
878
#endif
879

    
880
    s->csr[0] |= 0x0101;
881
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
882
}
883

    
884
static void pcnet_start(PCNetState *s)
885
{
886
#ifdef PCNET_DEBUG
887
    printf("pcnet_start\n");
888
#endif
889

    
890
    if (!CSR_DTX(s))
891
        s->csr[0] |= 0x0010;    /* set TXON */
892

    
893
    if (!CSR_DRX(s))
894
        s->csr[0] |= 0x0020;    /* set RXON */
895

    
896
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
897
    s->csr[0] |= 0x0002;
898
    pcnet_poll_timer(s);
899
}
900

    
901
static void pcnet_stop(PCNetState *s)
902
{
903
#ifdef PCNET_DEBUG
904
    printf("pcnet_stop\n");
905
#endif
906
    s->csr[0] &= ~0x7feb;
907
    s->csr[0] |= 0x0014;
908
    s->csr[4] &= ~0x02c2;
909
    s->csr[5] &= ~0x0011;
910
    pcnet_poll_timer(s);
911
}
912

    
913
static void pcnet_rdte_poll(PCNetState *s)
914
{
915
    s->csr[28] = s->csr[29] = 0;
916
    if (s->rdra) {
917
        int bad = 0;
918
#if 1
919
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
920
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
921
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
922
#else
923
        target_phys_addr_t crda = s->rdra +
924
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
925
            (BCR_SWSTYLE(s) ? 16 : 8 );
926
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
927
        target_phys_addr_t nrda = s->rdra +
928
            (CSR_RCVRL(s) - nrdc) *
929
            (BCR_SWSTYLE(s) ? 16 : 8 );
930
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
931
        target_phys_addr_t nnrd = s->rdra +
932
            (CSR_RCVRL(s) - nnrc) *
933
            (BCR_SWSTYLE(s) ? 16 : 8 );
934
#endif
935

    
936
        CHECK_RMD(crda, bad);
937
        if (!bad) {
938
            CHECK_RMD(nrda, bad);
939
            if (bad || (nrda == crda)) nrda = 0;
940
            CHECK_RMD(nnrd, bad);
941
            if (bad || (nnrd == crda)) nnrd = 0;
942

    
943
            s->csr[28] = crda & 0xffff;
944
            s->csr[29] = crda >> 16;
945
            s->csr[26] = nrda & 0xffff;
946
            s->csr[27] = nrda >> 16;
947
            s->csr[36] = nnrd & 0xffff;
948
            s->csr[37] = nnrd >> 16;
949
#ifdef PCNET_DEBUG
950
            if (bad) {
951
                printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
952
                       crda);
953
            }
954
        } else {
955
            printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n",
956
                   crda);
957
#endif
958
        }
959
    }
960

    
961
    if (CSR_CRDA(s)) {
962
        struct pcnet_RMD rmd;
963
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
964
        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
965
        CSR_CRST(s) = rmd.status;
966
#ifdef PCNET_DEBUG_RMD_X
967
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
968
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
969
                rmd.buf_length, rmd.status, rmd.msg_length);
970
        PRINT_RMD(&rmd);
971
#endif
972
    } else {
973
        CSR_CRBC(s) = CSR_CRST(s) = 0;
974
    }
975

    
976
    if (CSR_NRDA(s)) {
977
        struct pcnet_RMD rmd;
978
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
979
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
980
        CSR_NRST(s) = rmd.status;
981
    } else {
982
        CSR_NRBC(s) = CSR_NRST(s) = 0;
983
    }
984

    
985
}
986

    
987
static int pcnet_tdte_poll(PCNetState *s)
988
{
989
    s->csr[34] = s->csr[35] = 0;
990
    if (s->tdra) {
991
        target_phys_addr_t cxda = s->tdra +
992
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
993
            (BCR_SWSTYLE(s) ? 16 : 8);
994
        int bad = 0;
995
        CHECK_TMD(cxda, bad);
996
        if (!bad) {
997
            if (CSR_CXDA(s) != cxda) {
998
                s->csr[60] = s->csr[34];
999
                s->csr[61] = s->csr[35];
1000
                s->csr[62] = CSR_CXBC(s);
1001
                s->csr[63] = CSR_CXST(s);
1002
            }
1003
            s->csr[34] = cxda & 0xffff;
1004
            s->csr[35] = cxda >> 16;
1005
#ifdef PCNET_DEBUG_X
1006
            printf("pcnet: BAD TMD XDA=0x%08x\n", cxda);
1007
#endif
1008
        }
1009
    }
1010

    
1011
    if (CSR_CXDA(s)) {
1012
        struct pcnet_TMD tmd;
1013

    
1014
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1015

    
1016
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1017
        CSR_CXST(s) = tmd.status;
1018
    } else {
1019
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1020
    }
1021

    
1022
    return !!(CSR_CXST(s) & 0x8000);
1023
}
1024

    
1025
int pcnet_can_receive(VLANClientState *nc)
1026
{
1027
    PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1028
    if (CSR_STOP(s) || CSR_SPND(s))
1029
        return 0;
1030

    
1031
    return sizeof(s->buffer)-16;
1032
}
1033

    
1034
#define MIN_BUF_SIZE 60
1035

    
1036
ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
1037
{
1038
    PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1039
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1040
    uint8_t buf1[60];
1041
    int remaining;
1042
    int crc_err = 0;
1043
    int size = size_;
1044

    
1045
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size ||
1046
        (CSR_LOOP(s) && !s->looptest)) {
1047
        return -1;
1048
    }
1049
#ifdef PCNET_DEBUG
1050
    printf("pcnet_receive size=%d\n", size);
1051
#endif
1052

    
1053
    /* if too small buffer, then expand it */
1054
    if (size < MIN_BUF_SIZE) {
1055
        memcpy(buf1, buf, size);
1056
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1057
        buf = buf1;
1058
        size = MIN_BUF_SIZE;
1059
    }
1060

    
1061
    if (CSR_PROM(s)
1062
        || (is_padr=padr_match(s, buf, size))
1063
        || (is_bcast=padr_bcast(s, buf, size))
1064
        || (is_ladr=ladr_match(s, buf, size))) {
1065

    
1066
        pcnet_rdte_poll(s);
1067

    
1068
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1069
            struct pcnet_RMD rmd;
1070
            int rcvrc = CSR_RCVRC(s)-1,i;
1071
            target_phys_addr_t nrda;
1072
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1073
                if (rcvrc <= 1)
1074
                    rcvrc = CSR_RCVRL(s);
1075
                nrda = s->rdra +
1076
                    (CSR_RCVRL(s) - rcvrc) *
1077
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1078
                RMDLOAD(&rmd, nrda);
1079
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1080
#ifdef PCNET_DEBUG_RMD
1081
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1082
                                rcvrc, CSR_RCVRC(s));
1083
#endif
1084
                    CSR_RCVRC(s) = rcvrc;
1085
                    pcnet_rdte_poll(s);
1086
                    break;
1087
                }
1088
            }
1089
        }
1090

    
1091
        if (!(CSR_CRST(s) & 0x8000)) {
1092
#ifdef PCNET_DEBUG_RMD
1093
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1094
#endif
1095
            s->csr[0] |= 0x1000; /* Set MISS flag */
1096
            CSR_MISSC(s)++;
1097
        } else {
1098
            uint8_t *src = s->buffer;
1099
            target_phys_addr_t crda = CSR_CRDA(s);
1100
            struct pcnet_RMD rmd;
1101
            int pktcount = 0;
1102

    
1103
            if (!s->looptest) {
1104
                memcpy(src, buf, size);
1105
                /* no need to compute the CRC */
1106
                src[size] = 0;
1107
                src[size + 1] = 0;
1108
                src[size + 2] = 0;
1109
                src[size + 3] = 0;
1110
                size += 4;
1111
            } else if (s->looptest == PCNET_LOOPTEST_CRC ||
1112
                       !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {
1113
                uint32_t fcs = ~0;
1114
                uint8_t *p = src;
1115

    
1116
                while (p != &src[size])
1117
                    CRC(fcs, *p++);
1118
                *(uint32_t *)p = htonl(fcs);
1119
                size += 4;
1120
            } else {
1121
                uint32_t fcs = ~0;
1122
                uint8_t *p = src;
1123

    
1124
                while (p != &src[size-4])
1125
                    CRC(fcs, *p++);
1126
                crc_err = (*(uint32_t *)p != htonl(fcs));
1127
            }
1128

    
1129
#ifdef PCNET_DEBUG_MATCH
1130
            PRINT_PKTHDR(buf);
1131
#endif
1132

    
1133
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1134
            /*if (!CSR_LAPPEN(s))*/
1135
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1136

    
1137
#define PCNET_RECV_STORE() do {                                 \
1138
    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \
1139
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \
1140
    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
1141
    src += count; remaining -= count;                           \
1142
    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
1143
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1144
    pktcount++;                                                 \
1145
} while (0)
1146

    
1147
            remaining = size;
1148
            PCNET_RECV_STORE();
1149
            if ((remaining > 0) && CSR_NRDA(s)) {
1150
                target_phys_addr_t nrda = CSR_NRDA(s);
1151
#ifdef PCNET_DEBUG_RMD
1152
                PRINT_RMD(&rmd);
1153
#endif
1154
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1155
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1156
                    crda = nrda;
1157
                    PCNET_RECV_STORE();
1158
#ifdef PCNET_DEBUG_RMD
1159
                    PRINT_RMD(&rmd);
1160
#endif
1161
                    if ((remaining > 0) && (nrda=CSR_NNRD(s))) {
1162
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1163
                        if (GET_FIELD(rmd.status, RMDS, OWN)) {
1164
                            crda = nrda;
1165
                            PCNET_RECV_STORE();
1166
                        }
1167
                    }
1168
                }
1169
            }
1170

    
1171
#undef PCNET_RECV_STORE
1172

    
1173
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1174
            if (remaining == 0) {
1175
                SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);
1176
                SET_FIELD(&rmd.status, RMDS, ENP, 1);
1177
                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
1178
                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
1179
                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
1180
                if (crc_err) {
1181
                    SET_FIELD(&rmd.status, RMDS, CRC, 1);
1182
                    SET_FIELD(&rmd.status, RMDS, ERR, 1);
1183
                }
1184
            } else {
1185
                SET_FIELD(&rmd.status, RMDS, OFLO, 1);
1186
                SET_FIELD(&rmd.status, RMDS, BUFF, 1);
1187
                SET_FIELD(&rmd.status, RMDS, ERR, 1);
1188
            }
1189
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1190
            s->csr[0] |= 0x0400;
1191

    
1192
#ifdef PCNET_DEBUG
1193
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1194
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1195
#endif
1196
#ifdef PCNET_DEBUG_RMD
1197
            PRINT_RMD(&rmd);
1198
#endif
1199

    
1200
            while (pktcount--) {
1201
                if (CSR_RCVRC(s) <= 1)
1202
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1203
                else
1204
                    CSR_RCVRC(s)--;
1205
            }
1206

    
1207
            pcnet_rdte_poll(s);
1208

    
1209
        }
1210
    }
1211

    
1212
    pcnet_poll(s);
1213
    pcnet_update_irq(s);
1214

    
1215
    return size_;
1216
}
1217

    
1218
static void pcnet_transmit(PCNetState *s)
1219
{
1220
    target_phys_addr_t xmit_cxda = 0;
1221
    int count = CSR_XMTRL(s)-1;
1222
    int add_crc = 0;
1223

    
1224
    s->xmit_pos = -1;
1225

    
1226
    if (!CSR_TXON(s)) {
1227
        s->csr[0] &= ~0x0008;
1228
        return;
1229
    }
1230

    
1231
    s->tx_busy = 1;
1232

    
1233
    txagain:
1234
    if (pcnet_tdte_poll(s)) {
1235
        struct pcnet_TMD tmd;
1236

    
1237
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1238

    
1239
#ifdef PCNET_DEBUG_TMD
1240
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1241
        PRINT_TMD(&tmd);
1242
#endif
1243
        if (GET_FIELD(tmd.status, TMDS, STP)) {
1244
            s->xmit_pos = 0;
1245
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1246
            if (BCR_SWSTYLE(s) != 1)
1247
                add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
1248
        }
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 + s->xmit_pos, bcnt, CSR_BSWP(s));
1253
            s->xmit_pos += bcnt;
1254
        } else if (s->xmit_pos >= 0) {
1255
            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1256
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1257
                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1258
            s->xmit_pos += bcnt;
1259
#ifdef PCNET_DEBUG
1260
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1261
#endif
1262
            if (CSR_LOOP(s)) {
1263
                if (BCR_SWSTYLE(s) == 1)
1264
                    add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
1265
                s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
1266
                pcnet_receive(&s->nic->nc, s->buffer, s->xmit_pos);
1267
                s->looptest = 0;
1268
            } else
1269
                if (s->nic)
1270
                    qemu_send_packet(&s->nic->nc, s->buffer, s->xmit_pos);
1271

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

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

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

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

    
1306
    s->tx_busy = 0;
1307
}
1308

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

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

    
1322
        pcnet_transmit(s);
1323
    }
1324
}
1325

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

    
1330
    qemu_del_timer(s->poll_timer);
1331

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

    
1336
    pcnet_update_irq(s);
1337

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

    
1355

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

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

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

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

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

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

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

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

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

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

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

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

    
1557
void pcnet_h_reset(void *opaque)
1558
{
1559
    PCNetState *s = opaque;
1560

    
1561
    s->bcr[BCR_MSRDA] = 0x0005;
1562
    s->bcr[BCR_MSWRA] = 0x0005;
1563
    s->bcr[BCR_MC   ] = 0x0002;
1564
    s->bcr[BCR_LNKST] = 0x00c0;
1565
    s->bcr[BCR_LED1 ] = 0x0084;
1566
    s->bcr[BCR_LED2 ] = 0x0088;
1567
    s->bcr[BCR_LED3 ] = 0x0090;
1568
    s->bcr[BCR_FDC  ] = 0x0000;
1569
    s->bcr[BCR_BSBC ] = 0x9001;
1570
    s->bcr[BCR_EECAS] = 0x0002;
1571
    s->bcr[BCR_SWS  ] = 0x0200;
1572
    s->bcr[BCR_PLAT ] = 0xff06;
1573

    
1574
    pcnet_s_reset(s);
1575
    pcnet_update_irq(s);
1576
    pcnet_poll_timer(s);
1577
}
1578

    
1579
void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1580
{
1581
    PCNetState *s = opaque;
1582
    pcnet_poll_timer(s);
1583
#ifdef PCNET_DEBUG_IO
1584
    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1585
#endif
1586
    if (!BCR_DWIO(s)) {
1587
        switch (addr & 0x0f) {
1588
        case 0x00: /* RDP */
1589
            pcnet_csr_writew(s, s->rap, val);
1590
            break;
1591
        case 0x02:
1592
            s->rap = val & 0x7f;
1593
            break;
1594
        case 0x06:
1595
            pcnet_bcr_writew(s, s->rap, val);
1596
            break;
1597
        }
1598
    }
1599
    pcnet_update_irq(s);
1600
}
1601

    
1602
uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1603
{
1604
    PCNetState *s = opaque;
1605
    uint32_t val = -1;
1606
    pcnet_poll_timer(s);
1607
    if (!BCR_DWIO(s)) {
1608
        switch (addr & 0x0f) {
1609
        case 0x00: /* RDP */
1610
            val = pcnet_csr_readw(s, s->rap);
1611
            break;
1612
        case 0x02:
1613
            val = s->rap;
1614
            break;
1615
        case 0x04:
1616
            pcnet_s_reset(s);
1617
            val = 0;
1618
            break;
1619
        case 0x06:
1620
            val = pcnet_bcr_readw(s, s->rap);
1621
            break;
1622
        }
1623
    }
1624
    pcnet_update_irq(s);
1625
#ifdef PCNET_DEBUG_IO
1626
    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1627
#endif
1628
    return val;
1629
}
1630

    
1631
void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1632
{
1633
    PCNetState *s = opaque;
1634
    pcnet_poll_timer(s);
1635
#ifdef PCNET_DEBUG_IO
1636
    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1637
#endif
1638
    if (BCR_DWIO(s)) {
1639
        switch (addr & 0x0f) {
1640
        case 0x00: /* RDP */
1641
            pcnet_csr_writew(s, s->rap, val & 0xffff);
1642
            break;
1643
        case 0x04:
1644
            s->rap = val & 0x7f;
1645
            break;
1646
        case 0x0c:
1647
            pcnet_bcr_writew(s, s->rap, val & 0xffff);
1648
            break;
1649
        }
1650
    } else
1651
    if ((addr & 0x0f) == 0) {
1652
        /* switch device to dword i/o mode */
1653
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1654
#ifdef PCNET_DEBUG_IO
1655
        printf("device switched into dword i/o mode\n");
1656
#endif
1657
    }
1658
    pcnet_update_irq(s);
1659
}
1660

    
1661
uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1662
{
1663
    PCNetState *s = opaque;
1664
    uint32_t val = -1;
1665
    pcnet_poll_timer(s);
1666
    if (BCR_DWIO(s)) {
1667
        switch (addr & 0x0f) {
1668
        case 0x00: /* RDP */
1669
            val = pcnet_csr_readw(s, s->rap);
1670
            break;
1671
        case 0x04:
1672
            val = s->rap;
1673
            break;
1674
        case 0x08:
1675
            pcnet_s_reset(s);
1676
            val = 0;
1677
            break;
1678
        case 0x0c:
1679
            val = pcnet_bcr_readw(s, s->rap);
1680
            break;
1681
        }
1682
    }
1683
    pcnet_update_irq(s);
1684
#ifdef PCNET_DEBUG_IO
1685
    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1686
#endif
1687
    return val;
1688
}
1689

    
1690
static bool is_version_2(void *opaque, int version_id)
1691
{
1692
    return version_id == 2;
1693
}
1694

    
1695
const VMStateDescription vmstate_pcnet = {
1696
    .name = "pcnet",
1697
    .version_id = 3,
1698
    .minimum_version_id = 2,
1699
    .minimum_version_id_old = 2,
1700
    .fields      = (VMStateField []) {
1701
        VMSTATE_INT32(rap, PCNetState),
1702
        VMSTATE_INT32(isr, PCNetState),
1703
        VMSTATE_INT32(lnkst, PCNetState),
1704
        VMSTATE_UINT32(rdra, PCNetState),
1705
        VMSTATE_UINT32(tdra, PCNetState),
1706
        VMSTATE_BUFFER(prom, PCNetState),
1707
        VMSTATE_UINT16_ARRAY(csr, PCNetState, 128),
1708
        VMSTATE_UINT16_ARRAY(bcr, PCNetState, 32),
1709
        VMSTATE_UINT64(timer, PCNetState),
1710
        VMSTATE_INT32(xmit_pos, PCNetState),
1711
        VMSTATE_BUFFER(buffer, PCNetState),
1712
        VMSTATE_UNUSED_TEST(is_version_2, 4),
1713
        VMSTATE_INT32(tx_busy, PCNetState),
1714
        VMSTATE_TIMER(poll_timer, PCNetState),
1715
        VMSTATE_END_OF_LIST()
1716
    }
1717
};
1718

    
1719
void pcnet_common_cleanup(PCNetState *d)
1720
{
1721
    d->nic = NULL;
1722
}
1723

    
1724
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
1725
{
1726
    int i;
1727
    uint16_t checksum;
1728

    
1729
    s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
1730

    
1731
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
1732
    s->nic = qemu_new_nic(info, &s->conf, dev->info->name, dev->id, s);
1733
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
1734

    
1735
    add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
1736

    
1737
    /* Initialize the PROM */
1738

    
1739
    /*
1740
      Datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf
1741
      page 95
1742
    */
1743
    memcpy(s->prom, s->conf.macaddr.a, 6);
1744
    /* Reserved Location: must be 00h */
1745
    s->prom[6] = s->prom[7] = 0x00;
1746
    /* Reserved Location: must be 00h */
1747
    s->prom[8] = 0x00;
1748
    /* Hardware ID: must be 11h if compatibility to AMD drivers is desired */
1749
    s->prom[9] = 0x11;
1750
    /* User programmable space, init with 0 */
1751
    s->prom[10] = s->prom[11] = 0x00;
1752
    /* LSByte of two-byte checksum, which is the sum of bytes 00h-0Bh
1753
       and bytes 0Eh and 0Fh, must therefore be initialized with 0! */
1754
    s->prom[12] = s->prom[13] = 0x00;
1755
    /* Must be ASCII W (57h) if compatibility to AMD
1756
       driver software is desired */
1757
    s->prom[14] = s->prom[15] = 0x57;
1758

    
1759
    for (i = 0, checksum = 0; i < 16; i++) {
1760
        checksum += s->prom[i];
1761
    }
1762
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1763

    
1764
    return 0;
1765
}