Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 8af7a3ab

History | View | Annotate | Download (62.1 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 "pci.h"
39
#include "net.h"
40
#include "loader.h"
41
#include "qemu-timer.h"
42
#include "qemu_socket.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
typedef struct {
56
    PCIDevice pci_dev;
57
    PCNetState state;
58
} PCIPCNetState;
59

    
60
struct qemu_ether_header {
61
    uint8_t ether_dhost[6];
62
    uint8_t ether_shost[6];
63
    uint16_t ether_type;
64
};
65

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

    
80
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
81
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
82
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
83

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

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

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

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

    
139
struct pcnet_initblk16 {
140
    uint16_t mode;
141
    uint16_t padr[3];
142
    uint16_t ladrf[4];
143
    uint32_t rdra;
144
    uint32_t tdra;
145
};
146

    
147
struct pcnet_initblk32 {
148
    uint16_t mode;
149
    uint8_t rlen;
150
    uint8_t tlen;
151
    uint16_t padr[3];
152
    uint16_t _res;
153
    uint16_t ladrf[4];
154
    uint32_t rdra;
155
    uint32_t tdra;
156
};
157

    
158
struct pcnet_TMD {
159
    uint32_t tbadr;
160
    int16_t length;
161
    int16_t status;
162
    uint32_t misc;
163
    uint32_t res;
164
};
165

    
166
#define TMDL_BCNT_MASK  0x0fff
167
#define TMDL_BCNT_SH    0
168
#define TMDL_ONES_MASK  0xf000
169
#define TMDL_ONES_SH    12
170

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

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

    
209
struct pcnet_RMD {
210
    uint32_t rbadr;
211
    int16_t buf_length;
212
    int16_t status;
213
    uint32_t msg_length;
214
    uint32_t res;
215
};
216

    
217
#define RMDL_BCNT_MASK  0x0fff
218
#define RMDL_BCNT_SH    0
219
#define RMDL_ONES_MASK  0xf000
220
#define RMDL_ONES_SH    12
221

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

    
247
#define RMDM_MCNT_MASK  0x00000fff
248
#define RMDM_MCNT_SH    0
249
#define RMDM_ZEROS_MASK 0x0000f000
250
#define RMDM_ZEROS_SH   12
251
#define RMDM_RPC_MASK   0x00ff0000
252
#define RMDM_RPC_SH     16
253
#define RMDM_RCC_MASK   0xff000000
254
#define RMDM_RCC_SH     24
255

    
256
#define SET_FIELD(regp, name, field, value)             \
257
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
258
             | ((value) << name ## _ ## field ## _SH))
259

    
260
#define GET_FIELD(reg, name, field)                     \
261
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
262

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

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

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

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

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

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

    
449

    
450
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
451

    
452
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
453

    
454
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
455

    
456
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
457

    
458
#if 1
459

    
460
#define CHECK_RMD(ADDR,RES) do {                \
461
    struct pcnet_RMD rmd;                       \
462
    RMDLOAD(&rmd,(ADDR));                       \
463
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
464
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
465
} while (0)
466

    
467
#define CHECK_TMD(ADDR,RES) do {                \
468
    struct pcnet_TMD tmd;                       \
469
    TMDLOAD(&tmd,(ADDR));                       \
470
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
471
} while (0)
472

    
473
#else
474

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

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

    
531
#endif
532

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

    
545
#define MULTICAST_FILTER_LEN 8
546

    
547
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
548
{
549
#define LNC_POLYNOMIAL          0xEDB88320UL
550
    uint32_t crc = 0xFFFFFFFF;
551
    int idx, bit;
552
    uint8_t data;
553

    
554
    for (idx = 0; idx < 6; idx++) {
555
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
556
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
557
            data >>= 1;
558
        }
559
    }
560
    return crc;
561
#undef LNC_POLYNOMIAL
562
}
563

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

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

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

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

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

    
685
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
686
{
687
    while (idx < 1) idx += CSR_RCVRL(s);
688
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
689
}
690

    
691
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
692
{
693
    int64_t next_time = current_time +
694
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
695
                 get_ticks_per_sec(), 33000000L);
696
    if (next_time <= current_time)
697
        next_time = current_time + 1;
698
    return next_time;
