Revision 93f1e401

b/Makefile.target
272 272
obj-microblaze-y += xilinx_timer.o
273 273
obj-microblaze-y += xilinx_uartlite.o
274 274
obj-microblaze-y += xilinx_ethlite.o
275
obj-microblaze-y += xilinx_axidma.o
276
obj-microblaze-y += xilinx_axienet.o
275 277

  
276 278
obj-microblaze-$(CONFIG_FDT) += device_tree.o
277 279

  
b/hw/xilinx_axidma.c
1
/*
2
 * QEMU model of Xilinx AXI-DMA block.
3
 *
4
 * Copyright (c) 2011 Edgar E. Iglesias.
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
#include "sysbus.h"
26
#include "qemu-char.h"
27
#include "qemu-timer.h"
28
#include "qemu-log.h"
29
#include "qdev-addr.h"
30

  
31
#include "xilinx_axidma.h"
32

  
33
#define D(x)
34

  
35
#define R_DMACR             (0x00 / 4)
36
#define R_DMASR             (0x04 / 4)
37
#define R_CURDESC           (0x08 / 4)
38
#define R_TAILDESC          (0x10 / 4)
39
#define R_MAX               (0x30 / 4)
40

  
41
enum {
42
    DMACR_RUNSTOP = 1,
43
    DMACR_TAILPTR_MODE = 2,
44
    DMACR_RESET = 4
45
};
46

  
47
enum {
48
    DMASR_HALTED = 1,
49
    DMASR_IDLE  = 2,
50
    DMASR_IOC_IRQ  = 1 << 12,
51
    DMASR_DLY_IRQ  = 1 << 13,
52

  
53
    DMASR_IRQ_MASK = 7 << 12
54
};
55

  
56
struct SDesc {
57
    uint64_t nxtdesc;
58
    uint64_t buffer_address;
59
    uint64_t reserved;
60
    uint32_t control;
61
    uint32_t status;
62
    uint32_t app[6];
63
};
64

  
65
enum {
66
    SDESC_CTRL_EOF = (1 << 26),
67
    SDESC_CTRL_SOF = (1 << 27),
68

  
69
    SDESC_CTRL_LEN_MASK = (1 << 23) - 1
70
};
71

  
72
enum {
73
    SDESC_STATUS_EOF = (1 << 26),
74
    SDESC_STATUS_SOF_BIT = 27,
75
    SDESC_STATUS_SOF = (1 << SDESC_STATUS_SOF_BIT),
76
    SDESC_STATUS_COMPLETE = (1 << 31)
77
};
78

  
79
struct AXIStream {
80
    QEMUBH *bh;
81
    ptimer_state *ptimer;
82
    qemu_irq irq;
83

  
84
    int nr;
85

  
86
    struct SDesc desc;
87
    int pos;
88
    unsigned int complete_cnt;
89
    uint32_t regs[R_MAX];
90
};
91

  
92
struct XilinxAXIDMA {
93
    SysBusDevice busdev;
94
    uint32_t freqhz;
95
    void *dmach;
96

  
97
    struct AXIStream streams[2];
98
};
99

  
100
/*
101
 * Helper calls to extract info from desriptors and other trivial
102
 * state from regs.
103
 */
104
static inline int stream_desc_sof(struct SDesc *d)
105
{
106
    return d->control & SDESC_CTRL_SOF;
107
}
108

  
109
static inline int stream_desc_eof(struct SDesc *d)
110
{
111
    return d->control & SDESC_CTRL_EOF;
112
}
113

  
114
static inline int stream_resetting(struct AXIStream *s)
115
{
116
    return !!(s->regs[R_DMACR] & DMACR_RESET);
117
}
118

  
119
static inline int stream_running(struct AXIStream *s)
120
{
121
    return s->regs[R_DMACR] & DMACR_RUNSTOP;
122
}
123

  
124
static inline int stream_halted(struct AXIStream *s)
125
{
126
    return s->regs[R_DMASR] & DMASR_HALTED;
127
}
128

  
129
static inline int stream_idle(struct AXIStream *s)
130
{
131
    return !!(s->regs[R_DMASR] & DMASR_IDLE);
132
}
133

  
134
static void stream_reset(struct AXIStream *s)
135
{
136
    s->regs[R_DMASR] = DMASR_HALTED;  /* starts up halted.  */
137
    s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshhold.  */
138
}
139

  
140
/* Mapp an offset addr into a channel index.  */
141
static inline int streamid_from_addr(target_phys_addr_t addr)
142
{
143
    int sid;
144

  
145
    sid = addr / (0x30);
146
    sid &= 1;
147
    return sid;
148
}
149

  
150
#ifdef DEBUG_ENET
151
static void stream_desc_show(struct SDesc *d)
152
{
153
    qemu_log("buffer_addr  = " PRIx64 "\n", d->buffer_address);
154
    qemu_log("nxtdesc      = " PRIx64 "\n", d->nxtdesc);
155
    qemu_log("control      = %x\n", d->control);
156
    qemu_log("status       = %x\n", d->status);
157
}
158
#endif
159

  
160
static void stream_desc_load(struct AXIStream *s, target_phys_addr_t addr)
161
{
162
    struct SDesc *d = &s->desc;
163
    int i;
164

  
165
    cpu_physical_memory_read(addr, (void *) d, sizeof *d);
166

  
167
    /* Convert from LE into host endianness.  */
168
    d->buffer_address = le64_to_cpu(d->buffer_address);
169
    d->nxtdesc = le64_to_cpu(d->nxtdesc);
170
    d->control = le32_to_cpu(d->control);
171
    d->status = le32_to_cpu(d->status);
172
    for (i = 0; i < ARRAY_SIZE(d->app); i++) {
173
        d->app[i] = le32_to_cpu(d->app[i]);
174
    }
175
}
176

  
177
static void stream_desc_store(struct AXIStream *s, target_phys_addr_t addr)
178
{
179
    struct SDesc *d = &s->desc;
180
    int i;
181

  
182
    /* Convert from host endianness into LE.  */
183
    d->buffer_address = cpu_to_le64(d->buffer_address);
184
    d->nxtdesc = cpu_to_le64(d->nxtdesc);
185
    d->control = cpu_to_le32(d->control);
186
    d->status = cpu_to_le32(d->status);
187
    for (i = 0; i < ARRAY_SIZE(d->app); i++) {
188
        d->app[i] = cpu_to_le32(d->app[i]);
189
    }
190
    cpu_physical_memory_write(addr, (void *) d, sizeof *d);
191
}
192

  
193
static void stream_update_irq(struct AXIStream *s)
194
{
195
    unsigned int pending, mask, irq;
196

  
197
    pending = s->regs[R_DMASR] & DMASR_IRQ_MASK;
198
    mask = s->regs[R_DMACR] & DMASR_IRQ_MASK;
199

  
200
    irq = pending & mask;
201

  
202
    qemu_set_irq(s->irq, !!irq);
203
}
204

  
205
static void stream_reload_complete_cnt(struct AXIStream *s)
206
{
207
    unsigned int comp_th;
208
    comp_th = (s->regs[R_DMACR] >> 16) & 0xff;
209
    s->complete_cnt = comp_th;
210
}
211

  
212
static void timer_hit(void *opaque)
213
{
214
    struct AXIStream *s = opaque;
215

  
216
    stream_reload_complete_cnt(s);
217
    s->regs[R_DMASR] |= DMASR_DLY_IRQ;
218
    stream_update_irq(s);
219
}
220

  
221
static void stream_complete(struct AXIStream *s)
222
{
223
    unsigned int comp_delay;
224

  
225
    /* Start the delayed timer.  */
226
    comp_delay = s->regs[R_DMACR] >> 24;
227
    if (comp_delay) {
228
        ptimer_stop(s->ptimer);
229
        ptimer_set_count(s->ptimer, comp_delay);
230
        ptimer_run(s->ptimer, 1);
231
    }
232

  
233
    s->complete_cnt--;
234
    if (s->complete_cnt == 0) {
235
        /* Raise the IOC irq.  */
236
        s->regs[R_DMASR] |= DMASR_IOC_IRQ;
237
        stream_reload_complete_cnt(s);
238
    }
239
}
240

  
241
static void stream_process_mem2s(struct AXIStream *s,
242
                                 struct XilinxDMAConnection *dmach)
