Statistics
| Branch: | Revision:

root / hw / pcnet.c @ c1ded3dc

History | View | Annotate | Download (62.2 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
        (CSR_LOOP(s) && !s->looptest)) {
1053
        return -1;
1054
    }
1055
#ifdef PCNET_DEBUG
1056
    printf("pcnet_receive size=%d\n", size);
1057
#endif
1058

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

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

    
1072
        pcnet_rdte_poll(s);
1073

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

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

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

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

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

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

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

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

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

    
1177
#undef PCNET_RECV_STORE
1178

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

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

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

    
1213
            pcnet_rdte_poll(s);
1214

    
1215
        }
1216
    }
1217

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

    
1221
    return size_;
1222
}
1223

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

    
1230
    s->xmit_pos = -1;
1231

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

    
1237
    s->tx_busy = 1;
1238

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

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

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

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

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

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

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

    
1312
    s->tx_busy = 0;
1313
}
1314

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

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

    
1328
        pcnet_transmit(s);
1329
    }
1330
}
1331

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

    
1336
    qemu_del_timer(s->poll_timer);
1337

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

    
1342
    pcnet_update_irq(s);
1343

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

    
1361

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1569
    /* Initialize the PROM */
1570

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

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

    
1579

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1905
/* PCI interface */
1906

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

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

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

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

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

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

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

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

    
1948
    pcnet_common_cleanup(d);
1949
}
1950

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

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

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

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

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

    
1981
    pci_conf = pci_dev->config;
1982

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2047
device_init(pcnet_register_devices)