699
}
700

    
701
static void pcnet_poll(PCNetState *s);
702
static void pcnet_poll_timer(void *opaque);
703

    
704
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
705
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
706
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
707
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
708

    
709
static void pcnet_s_reset(PCNetState *s)
710
{
711
#ifdef PCNET_DEBUG
712
    printf("pcnet_s_reset\n");
713
#endif
714

    
715
    s->lnkst = 0x40;
716
    s->rdra = 0;
717
    s->tdra = 0;
718
    s->rap = 0;
719

    
720
    s->bcr[BCR_BSBC] &= ~0x0080;
721

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

    
751
    s->tx_busy = 0;
752
}
753

    
754
static void pcnet_update_irq(PCNetState *s)
755
{
756
    int isr = 0;
757
    s->csr[0] &= ~0x0080;
758

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

    
779
        isr = CSR_INEA(s);
780
        s->csr[0] |= 0x0080;
781
    }
782

    
783
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
784
        s->csr[4] &= ~0x0080;
785
        s->csr[4] |= 0x0040;
786
        s->csr[0] |= 0x0080;
787
        isr = 1;
788
#ifdef PCNET_DEBUG
789
        printf("pcnet user int\n");
790
#endif
791
    }
792

    
793
#if 1
794
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
795
#else
796
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
797
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
798
#endif
799
    {
800
        isr = 1;
801
        s->csr[0] |= 0x0080;
802
    }
803

    
804
    if (isr != s->isr) {
805
#ifdef PCNET_DEBUG
806
        printf("pcnet: INTA=%d\n", isr);
807
#endif
808
    }
809
    qemu_set_irq(s->irq, isr);
810
    s->isr = isr;
811
}
812

    
813
static void pcnet_init(PCNetState *s)
814
{
815
    int rlen, tlen;
816
    uint16_t padr[3], ladrf[4], mode;
817
    uint32_t rdra, tdra;
818

    
819
#ifdef PCNET_DEBUG
820
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
821
#endif
822

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

    
859
#if defined(PCNET_DEBUG)
860
    printf("rlen=%d tlen=%d\n", rlen, tlen);
861
#endif
862

    
863
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
864
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
865
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
866
    s->csr[15] = mode;
867
    s->csr[ 8] = ladrf[0];
868
    s->csr[ 9] = ladrf[1];
869
    s->csr[10] = ladrf[2];
870
    s->csr[11] = ladrf[3];
871
    s->csr[12] = padr[0];
872
    s->csr[13] = padr[1];
873
    s->csr[14] = padr[2];
874
    s->rdra = PHYSADDR(s, rdra);
875
    s->tdra = PHYSADDR(s, tdra);
876

    
877
    CSR_RCVRC(s) = CSR_RCVRL(s);
878
    CSR_XMTRC(s) = CSR_XMTRL(s);
879

    
880
#ifdef PCNET_DEBUG
881
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
882
        BCR_SSIZE32(s),
883
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
884
#endif
885

    
886
    s->csr[0] |= 0x0101;
887
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
888
}
889

    
890
static void pcnet_start(PCNetState *s)
891
{
892
#ifdef PCNET_DEBUG
893
    printf("pcnet_start\n");
894
#endif
895

    
896
    if (!CSR_DTX(s))
897
        s->csr[0] |= 0x0010;    /* set TXON */
898

    
899
    if (!CSR_DRX(s))
900
        s->csr[0] |= 0x0020;    /* set RXON */
901

    
902
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
903
    s->csr[0] |= 0x0002;
904
    pcnet_poll_timer(s);
905
}
906

    
907
static void pcnet_stop(PCNetState *s)
908
{
909
#ifdef PCNET_DEBUG
910
    printf("pcnet_stop\n");
911
#endif
912
    s->csr[0] &= ~0x7feb;
913
    s->csr[0] |= 0x0014;
914
    s->csr[4] &= ~0x02c2;
915
    s->csr[5] &= ~0x0011;
916
    pcnet_poll_timer(s);
917
}
918

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

    
942
        CHECK_RMD(crda, bad);
943
        if (!bad) {
944
            CHECK_RMD(nrda, bad);
945
            if (bad || (nrda == crda)) nrda = 0;
946
            CHECK_RMD(nnrd, bad);
947
            if (bad || (nnrd == crda)) nnrd = 0;
948

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

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

    
982
    if (CSR_NRDA(s)) {
983
        struct pcnet_RMD rmd;
984
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
985
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
986
        CSR_NRST(s) = rmd.status;
987
    } else {
988
        CSR_NRBC(s) = CSR_NRST(s) = 0;
989
    }
990

    
991
}
992

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

    
1017
    if (CSR_CXDA(s)) {
1018
        struct pcnet_TMD tmd;
1019

    
1020
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1021

    
1022
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1023
        CSR_CXST(s) = tmd.status;
1024
    } else {
1025
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1026
    }