243
{
244
    uint32_t prev_d;
245
    unsigned char txbuf[16 * 1024];
246
    unsigned int txlen;
247
    uint32_t app[6];
248

  
249
    if (!stream_running(s) || stream_idle(s)) {
250
        return;
251
    }
252

  
253
    while (1) {
254
        stream_desc_load(s, s->regs[R_CURDESC]);
255

  
256
        if (s->desc.status & SDESC_STATUS_COMPLETE) {
257
            s->regs[R_DMASR] |= DMASR_IDLE;
258
            break;
259
        }
260

  
261
        if (stream_desc_sof(&s->desc)) {
262
            s->pos = 0;
263
            memcpy(app, s->desc.app, sizeof app);
264
        }
265

  
266
        txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
267
        if ((txlen + s->pos) > sizeof txbuf) {
268
            hw_error("%s: too small internal txbuf! %d\n", __func__,
269
                     txlen + s->pos);
270
        }
271

  
272
        cpu_physical_memory_read(s->desc.buffer_address,
273
                                 txbuf + s->pos, txlen);
274
        s->pos += txlen;
275

  
276
        if (stream_desc_eof(&s->desc)) {
277
            xlx_dma_push_to_client(dmach, txbuf, s->pos, app);
278
            s->pos = 0;
279
            stream_complete(s);
280
        }
281

  
282
        /* Update the descriptor.  */
283
        s->desc.status = txlen | SDESC_STATUS_COMPLETE;
284
        stream_desc_store(s, s->regs[R_CURDESC]);
285

  
286
        /* Advance.  */
287
        prev_d = s->regs[R_CURDESC];
288
        s->regs[R_CURDESC] = s->desc.nxtdesc;
289
        if (prev_d == s->regs[R_TAILDESC]) {
290
            s->regs[R_DMASR] |= DMASR_IDLE;
291
            break;
292
        }
293
    }
294
}
295

  
296
static void stream_process_s2mem(struct AXIStream *s,
297
                                 unsigned char *buf, size_t len, uint32_t *app)
298
{
299
    uint32_t prev_d;
300
    unsigned int rxlen;
301
    int pos = 0;
302
    int sof = 1;
303

  
304
    if (!stream_running(s) || stream_idle(s)) {
305
        return;
306
    }
307

  
308
    while (len) {
309
        stream_desc_load(s, s->regs[R_CURDESC]);
310

  
311
        if (s->desc.status & SDESC_STATUS_COMPLETE) {
312
            s->regs[R_DMASR] |= DMASR_IDLE;
313
            break;
314
        }
315

  
316
        rxlen = s->desc.control & SDESC_CTRL_LEN_MASK;
317
        if (rxlen > len) {
318
            /* It fits.  */
319
            rxlen = len;
320
        }
321

  
322
        cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen);
323
        len -= rxlen;
324
        pos += rxlen;
325

  
326
        /* Update the descriptor.  */
327
        if (!len) {
328
            int i;
329

  
330
            stream_complete(s);
331
            for (i = 0; i < 5; i++) {
332
                s->desc.app[i] = app[i];
333
            }
334
            s->desc.status |= SDESC_STATUS_EOF;
335
        }
336

  
337
        s->desc.status |= sof << SDESC_STATUS_SOF_BIT;
338
        s->desc.status |= SDESC_STATUS_COMPLETE;
339
        stream_desc_store(s, s->regs[R_CURDESC]);
340
        sof = 0;
341

  
342
        /* Advance.  */
343
        prev_d = s->regs[R_CURDESC];
344
        s->regs[R_CURDESC] = s->desc.nxtdesc;
345
        if (prev_d == s->regs[R_TAILDESC]) {
346
            s->regs[R_DMASR] |= DMASR_IDLE;
347
            break;
348
        }
349
    }
350
}
351

  
352
static
353
void axidma_push(void *opaque, unsigned char *buf, size_t len, uint32_t *app)
354
{
355
    struct XilinxAXIDMA *d = opaque;
356
    struct AXIStream *s = &d->streams[1];
357

  
358
    if (!app) {
359
        hw_error("No stream app data!\n");
360
    }
361
    stream_process_s2mem(s, buf, len, app);
362
    stream_update_irq(s);
363
}
364

  
365
static uint32_t axidma_readl(void *opaque, target_phys_addr_t addr)
366
{
367
    struct XilinxAXIDMA *d = opaque;
368
    struct AXIStream *s;
369
    uint32_t r = 0;
370
    int sid;
371

  
372
    sid = streamid_from_addr(addr);
373
    s = &d->streams[sid];
374

  
375
    addr = addr % 0x30;
376
    addr >>= 2;
377
    switch (addr) {
378
        case R_DMACR:
379
            /* Simulate one cycles reset delay.  */
380
            s->regs[addr] &= ~DMACR_RESET;
381
            r = s->regs[addr];
382
            break;
383
        case R_DMASR:
384
            s->regs[addr] &= 0xffff;
385
            s->regs[addr] |= (s->complete_cnt & 0xff) << 16;
386
            s->regs[addr] |= (ptimer_get_count(s->ptimer) & 0xff) << 24;
387
            r = s->regs[addr];
388
            break;
389
        default:
390
            r = s->regs[addr];
391
            D(qemu_log("%s ch=%d addr=" TARGET_FMT_plx " v=%x\n",
392
                           __func__, sid, addr * 4, r));
393
            break;
394
    }
395
    return r;
396

  
397
}
398

  
399
static void
400
axidma_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
401
{
402
    struct XilinxAXIDMA *d = opaque;
403
    struct AXIStream *s;
404
    int sid;
405

  
406
    sid = streamid_from_addr(addr);
407
    s = &d->streams[sid];
408

  
409
    addr = addr % 0x30;
410
    addr >>= 2;
411
    switch (addr) {
412
        case R_DMACR:
413
            /* Tailptr mode is always on.  */
414
            value |= DMACR_TAILPTR_MODE;
415
            /* Remember our previous reset state.  */
416
            value |= (s->regs[addr] & DMACR_RESET);
417
            s->regs[addr] = value;
418

  
419
            if (value & DMACR_RESET) {
420
                stream_reset(s);
421
            }
422

  
423
            if ((value & 1) && !stream_resetting(s)) {
424
                /* Start processing.  */
425
                s->regs[R_DMASR] &= ~(DMASR_HALTED | DMASR_IDLE);
426
            }
427
            stream_reload_complete_cnt(s);
428
            break;
429

  
430
        case R_DMASR:
431
            /* Mask away write to clear irq lines.  */
432
            value &= ~(value & DMASR_IRQ_MASK);
433
            s->regs[addr] = value;
434
            break;
435

  
436
        case R_TAILDESC:
437
            s->regs[addr] = value;
438
            s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle.  */
439
            if (!sid) {
440
                stream_process_mem2s(s, d->dmach);
441
            }
442
            break;
443
        default:
444
            D(qemu_log("%s: ch=%d addr=" TARGET_FMT_plx " v=%x\n",
445
                  __func__, sid, addr * 4, value));
446
            s->regs[addr] = value;
447
            break;
448
    }
449
    stream_update_irq(s);
450
}
451

  
452
static CPUReadMemoryFunc * const axidma_read[] = {
453
    &axidma_readl,
454
    &axidma_readl,
455
    &axidma_readl,
456
};
457

  
458
static CPUWriteMemoryFunc * const axidma_write[] = {
459
    &axidma_writel,
460
    &axidma_writel,
461
    &axidma_writel,
462
};
463

  
464
static int xilinx_axidma_init(SysBusDevice *dev)
465
{
466
    struct XilinxAXIDMA *s = FROM_SYSBUS(typeof(*s), dev);
467
    int axidma_regs;
468
    int i;
469

  
470
    sysbus_init_irq(dev, &s->streams[1].irq);
471
    sysbus_init_irq(dev, &s->streams[0].irq);
472

  
473
    if (!s->dmach) {
474
        hw_error("Unconnected DMA channel.\n");
475
    }
476

  
477
    xlx_dma_connect_dma(s->dmach, s, axidma_push);
478

  
479
    axidma_regs = cpu_register_io_memory(axidma_read, axidma_write, s,
480
                                       DEVICE_NATIVE_ENDIAN);
481
    sysbus_init_mmio(dev, R_MAX * 4 * 2, axidma_regs);
482

  
483
    for (i = 0; i < 2; i++) {
484
        stream_reset(&s->streams[i]);
485
        s->streams[i].nr = i;
486
        s->streams[i].bh = qemu_bh_new(timer_hit, &s->streams[i]);
487
        s->streams[i].ptimer = ptimer_init(s->streams[i].bh);
488
        ptimer_set_freq(s->streams[i].ptimer, s->freqhz);
489
    }
490
    return 0;
491
}
492

  
493
static SysBusDeviceInfo axidma_info = {
494
    .init = xilinx_axidma_init,
495
    .qdev.name  = "xilinx,axidma",
496
    .qdev.size  = sizeof(struct XilinxAXIDMA),
497
    .qdev.props = (Property[]) {
498
        DEFINE_PROP_UINT32("freqhz", struct XilinxAXIDMA, freqhz, 50000000),
499
        DEFINE_PROP_PTR("dmach", struct XilinxAXIDMA, dmach),
500
        DEFINE_PROP_END_OF_LIST(),
501
    }
502
};
503

  
504
static void xilinx_axidma_register(void)
505
{
506
    sysbus_register_withprop(&axidma_info);
507
}
508

  
509
device_init(xilinx_axidma_register)
b/hw/xilinx_axidma.h
1
/* AXI DMA connection. Used until qdev provides a generic way.  */
2
typedef void (*DMAPushFn)(void *opaque,
3
                            unsigned char *buf, size_t len, uint32_t *app);
4

  
5
struct XilinxDMAConnection {
6
    void *dma;
7
    void *client;
8

  
9
    DMAPushFn to_dma;
10
    DMAPushFn to_client;
11
};
12

  
13
static inline void xlx_dma_connect_client(struct XilinxDMAConnection *dmach,
14
                                          void *c, DMAPushFn f)