1027

    
1028
    return !!(CSR_CXST(s) & 0x8000);
1029
}
1030

    
1031
int pcnet_can_receive(VLANClientState *nc)
1032
{
1033
    PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1034
    if (CSR_STOP(s) || CSR_SPND(s))
1035
        return 0;
1036

    
1037
    return sizeof(s->buffer)-16;
1038
}
1039

    
1040
#define MIN_BUF_SIZE 60
1041

    
1042
ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
1043
{
1044
    PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1045
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1046
    uint8_t buf1[60];
1047
    int remaining;
1048
    int crc_err = 0;
1049
    int size = size_;
1050

    
1051
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1052
        return -1;
1053

    
1054
#ifdef PCNET_DEBUG
1055
    printf("pcnet_receive size=%d\n", size);
1056
#endif
1057

    
1058
    /* if too small buffer, then expand it */
1059
    if (size < MIN_BUF_SIZE) {
1060
        memcpy(buf1, buf, size);
1061
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1062
        buf = buf1;
1063
        size = MIN_BUF_SIZE;
1064
    }
1065

    
1066
    if (CSR_PROM(s)
1067
        || (is_padr=padr_match(s, buf, size))
1068
        || (is_bcast=padr_bcast(s, buf, size))
1069
        || (is_ladr=ladr_match(s, buf, size))) {
1070

    
1071
        pcnet_rdte_poll(s);
1072

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

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

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

    
1121
                while (p != &src[size])
1122
                    CRC(fcs, *p++);
1123
                *(uint32_t *)p = htonl(fcs);
1124
                size += 4;
1125
            } else {
1126
                uint32_t fcs = ~0;
1127
                uint8_t *p = src;
1128

    
1129
                while (p != &src[size-4])
1130
                    CRC(fcs, *p++);
1131
                crc_err = (*(uint32_t *)p != htonl(fcs));
1132
            }
1133

    
1134
#ifdef PCNET_DEBUG_MATCH
1135
            PRINT_PKTHDR(buf);
1136
#endif
1137

    
1138
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1139
            /*if (!CSR_LAPPEN(s))*/
1140
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1141

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

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

    
1176
#undef PCNET_RECV_STORE
1177

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

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

    
1205
            while (pktcount--) {
1206
                if (CSR_RCVRC(s) <= 1)
1207
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1208
                else
1209
                    CSR_RCVRC(s)--;
1210
            }
1211

    
1212
            pcnet_rdte_poll(s);
1213

    
1214
        }
1215
    }
1216

    
1217
    pcnet_poll(s);
1218
    pcnet_update_irq(s);
1219

    
1220
    return size_;
1221
}
1222

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

    
1229
    s->xmit_pos = -1;
1230

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

    
1236
    s->tx_busy = 1;
1237

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

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

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

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

    
1282
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1283
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1284
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
1285
            s->csr[0] |= 0x0200;    /* set TINT */
1286

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

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

    
1311
    s->tx_busy = 0;
1312
}
1313

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

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

    
1327
        pcnet_transmit(s);
1328
    }
1329
}
1330

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

    
1335
    qemu_del_timer(s->poll_timer);
1336

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

    
1341
    pcnet_update_irq(s);
1342

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

    
1360

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1568
    /* Initialize the PROM */
1569

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

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

    
1578

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

    
1592
    pcnet_s_reset(s);
1593
    pcnet_update_irq(s);
1594
    pcnet_poll_timer(s);
1595
}
1596

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

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

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

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

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

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

    
1729
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1730
                             pcibus_t addr, pcibus_t size, int type)
1731
{
1732
    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
1733

    
1734
#ifdef PCNET_DEBUG_IO
1735
    printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
1736
           addr, size);