15
{
16
    dmach->client = c;
17
    dmach->to_client = f;
18
}
19

  
20
static inline void xlx_dma_connect_dma(struct XilinxDMAConnection *dmach,
21
                                       void *d, DMAPushFn f)
22
{
23
    dmach->dma = d;
24
    dmach->to_dma = f;
25
}
26

  
27
static inline
28
void xlx_dma_push_to_dma(struct XilinxDMAConnection *dmach,
29
                         uint8_t *buf, size_t len, uint32_t *app)
30
{
31
    dmach->to_dma(dmach->dma, buf, len, app);
32
}
33
static inline
34
void xlx_dma_push_to_client(struct XilinxDMAConnection *dmach,
35
                            uint8_t *buf, size_t len, uint32_t *app)
36
{
37
    dmach->to_client(dmach->client, buf, len, app);
38
}
39

  
b/hw/xilinx_axienet.c
1
/*
2
 * QEMU model of Xilinx AXI-Ethernet.
3
 *
4
 * Copyright (c) 2011 Edgar E. Iglesias.
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
#include "sysbus.h"
26
#include "qemu-char.h"
27
#include "qemu-log.h"
28
#include "net.h"
29
#include "net/checksum.h"
30

  
31
#include "xilinx_axidma.h"
32

  
33
#define DPHY(x)
34

  
35
/* Advertisement control register. */
36
#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
37
#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
38
#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
39
#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
40

  
41
struct PHY {
42
    uint32_t regs[32];
43

  
44
    int link;
45

  
46
    unsigned int (*read)(struct PHY *phy, unsigned int req);
47
    void (*write)(struct PHY *phy, unsigned int req,
48
                  unsigned int data);
49
};
50

  
51
static unsigned int tdk_read(struct PHY *phy, unsigned int req)
52
{
53
    int regnum;
54
    unsigned r = 0;
55

  
56
    regnum = req & 0x1f;
57

  
58
    switch (regnum) {
59
        case 1:
60
            if (!phy->link) {
61
                break;
62
            }
63
            /* MR1.  */
64
            /* Speeds and modes.  */
65
            r |= (1 << 13) | (1 << 14);
66
            r |= (1 << 11) | (1 << 12);
67
            r |= (1 << 5); /* Autoneg complete.  */
68
            r |= (1 << 3); /* Autoneg able.  */
69
            r |= (1 << 2); /* link.  */
70
            r |= (1 << 1); /* link.  */
71
            break;
72
        case 5:
73
            /* Link partner ability.
74
               We are kind; always agree with whatever best mode
75
               the guest advertises.  */
76
            r = 1 << 14; /* Success.  */
77
            /* Copy advertised modes.  */
78
            r |= phy->regs[4] & (15 << 5);
79
            /* Autoneg support.  */
80
            r |= 1;
81
            break;
82
        case 17:
83
            /* Marvel PHY on many xilinx boards.  */
84
            r = 0x8000; /* 1000Mb  */
85
            break;
86
        case 18:
87
            {
88
                /* Diagnostics reg.  */
89
                int duplex = 0;
90
                int speed_100 = 0;
91

  
92
                if (!phy->link) {
93
                    break;
94
                }
95

  
96
                /* Are we advertising 100 half or 100 duplex ? */
97
                speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
98
                speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
99

  
100
                /* Are we advertising 10 duplex or 100 duplex ? */
101
                duplex = !!(phy->regs[4] & ADVERTISE_100FULL);
102
                duplex |= !!(phy->regs[4] & ADVERTISE_10FULL);
103
                r = (speed_100 << 10) | (duplex << 11);
104
            }
105
            break;
106

  
107
        default:
108
            r = phy->regs[regnum];
109
            break;
110
    }
111
    DPHY(qemu_log("\n%s %x = reg[%d]\n", __func__, r, regnum));
112
    return r;
113
}
114

  
115
static void
116
tdk_write(struct PHY *phy, unsigned int req, unsigned int data)
117
{
118
    int regnum;
119

  
120
    regnum = req & 0x1f;
121
    DPHY(qemu_log("%s reg[%d] = %x\n", __func__, regnum, data));
122
    switch (regnum) {
123
        default:
124
            phy->regs[regnum] = data;
125
            break;
126
    }
127
}
128

  
129
static void
130
tdk_init(struct PHY *phy)
131
{
132
    phy->regs[0] = 0x3100;
133
    /* PHY Id.  */
134
    phy->regs[2] = 0x0300;
135
    phy->regs[3] = 0xe400;
136
    /* Autonegotiation advertisement reg.  */
137
    phy->regs[4] = 0x01E1;
138
    phy->link = 1;
139

  
140
    phy->read = tdk_read;
141
    phy->write = tdk_write;
142
}
143

  
144
struct MDIOBus {
145
    /* bus.  */
146
    int mdc;
147
    int mdio;
148

  
149
    /* decoder.  */
150
    enum {
151
        PREAMBLE,
152
        SOF,
153
        OPC,
154
        ADDR,
155
        REQ,
156
        TURNAROUND,
157
        DATA
158
    } state;
159
    unsigned int drive;
160

  
161
    unsigned int cnt;
162
    unsigned int addr;
163
    unsigned int opc;
164
    unsigned int req;
165
    unsigned int data;
166

  
167
    struct PHY *devs[32];
168
};
169

  
170
static void
171
mdio_attach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
172
{
173
    bus->devs[addr & 0x1f] = phy;
174
}
175

  
176
#ifdef USE_THIS_DEAD_CODE
177
static void
178
mdio_detach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
179
{
180
    bus->devs[addr & 0x1f] = NULL;
181
}
182
#endif
183

  
184
static uint16_t mdio_read_req(struct MDIOBus *bus, unsigned int addr,
185
                  unsigned int reg)
186
{
187
    struct PHY *phy;
188
    uint16_t data;
189

  
190
    phy = bus->devs[addr];
191
    if (phy && phy->read) {
192
        data = phy->read(phy, reg);
193
    } else {
194
        data = 0xffff;
195
    }
196
    DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
197
    return data;
198
}
199

  
200
static void mdio_write_req(struct MDIOBus *bus, unsigned int addr,
201
               unsigned int reg, uint16_t data)
202
{
203
    struct PHY *phy;
204

  
205
    DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
206
    phy = bus->devs[addr];
207
    if (phy && phy->write) {
208
        phy->write(phy, reg, data);
209
    }
210
}
211

  
212
#define DENET(x)
213

  
214
#define R_RAF      (0x000 / 4)
215
enum {
216
    RAF_MCAST_REJ = (1 << 1),
217
    RAF_BCAST_REJ = (1 << 2),
218
    RAF_EMCF_EN = (1 << 12),
219
    RAF_NEWFUNC_EN = (1 << 11)
220
};
221

  
222
#define R_IS       (0x00C / 4)
223
enum {
224
    IS_HARD_ACCESS_COMPLETE = 1,
225
    IS_AUTONEG = (1 << 1),
226
    IS_RX_COMPLETE = (1 << 2),
227
    IS_RX_REJECT = (1 << 3),
228
    IS_TX_COMPLETE = (1 << 5),
229
    IS_RX_DCM_LOCK = (1 << 6),
230
    IS_MGM_RDY = (1 << 7),
231
    IS_PHY_RST_DONE = (1 << 8),
232
};
233

  
234
#define R_IP       (0x010 / 4)
235
#define R_IE       (0x014 / 4)
236
#define R_UAWL     (0x020 / 4)
237
#define R_UAWU     (0x024 / 4)
238
#define R_PPST     (0x030 / 4)
239
enum {
240
    PPST_LINKSTATUS = (1 << 0),
241
    PPST_PHY_LINKSTATUS = (1 << 7),
242
};
243

  
244
#define R_STATS_RX_BYTESL (0x200 / 4)
245
#define R_STATS_RX_BYTESH (0x204 / 4)
246
#define R_STATS_TX_BYTESL (0x208 / 4)
247
#define R_STATS_TX_BYTESH (0x20C / 4)
248
#define R_STATS_RXL       (0x290 / 4)
249
#define R_STATS_RXH       (0x294 / 4)
250
#define R_STATS_RX_BCASTL (0x2a0 / 4)
251
#define R_STATS_RX_BCASTH (0x2a4 / 4)
252
#define R_STATS_RX_MCASTL (0x2a8 / 4)
253
#define R_STATS_RX_MCASTH (0x2ac / 4)
254

  
255
#define R_RCW0     (0x400 / 4)
256
#define R_RCW1     (0x404 / 4)
257
enum {
258
    RCW1_VLAN = (1 << 27),
259
    RCW1_RX   = (1 << 28),
260
    RCW1_FCS  = (1 << 29),
261
    RCW1_JUM  = (1 << 30),
262
    RCW1_RST  = (1 << 31),
263
};
264

  
265
#define R_TC       (0x408 / 4)
266
enum {
267
    TC_VLAN = (1 << 27),
268
    TC_TX   = (1 << 28),
269
    TC_FCS  = (1 << 29),
270
    TC_JUM  = (1 << 30),
271
    TC_RST  = (1 << 31),
272
};
273

  
274
#define R_EMMC     (0x410 / 4)
275
enum {
276
    EMMC_LINKSPEED_10MB = (0 << 30),
277
    EMMC_LINKSPEED_100MB = (1 << 30),
278
    EMMC_LINKSPEED_1000MB = (2 << 30),
279
};
280

  
281
#define R_PHYC     (0x414 / 4)
282

  
283
#define R_MC       (0x500 / 4)
284
#define MC_EN      (1 << 6)
285

  
286
#define R_MCR      (0x504 / 4)
287
#define R_MWD      (0x508 / 4)
288
#define R_MRD      (0x50c / 4)
289
#define R_MIS      (0x600 / 4)
290
#define R_MIP      (0x620 / 4)
291
#define R_MIE      (0x640 / 4)
292
#define R_MIC      (0x640 / 4)
293

  
294
#define R_UAW0     (0x700 / 4)
295
#define R_UAW1     (0x704 / 4)
296
#define R_FMI      (0x708 / 4)
297
#define R_AF0      (0x710 / 4)
298
#define R_AF1      (0x714 / 4)
299
#define R_MAX      (0x34 / 4)
300

  
301
/* Indirect registers.  */
302
struct TEMAC  {
303
    struct MDIOBus mdio_bus;
304
    struct PHY phy;
305

  
306
    void *parent;
307
};
308

  
309
struct XilinxAXIEnet {
310
    SysBusDevice busdev;
311
    qemu_irq irq;
312
    void *dmach;
313
    NICState *nic;
314
    NICConf conf;
315

  
316

  
317
    uint32_t c_rxmem;
318
    uint32_t c_txmem;
319
    uint32_t c_phyaddr;
320

  
321
    struct TEMAC TEMAC;
322

  
323
    /* MII regs.  */
324
    union {
325
        uint32_t regs[4];
326
        struct {
327
            uint32_t mc;
328
            uint32_t mcr;
329
            uint32_t mwd;
330
            uint32_t mrd;
331
        };
332
    } mii;
333

  
334
    struct {
335
        uint64_t rx_bytes;
336
        uint64_t tx_bytes;
337

  
338
        uint64_t rx;
339
        uint64_t rx_bcast;
340
        uint64_t rx_mcast;
341
    } stats;
342

  
343
    /* Receive configuration words.  */
344
    uint32_t rcw[2];
345
    /* Transmit config.  */
346
    uint32_t tc;
347
    uint32_t emmc;
348
    uint32_t phyc;
349

  
350
    /* Unicast Address Word.  */
351
    uint32_t uaw[2];
352
    /* Unicast address filter used with extended mcast.  */
353
    uint32_t ext_uaw[2];
354
    uint32_t fmi;
355

  
356
    uint32_t regs[R_MAX];
357

  
358
    /* Multicast filter addrs.  */
359
    uint32_t maddr[4][2];
360
    /* 32K x 1 lookup filter.  */
361
    uint32_t ext_mtable[1024];
362

  
363

  
364
    uint8_t *rxmem;
365
};
366

  
367
static void axienet_rx_reset(struct XilinxAXIEnet *s)
368
{
369
    s->rcw[1] = RCW1_JUM | RCW1_FCS | RCW1_RX | RCW1_VLAN;
370
}
371

  
372
static void axienet_tx_reset(struct XilinxAXIEnet *s)
373
{
374
    s->tc = TC_JUM | TC_TX | TC_VLAN;
375
}
376

  
377
static inline int axienet_rx_resetting(struct XilinxAXIEnet *s)
378
{
379
    return s->rcw[1] & RCW1_RST;
380
}
381

  
382
static inline int axienet_rx_enabled(struct XilinxAXIEnet *s)
383
{
384
    return s->rcw[1] & RCW1_RX;
385
}
386

  
387
static inline int axienet_extmcf_enabled(struct XilinxAXIEnet *s)
388
{
389
    return !!(s->regs[R_RAF] & RAF_EMCF_EN);
390
}
391

  
392
static inline int axienet_newfunc_enabled(struct XilinxAXIEnet *s)
393
{
394
    return !!(s->regs[R_RAF] & RAF_NEWFUNC_EN);
395
}
396

  
397
static void axienet_reset(struct XilinxAXIEnet *s)
398
{
399
    axienet_rx_reset(s);
400
    axienet_tx_reset(s);
401

  
402
    s->regs[R_PPST] = PPST_LINKSTATUS | PPST_PHY_LINKSTATUS;
403
    s->regs[R_IS] = IS_AUTONEG | IS_RX_DCM_LOCK | IS_MGM_RDY | IS_PHY_RST_DONE;
404

  
405
    s->emmc = EMMC_LINKSPEED_100MB;
406
}
407

  
408
static void enet_update_irq(struct XilinxAXIEnet *s)
409
{
410
    s->regs[R_IP] = s->regs[R_IS] & s->regs[R_IE];
411
    qemu_set_irq(s->irq, !!s->regs[R_IP]);
412
}
413

  
414
static uint32_t enet_readl(void *opaque, target_phys_addr_t addr)
415
{
416
    struct XilinxAXIEnet *s = opaque;
417
    uint32_t r = 0;
418
    addr >>= 2;
419

  
420
    switch (addr) {
421
        case R_RCW0:
422
        case R_RCW1:
423
            r = s->rcw[addr & 1];
424
            break;
425

  
426
        case R_TC:
427
            r = s->tc;
428
            break;
429

  
430
        case R_EMMC:
431
            r = s->emmc;
432
            break;
433

  
434
        case R_PHYC:
435
            r = s->phyc;
436
            break;
437

  
438
        case R_MCR:
439
            r = s->mii.regs[addr & 3] | (1 << 7); /* Always ready.  */
440
            break;
441

  
442
        case R_STATS_RX_BYTESL:
443
        case R_STATS_RX_BYTESH:
444
            r = s->stats.rx_bytes >> (32 * (addr & 1));
445
            break;
446

  
447
        case R_STATS_TX_BYTESL:
448
        case R_STATS_TX_BYTESH:
449
            r = s->stats.tx_bytes >> (32 * (addr & 1));
450
            break;
451

  
452
        case R_STATS_RXL:
453
        case R_STATS_RXH:
454
            r = s->stats.rx >> (32 * (addr & 1));
455
            break;
456
        case R_STATS_RX_BCASTL:
457
        case R_STATS_RX_BCASTH:
458
            r = s->stats.rx_bcast >> (32 * (addr & 1));
459
            break;
460
        case R_STATS_RX_MCASTL:
461
        case R_STATS_RX_MCASTH:
462
            r = s->stats.rx_mcast >> (32 * (addr & 1));
463
            break;
464

  
465
        case R_MC:
466
        case R_MWD:
467
        case R_MRD:
468
            r = s->mii.regs[addr & 3];
469
            break;
470

  
471
        case R_UAW0:
472
        case R_UAW1:
473
            r = s->uaw[addr & 1];
474
            break;
475

  
476
        case R_UAWU:
477
        case R_UAWL:
478
            r = s->ext_uaw[addr & 1];
479
            break;
480

  
481
        case R_FMI:
482
            r = s->fmi;
483
            break;
484

  
485
        case R_AF0:
486
        case R_AF1:
487
            r = s->maddr[s->fmi & 3][addr & 1];
488
            break;
489

  
490
        case 0x8000 ... 0x83ff:
491
            r = s->ext_mtable[addr - 0x8000];
492
            break;
493

  
494
        default:
495
            if (addr < ARRAY_SIZE(s->regs)) {
496
                r = s->regs[addr];
497
            }
498
            DENET(qemu_log("%s addr=" TARGET_FMT_plx " v=%x\n",
499
                            __func__, addr * 4, r));
500
            break;
501
    }
502
    return r;
503
}
504

  
505
static void
506
enet_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
507
{
508
    struct XilinxAXIEnet *s = opaque;
509
    struct TEMAC *t = &s->TEMAC;
510

  
511
    addr >>= 2;
512
    switch (addr) {
513
        case R_RCW0:
514
        case R_RCW1:
515
            s->rcw[addr & 1] = value;
516
            if ((addr & 1) && value & RCW1_RST) {
517
                axienet_rx_reset(s);
518
            }
519
            break;
520

  
521
        case R_TC:
522
            s->tc = value;
523
            if (value & TC_RST) {
524
                axienet_tx_reset(s);
525
            }
526
            break;
527

  
528
        case R_EMMC:
529
            s->emmc = value;
530
            break;
531

  
532
        case R_PHYC:
533
            s->phyc = value;
534
            break;
535

  
536
        case R_MC:
537
             value &= ((1 < 7) - 1);
538

  
539
             /* Enable the MII.  */
540
             if (value & MC_EN) {
541
                 unsigned int miiclkdiv = value & ((1 << 6) - 1);
542
                 if (!miiclkdiv) {
543
                     qemu_log("AXIENET: MDIO enabled but MDIOCLK is zero!\n");
544
                 }
545
             }
546
             s->mii.mc = value;
547
             break;
548

  
549
        case R_MCR: {
550
             unsigned int phyaddr = (value >> 24) & 0x1f;
551
             unsigned int regaddr = (value >> 16) & 0x1f;
552
             unsigned int op = (value >> 14) & 3;
553
             unsigned int initiate = (value >> 11) & 1;
554

  
555
             if (initiate) {
556
                 if (op == 1) {
557
                     mdio_write_req(&t->mdio_bus, phyaddr, regaddr, s->mii.mwd);
558
                 } else if (op == 2) {
559
                     s->mii.mrd = mdio_read_req(&t->mdio_bus, phyaddr, regaddr);
560
                 } else {
561
                     qemu_log("AXIENET: invalid MDIOBus OP=%d\n", op);
562
                 }
563
             }
564
             s->mii.mcr = value;
565
             break;
566
        }
567

  
568
        case R_MWD:
569
        case R_MRD:
570
             s->mii.regs[addr & 3] = value;
571
             break;
572

  
573

  
574
        case R_UAW0:
575
        case R_UAW1:
576
            s->uaw[addr & 1] = value;
577
            break;
578

  
579
        case R_UAWL:
580
        case R_UAWU:
581
            s->ext_uaw[addr & 1] = value;
582
            break;
583

  
584
        case R_FMI:
585
            s->fmi = value;
586
            break;
587

  
588
        case R_AF0:
589
        case R_AF1:
590
            s->maddr[s->fmi & 3][addr & 1] = value;
591
            break;
592

  
593
        case 0x8000 ... 0x83ff:
594
            s->ext_mtable[addr - 0x8000] = value;
595
            break;
596

  
597
        default:
598
            DENET(qemu_log("%s addr=" TARGET_FMT_plx " v=%x\n",
599
                           __func__, addr * 4, value));
600
            if (addr < ARRAY_SIZE(s->regs)) {
601
                s->regs[addr] = value;
602
            }
603
            break;
604
    }
605
    enet_update_irq(s);
606
}
607

  
608
static CPUReadMemoryFunc * const enet_read[] = {
609
    &enet_readl,
610
    &enet_readl,
611
    &enet_readl,
612
};
613

  
614
static CPUWriteMemoryFunc * const enet_write[] = {
615
    &enet_writel,
616
    &enet_writel,
617
    &enet_writel,
618
};
619

  
620
static int eth_can_rx(VLANClientState *nc)
621
{
622
    struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
623

  
624
    /* RX enabled?  */
625
    return !axienet_rx_resetting(s) && axienet_rx_enabled(s);
626
}
627

  
628
static int enet_match_addr(const uint8_t *buf, uint32_t f0, uint32_t f1)
629
{
630
    int match = 1;
631

  
632
    if (memcmp(buf, &f0, 4)) {
633
        match = 0;
634
    }
635

  
636
    if (buf[4] != (f1 & 0xff) || buf[5] != ((f1 >> 8) & 0xff)) {
637
        match = 0;
638
    }
639

  
640
    return match;
641
}
642

  
643
static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
644
{
645
    struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
646
    static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
647
                                              0xff, 0xff, 0xff};