1737
#endif
1738

    
1739
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1740
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1741

    
1742
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1743
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1744
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1745
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1746
}
1747

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

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

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

    
1788
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
1789
{
1790
    PCNetState *d = opaque;
1791
    uint32_t val = -1;
1792
    if (addr & 0x10)
1793
        val = pcnet_ioport_readw(d, addr & 0x0f);
1794
    else {
1795
        addr &= 0x0f;
1796
        val = pcnet_aprom_readb(d, addr+1);
1797
        val <<= 8;
1798
        val |= pcnet_aprom_readb(d, addr);
1799
    }
1800
#ifdef PCNET_DEBUG_IO
1801
    printf("pcnet_mmio_readw addr=0x" TARGET_FMT_plx" val = 0x%04x\n", addr,
1802
           val & 0xffff);
1803
#endif
1804
    return val;
1805
}
1806

    
1807
static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1808
{
1809
    PCNetState *d = opaque;
1810
#ifdef PCNET_DEBUG_IO
1811
    printf("pcnet_mmio_writel addr=0x" TARGET_FMT_plx" val=0x%08x\n", addr,
1812
           val);
1813
#endif
1814
    if (addr & 0x10)
1815
        pcnet_ioport_writel(d, addr & 0x0f, val);
1816
    else {
1817
        addr &= 0x0f;
1818
        pcnet_aprom_writeb(d, addr, val & 0xff);
1819
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1820
        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1821
        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1822
    }
1823
}
1824

    
1825
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
1826
{
1827
    PCNetState *d = opaque;
1828
    uint32_t val;
1829
    if (addr & 0x10)
1830
        val = pcnet_ioport_readl(d, addr & 0x0f);
1831
    else {
1832
        addr &= 0x0f;
1833
        val = pcnet_aprom_readb(d, addr+3);
1834
        val <<= 8;
1835
        val |= pcnet_aprom_readb(d, addr+2);
1836
        val <<= 8;
1837
        val |= pcnet_aprom_readb(d, addr+1);
1838
        val <<= 8;
1839
        val |= pcnet_aprom_readb(d, addr);
1840
    }
1841
#ifdef PCNET_DEBUG_IO
1842
    printf("pcnet_mmio_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr,
1843
           val);
1844
#endif
1845
    return val;
1846
}
1847

    
1848
static bool is_version_2(void *opaque, int version_id)
1849
{
1850
    return version_id == 2;
1851
}
1852

    
1853
const VMStateDescription vmstate_pcnet = {
1854
    .name = "pcnet",
1855
    .version_id = 3,
1856
    .minimum_version_id = 2,
1857
    .minimum_version_id_old = 2,
1858
    .fields      = (VMStateField []) {
1859
        VMSTATE_INT32(rap, PCNetState),
1860
        VMSTATE_INT32(isr, PCNetState),
1861
        VMSTATE_INT32(lnkst, PCNetState),
1862
        VMSTATE_UINT32(rdra, PCNetState),
1863
        VMSTATE_UINT32(tdra, PCNetState),
1864
        VMSTATE_BUFFER(prom, PCNetState),
1865
        VMSTATE_UINT16_ARRAY(csr, PCNetState, 128),
1866
        VMSTATE_UINT16_ARRAY(bcr, PCNetState, 32),
1867
        VMSTATE_UINT64(timer, PCNetState),
1868
        VMSTATE_INT32(xmit_pos, PCNetState),
1869
        VMSTATE_BUFFER(buffer, PCNetState),
1870
        VMSTATE_UNUSED_TEST(is_version_2, 4),
1871
        VMSTATE_INT32(tx_busy, PCNetState),
1872
        VMSTATE_TIMER(poll_timer, PCNetState),
1873
        VMSTATE_END_OF_LIST()
1874
    }
1875
};
1876

    
1877
static const VMStateDescription vmstate_pci_pcnet = {
1878
    .name = "pcnet",
1879
    .version_id = 3,
1880
    .minimum_version_id = 2,
1881
    .minimum_version_id_old = 2,
1882
    .fields      = (VMStateField []) {
1883
        VMSTATE_PCI_DEVICE(pci_dev, PCIPCNetState),
1884
        VMSTATE_STRUCT(state, PCIPCNetState, 0, vmstate_pcnet, PCNetState),
1885
        VMSTATE_END_OF_LIST()
1886
    }
1887
};
1888

    
1889
void pcnet_common_cleanup(PCNetState *d)
1890
{
1891
    d->nic = NULL;
1892
}
1893

    
1894
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
1895
{
1896
    s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
1897

    
1898
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
1899
    s->nic = qemu_new_nic(info, &s->conf, dev->info->name, dev->id, s);
1900
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
1901
    return 0;
1902
}
1903

    
1904
/* PCI interface */
1905

    
1906
static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
1907
    &pcnet_mmio_writeb,