648
    static const unsigned char sa_ipmcast[3] = {0x01, 0x00, 0x52};
649
    uint32_t app[6] = {0};
650
    int promisc = s->fmi & (1 << 31);
651
    int unicast, broadcast, multicast, ip_multicast = 0;
652
    uint32_t csum32;
653
    uint16_t csum16;
654
    int i;
655

  
656
    s = s;
657
    DENET(qemu_log("%s: %zd bytes\n", __func__, size));
658

  
659
    unicast = ~buf[0] & 0x1;
660
    broadcast = memcmp(buf, sa_bcast, 6) == 0;
661
    multicast = !unicast && !broadcast;
662
    if (multicast && (memcmp(sa_ipmcast, buf, sizeof sa_ipmcast) == 0)) {
663
        ip_multicast = 1;
664
    }
665

  
666
    /* Jumbo or vlan sizes ?  */
667
    if (!(s->rcw[1] & RCW1_JUM)) {
668
        if (size > 1518 && size <= 1522 && !(s->rcw[1] & RCW1_VLAN)) {
669
            return size;
670
        }
671
    }
672

  
673
    /* Basic Address filters.  If you want to use the extended filters
674
       you'll generally have to place the ethernet mac into promiscuous mode
675
       to avoid the basic filtering from dropping most frames.  */
676
    if (!promisc) {
677
        if (unicast) {
678
            if (!enet_match_addr(buf, s->uaw[0], s->uaw[1])) {
679
                return size;
680
            }
681
        } else {
682
            if (broadcast) {
683
                /* Broadcast.  */
684
                if (s->regs[R_RAF] & RAF_BCAST_REJ) {
685
                    return size;
686
                }
687
            } else {
688
                int drop = 1;
689

  
690
                /* Multicast.  */
691
                if (s->regs[R_RAF] & RAF_MCAST_REJ) {
692
                    return size;
693
                }
694

  
695
                for (i = 0; i < 4; i++) {
696
                    if (enet_match_addr(buf, s->maddr[i][0], s->maddr[i][1])) {
697
                        drop = 0;
698
                        break;
699
                    }
700
                }
701

  
702
                if (drop) {
703
                    return size;
704
                }
705
            }
706
        }
707
    }
708

  
709
    /* Extended mcast filtering enabled?  */
710
    if (axienet_newfunc_enabled(s) && axienet_extmcf_enabled(s)) {
711
        if (unicast) {
712
            if (!enet_match_addr(buf, s->ext_uaw[0], s->ext_uaw[1])) {
713
                return size;
714
            }
715
        } else {
716
            if (broadcast) {
717
                /* Broadcast. ???  */
718
                if (s->regs[R_RAF] & RAF_BCAST_REJ) {
719
                    return size;
720
                }
721
            } else {
722
                int idx, bit;
723

  
724
                /* Multicast.  */
725
                if (!memcmp(buf, sa_ipmcast, 3)) {
726
                    return size;
727
                }
728

  
729
                idx  = (buf[4] & 0x7f) << 8;
730
                idx |= buf[5];
731

  
732
                bit = 1 << (idx & 0x1f);
733
                idx >>= 5;
734

  
735
                if (!(s->ext_mtable[idx] & bit)) {
736
                    return size;
737
                }
738
            }
739
        }
740
    }