1908
    &pcnet_mmio_writew,
1909
    &pcnet_mmio_writel
1910
};
1911

    
1912
static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
1913
    &pcnet_mmio_readb,
1914
    &pcnet_mmio_readw,
1915
    &pcnet_mmio_readl
1916
};
1917

    
1918
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1919
                            pcibus_t addr, pcibus_t size, int type)
1920
{
1921
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
1922

    
1923
#ifdef PCNET_DEBUG_IO
1924
    printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
1925
           addr, size);
1926
#endif
1927

    
1928
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
1929
}
1930

    
1931
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1932
                                      uint8_t *buf, int len, int do_bswap)
1933
{
1934
    cpu_physical_memory_write(addr, buf, len);
1935
}
1936

    
1937
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1938
                                     uint8_t *buf, int len, int do_bswap)
1939
{
1940
    cpu_physical_memory_read(addr, buf, len);
1941
}
1942

    
1943
static void pci_pcnet_cleanup(VLANClientState *nc)
1944
{
1945
    PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
1946

    
1947
    pcnet_common_cleanup(d);
1948
}
1949

    
1950
static int pci_pcnet_uninit(PCIDevice *dev)
1951
{
1952
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
1953

    
1954
    cpu_unregister_io_memory(d->state.mmio_index);
1955
    qemu_del_timer(d->state.poll_timer);
1956
    qemu_free_timer(d->state.poll_timer);
1957
    qemu_del_vlan_client(&d->state.nic->nc);
1958
    return 0;
1959
}
1960

    
1961
static NetClientInfo net_pci_pcnet_info = {
1962
    .type = NET_CLIENT_TYPE_NIC,
1963
    .size = sizeof(NICState),
1964
    .can_receive = pcnet_can_receive,
1965
    .receive = pcnet_receive,
1966
    .cleanup = pci_pcnet_cleanup,
1967
};
1968

    
1969
static int pci_pcnet_init(PCIDevice *pci_dev)
1970
{
1971
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
1972
    PCNetState *s = &d->state;
1973
    uint8_t *pci_conf;
1974

    
1975
#if 0
1976
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
1977
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1978
#endif
1979

    
1980
    pci_conf = pci_dev->config;
1981

    
1982
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
1983
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
1984
    pci_set_word(pci_conf + PCI_STATUS,
1985
                 PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
1986
    pci_conf[PCI_REVISION_ID] = 0x10;
1987
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
1988

    
1989
    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
1990
    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
1991

    
1992
    pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
1993
    pci_conf[PCI_MIN_GNT] = 0x06;
1994
    pci_conf[PCI_MAX_LAT] = 0xff;
1995

    
1996
    /* Handler for memory-mapped I/O */
1997
    s->mmio_index =
1998
      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
1999

    
2000
    pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
2001
                           PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
2002

    
2003
    pci_register_bar(pci_dev, 1, PCNET_PNPMMIO_SIZE,
2004
                           PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map);
2005

    
2006
    s->irq = pci_dev->irq[0];
2007
    s->phys_mem_read = pci_physical_memory_read;
2008
    s->phys_mem_write = pci_physical_memory_write;
2009

    
2010
    if (!pci_dev->qdev.hotplugged) {
2011
        static int loaded = 0;
2012
        if (!loaded) {
2013
            rom_add_option("pxe-pcnet.bin");
2014
            loaded = 1;
2015
        }
2016
    }
2017

    
2018
    return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info);
2019
}
2020

    
2021
static void pci_reset(DeviceState *dev)
2022
{
2023
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev);
2024

    
2025
    pcnet_h_reset(&d->state);
2026
}
2027

    
2028
static PCIDeviceInfo pcnet_info = {
2029
    .qdev.name  = "pcnet",
2030
    .qdev.size  = sizeof(PCIPCNetState),
2031
    .qdev.reset = pci_reset,
2032
    .qdev.vmsd  = &vmstate_pci_pcnet,
2033
    .init       = pci_pcnet_init,
2034
    .exit       = pci_pcnet_uninit,
2035
    .qdev.props = (Property[]) {
2036
        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
2037
        DEFINE_PROP_END_OF_LIST(),
2038
    }
2039
};
2040

    
2041
static void pcnet_register_devices(void)
2042
{
2043
    pci_qdev_register(&pcnet_info);
2044
}
2045

    
2046
device_init(pcnet_register_devices)