741

  
742
    if (size < 12) {
743
        s->regs[R_IS] |= IS_RX_REJECT;
744
        enet_update_irq(s);
745
        return -1;
746
    }
747

  
748
    if (size > (s->c_rxmem - 4)) {
749
        size = s->c_rxmem - 4;
750
    }
751

  
752
    memcpy(s->rxmem, buf, size);
753
    memset(s->rxmem + size, 0, 4); /* Clear the FCS.  */
754

  
755
    if (s->rcw[1] & RCW1_FCS) {
756
        size += 4; /* fcs is inband.  */
757
    }
758

  
759
    app[0] = 5 << 28;
760
    csum32 = net_checksum_add(size - 14, (uint8_t *)s->rxmem + 14);
761
    /* Fold it once.  */
762
    csum32 = (csum32 & 0xffff) + (csum32 >> 16);
763
    /* And twice to get rid of possible carries.  */
764
    csum16 = (csum32 & 0xffff) + (csum32 >> 16);
765
    app[3] = csum16;
766
    app[4] = size & 0xffff;
767

  
768
    s->stats.rx_bytes += size;
769
    s->stats.rx++;
770
    if (multicast) {
771
        s->stats.rx_mcast++;
772
        app[2] |= 1 | (ip_multicast << 1);
773
    } else if (broadcast) {
774
        s->stats.rx_bcast++;
775
        app[2] |= 1 << 3;
776
    }
777

  
778
    /* Good frame.  */
779
    app[2] |= 1 << 6;
780

  
781
    xlx_dma_push_to_dma(s->dmach, (void *)s->rxmem, size, app);
782

  
783
    s->regs[R_IS] |= IS_RX_COMPLETE;
784
    enet_update_irq(s);
785
    return size;
786
}
787

  
788
static void eth_cleanup(VLANClientState *nc)
789
{
790
    /* FIXME.  */
791
    struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
792
    qemu_free(s->rxmem);
793
    qemu_free(s);
794
}
795

  
796
static void
797
axienet_stream_push(void *opaque, uint8_t *buf, size_t size, uint32_t *hdr)
798
{
799
    struct XilinxAXIEnet *s = opaque;
800

  
801
    /* TX enable ?  */
802
    if (!(s->tc & TC_TX)) {
803
        return;
804
    }
805

  
806
    /* Jumbo or vlan sizes ?  */
807
    if (!(s->tc & TC_JUM)) {
808
        if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) {
809
            return;
810
        }
811
    }
812

  
813
    if (hdr[0] & 1) {
814
        unsigned int start_off = hdr[1] >> 16;
815
        unsigned int write_off = hdr[1] & 0xffff;
816
        uint32_t tmp_csum;
817
        uint16_t csum;
818

  
819
        tmp_csum = net_checksum_add(size - start_off,
820
                                    (uint8_t *)buf + start_off);
821
        /* Accumulate the seed.  */
822
        tmp_csum += hdr[2] & 0xffff;
823

  
824
        /* Fold the 32bit partial checksum.  */
825
        csum = net_checksum_finish(tmp_csum);
826

  
827
        /* Writeback.  */
828
        buf[write_off] = csum >> 8;
829
        buf[write_off + 1] = csum & 0xff;
830
    }
831

  
832
    qemu_send_packet(&s->nic->nc, buf, size);
833

  
834
    s->stats.tx_bytes += size;
835
    s->regs[R_IS] |= IS_TX_COMPLETE;
836
    enet_update_irq(s);
837
}
838

  
839
static NetClientInfo net_xilinx_enet_info = {
840
    .type = NET_CLIENT_TYPE_NIC,
841
    .size = sizeof(NICState),
842
    .can_receive = eth_can_rx,
843
    .receive = eth_rx,
844
    .cleanup = eth_cleanup,
845
};
846

  
847
static int xilinx_enet_init(SysBusDevice *dev)
848
{
849
    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), dev);
850
    int enet_regs;
851

  
852
    sysbus_init_irq(dev, &s->irq);
853

  
854
    if (!s->dmach) {
855
        hw_error("Unconnected Xilinx Ethernet MAC.\n");
856
    }
857

  
858
    xlx_dma_connect_client(s->dmach, s, axienet_stream_push);
859

  
860
    enet_regs = cpu_register_io_memory(enet_read, enet_write, s,
861
                                       DEVICE_LITTLE_ENDIAN);
862
    sysbus_init_mmio(dev, 0x40000, enet_regs);
863

  
864
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
865
    s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
866
                          dev->qdev.info->name, dev->qdev.id, s);
867
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
868

  
869
    tdk_init(&s->TEMAC.phy);
870
    mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);
871

  
872
    s->TEMAC.parent = s;
873

  
874
    s->rxmem = qemu_malloc(s->c_rxmem);
875
    axienet_reset(s);
876

  
877
    return 0;
878
}
879

  
880
static SysBusDeviceInfo xilinx_enet_info = {
881
    .init = xilinx_enet_init,
882
    .qdev.name  = "xilinx,axienet",
883
    .qdev.size  = sizeof(struct XilinxAXIEnet),
884
    .qdev.props = (Property[]) {
885
        DEFINE_PROP_UINT32("phyaddr", struct XilinxAXIEnet, c_phyaddr, 7),
886
        DEFINE_PROP_UINT32("c_rxmem", struct XilinxAXIEnet, c_rxmem, 0x1000),
887
        DEFINE_PROP_UINT32("c_txmem", struct XilinxAXIEnet, c_txmem, 0x1000),
888
        DEFINE_PROP_PTR("dmach", struct XilinxAXIEnet, dmach),
889
        DEFINE_NIC_PROPERTIES(struct XilinxAXIEnet, conf),
890
        DEFINE_PROP_END_OF_LIST(),
891
    }
892
};
893
static void xilinx_enet_register(void)
894
{
895
    sysbus_register_withprop(&xilinx_enet_info);
896
}
897

  
898
device_init(xilinx_enet_register)

Also available in: Unified diff