]> Git Repo - qemu.git/blame - hw/net/xilinx_axienet.c
xilinx_axienet/dma: Implement rx path flow control
[qemu.git] / hw / net / xilinx_axienet.c
CommitLineData
93f1e401
EI
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
83c9f4ca 25#include "hw/sysbus.h"
1de7afc9 26#include "qemu/log.h"
1422e32d 27#include "net/net.h"
93f1e401 28#include "net/checksum.h"
b4a42f81 29#include "qapi/qmp/qerror.h"
93f1e401 30
83c9f4ca 31#include "hw/stream.h"
93f1e401
EI
32
33#define DPHY(x)
34
f0e7a81c 35#define TYPE_XILINX_AXI_ENET "xlnx.axi-ethernet"
55b3e0c2 36#define TYPE_XILINX_AXI_ENET_DATA_STREAM "xilinx-axienet-data-stream"
f0e7a81c
PC
37
38#define XILINX_AXI_ENET(obj) \
39 OBJECT_CHECK(XilinxAXIEnet, (obj), TYPE_XILINX_AXI_ENET)
40
55b3e0c2
PC
41#define XILINX_AXI_ENET_DATA_STREAM(obj) \
42 OBJECT_CHECK(XilinxAXIEnetStreamSlave, (obj),\
43 TYPE_XILINX_AXI_ENET_DATA_STREAM)
44
93f1e401
EI
45/* Advertisement control register. */
46#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
47#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
48#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
49#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
50
51struct PHY {
52 uint32_t regs[32];
53
54 int link;
55
56 unsigned int (*read)(struct PHY *phy, unsigned int req);
57 void (*write)(struct PHY *phy, unsigned int req,
58 unsigned int data);
59};
60
61static unsigned int tdk_read(struct PHY *phy, unsigned int req)
62{
63 int regnum;
64 unsigned r = 0;
65
66 regnum = req & 0x1f;
67
68 switch (regnum) {
69 case 1:
70 if (!phy->link) {
71 break;
72 }
73 /* MR1. */
74 /* Speeds and modes. */
75 r |= (1 << 13) | (1 << 14);
76 r |= (1 << 11) | (1 << 12);
77 r |= (1 << 5); /* Autoneg complete. */
78 r |= (1 << 3); /* Autoneg able. */
79 r |= (1 << 2); /* link. */
80 r |= (1 << 1); /* link. */
81 break;
82 case 5:
83 /* Link partner ability.
84 We are kind; always agree with whatever best mode
85 the guest advertises. */
86 r = 1 << 14; /* Success. */
87 /* Copy advertised modes. */
88 r |= phy->regs[4] & (15 << 5);
89 /* Autoneg support. */
90 r |= 1;
91 break;
92 case 17:
93 /* Marvel PHY on many xilinx boards. */
94 r = 0x8000; /* 1000Mb */
95 break;
96 case 18:
97 {
98 /* Diagnostics reg. */
99 int duplex = 0;
100 int speed_100 = 0;
101
102 if (!phy->link) {
103 break;
104 }
105
106 /* Are we advertising 100 half or 100 duplex ? */
107 speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
108 speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
109
110 /* Are we advertising 10 duplex or 100 duplex ? */
111 duplex = !!(phy->regs[4] & ADVERTISE_100FULL);
112 duplex |= !!(phy->regs[4] & ADVERTISE_10FULL);
113 r = (speed_100 << 10) | (duplex << 11);
114 }
115 break;
116
117 default:
118 r = phy->regs[regnum];
119 break;
120 }
121 DPHY(qemu_log("\n%s %x = reg[%d]\n", __func__, r, regnum));
122 return r;
123}
124
125static void
126tdk_write(struct PHY *phy, unsigned int req, unsigned int data)
127{
128 int regnum;
129
130 regnum = req & 0x1f;
131 DPHY(qemu_log("%s reg[%d] = %x\n", __func__, regnum, data));
132 switch (regnum) {
133 default:
134 phy->regs[regnum] = data;
135 break;
136 }
137}
138
139static void
140tdk_init(struct PHY *phy)
141{
142 phy->regs[0] = 0x3100;
143 /* PHY Id. */
144 phy->regs[2] = 0x0300;
145 phy->regs[3] = 0xe400;
146 /* Autonegotiation advertisement reg. */
147 phy->regs[4] = 0x01E1;
148 phy->link = 1;
149
150 phy->read = tdk_read;
151 phy->write = tdk_write;
152}
153
154struct MDIOBus {
155 /* bus. */
156 int mdc;
157 int mdio;
158
159 /* decoder. */
160 enum {
161 PREAMBLE,
162 SOF,
163 OPC,
164 ADDR,
165 REQ,
166 TURNAROUND,
167 DATA
168 } state;
169 unsigned int drive;
170
171 unsigned int cnt;
172 unsigned int addr;
173 unsigned int opc;
174 unsigned int req;
175 unsigned int data;
176
177 struct PHY *devs[32];
178};
179
180static void
181mdio_attach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
182{
183 bus->devs[addr & 0x1f] = phy;
184}
185
186#ifdef USE_THIS_DEAD_CODE
187static void
188mdio_detach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
189{
190 bus->devs[addr & 0x1f] = NULL;
191}
192#endif
193
194static uint16_t mdio_read_req(struct MDIOBus *bus, unsigned int addr,
195 unsigned int reg)
196{
197 struct PHY *phy;
198 uint16_t data;
199
200 phy = bus->devs[addr];
201 if (phy && phy->read) {
202 data = phy->read(phy, reg);
203 } else {
204 data = 0xffff;
205 }
206 DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
207 return data;
208}
209
210static void mdio_write_req(struct MDIOBus *bus, unsigned int addr,
211 unsigned int reg, uint16_t data)
212{
213 struct PHY *phy;
214
215 DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
216 phy = bus->devs[addr];
217 if (phy && phy->write) {
218 phy->write(phy, reg, data);
219 }
220}
221
222#define DENET(x)
223
224#define R_RAF (0x000 / 4)
225enum {
226 RAF_MCAST_REJ = (1 << 1),
227 RAF_BCAST_REJ = (1 << 2),
228 RAF_EMCF_EN = (1 << 12),
229 RAF_NEWFUNC_EN = (1 << 11)
230};
231
232#define R_IS (0x00C / 4)
233enum {
234 IS_HARD_ACCESS_COMPLETE = 1,
235 IS_AUTONEG = (1 << 1),
236 IS_RX_COMPLETE = (1 << 2),
237 IS_RX_REJECT = (1 << 3),
238 IS_TX_COMPLETE = (1 << 5),
239 IS_RX_DCM_LOCK = (1 << 6),
240 IS_MGM_RDY = (1 << 7),
241 IS_PHY_RST_DONE = (1 << 8),
242};
243
244#define R_IP (0x010 / 4)
245#define R_IE (0x014 / 4)
246#define R_UAWL (0x020 / 4)
247#define R_UAWU (0x024 / 4)
248#define R_PPST (0x030 / 4)
249enum {
250 PPST_LINKSTATUS = (1 << 0),
251 PPST_PHY_LINKSTATUS = (1 << 7),
252};
253
254#define R_STATS_RX_BYTESL (0x200 / 4)
255#define R_STATS_RX_BYTESH (0x204 / 4)
256#define R_STATS_TX_BYTESL (0x208 / 4)
257#define R_STATS_TX_BYTESH (0x20C / 4)
258#define R_STATS_RXL (0x290 / 4)
259#define R_STATS_RXH (0x294 / 4)
260#define R_STATS_RX_BCASTL (0x2a0 / 4)
261#define R_STATS_RX_BCASTH (0x2a4 / 4)
262#define R_STATS_RX_MCASTL (0x2a8 / 4)
263#define R_STATS_RX_MCASTH (0x2ac / 4)
264
265#define R_RCW0 (0x400 / 4)
266#define R_RCW1 (0x404 / 4)
267enum {
268 RCW1_VLAN = (1 << 27),
269 RCW1_RX = (1 << 28),
270 RCW1_FCS = (1 << 29),
271 RCW1_JUM = (1 << 30),
272 RCW1_RST = (1 << 31),
273};
274
275#define R_TC (0x408 / 4)
276enum {
277 TC_VLAN = (1 << 27),
278 TC_TX = (1 << 28),
279 TC_FCS = (1 << 29),
280 TC_JUM = (1 << 30),
281 TC_RST = (1 << 31),
282};
283
284#define R_EMMC (0x410 / 4)
285enum {
286 EMMC_LINKSPEED_10MB = (0 << 30),
287 EMMC_LINKSPEED_100MB = (1 << 30),
288 EMMC_LINKSPEED_1000MB = (2 << 30),
289};
290
291#define R_PHYC (0x414 / 4)
292
293#define R_MC (0x500 / 4)
294#define MC_EN (1 << 6)
295
296#define R_MCR (0x504 / 4)
297#define R_MWD (0x508 / 4)
298#define R_MRD (0x50c / 4)
299#define R_MIS (0x600 / 4)
300#define R_MIP (0x620 / 4)
301#define R_MIE (0x640 / 4)
302#define R_MIC (0x640 / 4)
303
304#define R_UAW0 (0x700 / 4)
305#define R_UAW1 (0x704 / 4)
306#define R_FMI (0x708 / 4)
307#define R_AF0 (0x710 / 4)
308#define R_AF1 (0x714 / 4)
309#define R_MAX (0x34 / 4)
310
311/* Indirect registers. */
312struct TEMAC {
313 struct MDIOBus mdio_bus;
314 struct PHY phy;
315
316 void *parent;
317};
318
55b3e0c2 319typedef struct XilinxAXIEnetStreamSlave XilinxAXIEnetStreamSlave;
545129e5
PC
320typedef struct XilinxAXIEnet XilinxAXIEnet;
321
55b3e0c2
PC
322struct XilinxAXIEnetStreamSlave {
323 Object parent;
324
325 struct XilinxAXIEnet *enet;
326} ;
327
93f1e401
EI
328struct XilinxAXIEnet {
329 SysBusDevice busdev;
0dc31f3b 330 MemoryRegion iomem;
93f1e401 331 qemu_irq irq;
669b4983 332 StreamSlave *tx_dev;
55b3e0c2 333 XilinxAXIEnetStreamSlave rx_data_dev;
93f1e401
EI
334 NICState *nic;
335 NICConf conf;
336
337
338 uint32_t c_rxmem;
339 uint32_t c_txmem;
340 uint32_t c_phyaddr;
341
342 struct TEMAC TEMAC;
343
344 /* MII regs. */
345 union {
346 uint32_t regs[4];
347 struct {
348 uint32_t mc;
349 uint32_t mcr;
350 uint32_t mwd;
351 uint32_t mrd;
352 };
353 } mii;
354
355 struct {
356 uint64_t rx_bytes;
357 uint64_t tx_bytes;
358
359 uint64_t rx;
360 uint64_t rx_bcast;
361 uint64_t rx_mcast;
362 } stats;
363
364 /* Receive configuration words. */
365 uint32_t rcw[2];
366 /* Transmit config. */
367 uint32_t tc;
368 uint32_t emmc;
369 uint32_t phyc;
370
371 /* Unicast Address Word. */
372 uint32_t uaw[2];
373 /* Unicast address filter used with extended mcast. */
374 uint32_t ext_uaw[2];
375 uint32_t fmi;
376
377 uint32_t regs[R_MAX];
378
379 /* Multicast filter addrs. */
380 uint32_t maddr[4][2];
381 /* 32K x 1 lookup filter. */
382 uint32_t ext_mtable[1024];
383
384
385 uint8_t *rxmem;
3630ae95
PC
386 uint32_t *rxapp;
387 uint32_t rxsize;
388 uint32_t rxpos;
93f1e401
EI
389};
390
545129e5 391static void axienet_rx_reset(XilinxAXIEnet *s)
93f1e401
EI
392{
393 s->rcw[1] = RCW1_JUM | RCW1_FCS | RCW1_RX | RCW1_VLAN;
394}
395
545129e5 396static void axienet_tx_reset(XilinxAXIEnet *s)
93f1e401
EI
397{
398 s->tc = TC_JUM | TC_TX | TC_VLAN;
399}
400
545129e5 401static inline int axienet_rx_resetting(XilinxAXIEnet *s)
93f1e401
EI
402{
403 return s->rcw[1] & RCW1_RST;
404}
405
545129e5 406static inline int axienet_rx_enabled(XilinxAXIEnet *s)
93f1e401
EI
407{
408 return s->rcw[1] & RCW1_RX;
409}
410
545129e5 411static inline int axienet_extmcf_enabled(XilinxAXIEnet *s)
93f1e401
EI
412{
413 return !!(s->regs[R_RAF] & RAF_EMCF_EN);
414}
415
545129e5 416static inline int axienet_newfunc_enabled(XilinxAXIEnet *s)
93f1e401
EI
417{
418 return !!(s->regs[R_RAF] & RAF_NEWFUNC_EN);
419}
420
9ee0ceb7 421static void xilinx_axienet_reset(DeviceState *d)
93f1e401 422{
9ee0ceb7
PC
423 XilinxAXIEnet *s = XILINX_AXI_ENET(d);
424
93f1e401
EI
425 axienet_rx_reset(s);
426 axienet_tx_reset(s);
427
428 s->regs[R_PPST] = PPST_LINKSTATUS | PPST_PHY_LINKSTATUS;
429 s->regs[R_IS] = IS_AUTONEG | IS_RX_DCM_LOCK | IS_MGM_RDY | IS_PHY_RST_DONE;
430
431 s->emmc = EMMC_LINKSPEED_100MB;
432}
433
545129e5 434static void enet_update_irq(XilinxAXIEnet *s)
93f1e401
EI
435{
436 s->regs[R_IP] = s->regs[R_IS] & s->regs[R_IE];
437 qemu_set_irq(s->irq, !!s->regs[R_IP]);
438}
439
a8170e5e 440static uint64_t enet_read(void *opaque, hwaddr addr, unsigned size)
93f1e401 441{
545129e5 442 XilinxAXIEnet *s = opaque;
93f1e401
EI
443 uint32_t r = 0;
444 addr >>= 2;
445
446 switch (addr) {
447 case R_RCW0:
448 case R_RCW1:
449 r = s->rcw[addr & 1];
450 break;
451
452 case R_TC:
453 r = s->tc;
454 break;
455
456 case R_EMMC:
457 r = s->emmc;
458 break;
459
460 case R_PHYC:
461 r = s->phyc;
462 break;
463
464 case R_MCR:
465 r = s->mii.regs[addr & 3] | (1 << 7); /* Always ready. */
466 break;
467
468 case R_STATS_RX_BYTESL:
469 case R_STATS_RX_BYTESH:
470 r = s->stats.rx_bytes >> (32 * (addr & 1));
471 break;
472
473 case R_STATS_TX_BYTESL:
474 case R_STATS_TX_BYTESH:
475 r = s->stats.tx_bytes >> (32 * (addr & 1));
476 break;
477
478 case R_STATS_RXL:
479 case R_STATS_RXH:
480 r = s->stats.rx >> (32 * (addr & 1));
481 break;
482 case R_STATS_RX_BCASTL:
483 case R_STATS_RX_BCASTH:
484 r = s->stats.rx_bcast >> (32 * (addr & 1));
485 break;
486 case R_STATS_RX_MCASTL:
487 case R_STATS_RX_MCASTH:
488 r = s->stats.rx_mcast >> (32 * (addr & 1));
489 break;
490
491 case R_MC:
492 case R_MWD:
493 case R_MRD:
494 r = s->mii.regs[addr & 3];
495 break;
496
497 case R_UAW0:
498 case R_UAW1:
499 r = s->uaw[addr & 1];
500 break;
501
502 case R_UAWU:
503 case R_UAWL:
504 r = s->ext_uaw[addr & 1];
505 break;
506
507 case R_FMI:
508 r = s->fmi;
509 break;
510
511 case R_AF0:
512 case R_AF1:
513 r = s->maddr[s->fmi & 3][addr & 1];
514 break;
515
516 case 0x8000 ... 0x83ff:
517 r = s->ext_mtable[addr - 0x8000];
518 break;
519
520 default:
521 if (addr < ARRAY_SIZE(s->regs)) {
522 r = s->regs[addr];
523 }
524 DENET(qemu_log("%s addr=" TARGET_FMT_plx " v=%x\n",
525 __func__, addr * 4, r));
526 break;
527 }
528 return r;
529}
530
a8170e5e 531static void enet_write(void *opaque, hwaddr addr,
0dc31f3b 532 uint64_t value, unsigned size)
93f1e401 533{
545129e5 534 XilinxAXIEnet *s = opaque;
93f1e401
EI
535 struct TEMAC *t = &s->TEMAC;
536
537 addr >>= 2;
538 switch (addr) {
539 case R_RCW0:
540 case R_RCW1:
541 s->rcw[addr & 1] = value;
542 if ((addr & 1) && value & RCW1_RST) {
543 axienet_rx_reset(s);
4dbb9ed3
PC
544 } else {
545 qemu_flush_queued_packets(qemu_get_queue(s->nic));
93f1e401
EI
546 }
547 break;
548
549 case R_TC:
550 s->tc = value;
551 if (value & TC_RST) {
552 axienet_tx_reset(s);
553 }
554 break;
555
556 case R_EMMC:
557 s->emmc = value;
558 break;
559
560 case R_PHYC:
561 s->phyc = value;
562 break;
563
564 case R_MC:
565 value &= ((1 < 7) - 1);
566
567 /* Enable the MII. */
568 if (value & MC_EN) {
569 unsigned int miiclkdiv = value & ((1 << 6) - 1);
570 if (!miiclkdiv) {
571 qemu_log("AXIENET: MDIO enabled but MDIOCLK is zero!\n");
572 }
573 }
574 s->mii.mc = value;
575 break;
576
577 case R_MCR: {
578 unsigned int phyaddr = (value >> 24) & 0x1f;
579 unsigned int regaddr = (value >> 16) & 0x1f;
580 unsigned int op = (value >> 14) & 3;
581 unsigned int initiate = (value >> 11) & 1;
582
583 if (initiate) {
584 if (op == 1) {
585 mdio_write_req(&t->mdio_bus, phyaddr, regaddr, s->mii.mwd);
586 } else if (op == 2) {
587 s->mii.mrd = mdio_read_req(&t->mdio_bus, phyaddr, regaddr);
588 } else {
589 qemu_log("AXIENET: invalid MDIOBus OP=%d\n", op);
590 }
591 }
592 s->mii.mcr = value;
593 break;
594 }
595
596 case R_MWD:
597 case R_MRD:
598 s->mii.regs[addr & 3] = value;
599 break;
600
601
602 case R_UAW0:
603 case R_UAW1:
604 s->uaw[addr & 1] = value;
605 break;
606
607 case R_UAWL:
608 case R_UAWU:
609 s->ext_uaw[addr & 1] = value;
610 break;
611
612 case R_FMI:
613 s->fmi = value;
614 break;
615
616 case R_AF0:
617 case R_AF1:
618 s->maddr[s->fmi & 3][addr & 1] = value;
619 break;
620
d4d230da
PC
621 case R_IS:
622 s->regs[addr] &= ~value;
623 break;
624
93f1e401
EI
625 case 0x8000 ... 0x83ff:
626 s->ext_mtable[addr - 0x8000] = value;
627 break;
628
629 default:
630 DENET(qemu_log("%s addr=" TARGET_FMT_plx " v=%x\n",
0dc31f3b 631 __func__, addr * 4, (unsigned)value));
93f1e401
EI
632 if (addr < ARRAY_SIZE(s->regs)) {
633 s->regs[addr] = value;
634 }
635 break;
636 }
637 enet_update_irq(s);
638}
639
0dc31f3b
AK
640static const MemoryRegionOps enet_ops = {
641 .read = enet_read,
642 .write = enet_write,
643 .endianness = DEVICE_LITTLE_ENDIAN,
93f1e401
EI
644};
645
4e68f7a0 646static int eth_can_rx(NetClientState *nc)
93f1e401 647{
545129e5 648 XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
93f1e401
EI
649
650 /* RX enabled? */
3630ae95 651 return !s->rxsize && !axienet_rx_resetting(s) && axienet_rx_enabled(s);
93f1e401
EI
652}
653
654static int enet_match_addr(const uint8_t *buf, uint32_t f0, uint32_t f1)
655{
656 int match = 1;
657
658 if (memcmp(buf, &f0, 4)) {
659 match = 0;
660 }
661
662 if (buf[4] != (f1 & 0xff) || buf[5] != ((f1 >> 8) & 0xff)) {
663 match = 0;
664 }
665
666 return match;
667}
668
3630ae95
PC
669static void axienet_eth_rx_notify(void *opaque)
670{
671 XilinxAXIEnet *s = XILINX_AXI_ENET(opaque);
672
673 while (s->rxsize && stream_can_push(s->tx_dev, axienet_eth_rx_notify, s)) {
674 size_t ret = stream_push(s->tx_dev, (void *)s->rxmem + s->rxpos,
675 s->rxsize, s->rxapp);
676 s->rxsize -= ret;
677 s->rxpos += ret;
678 if (!s->rxsize) {
679 s->regs[R_IS] |= IS_RX_COMPLETE;
680 g_free(s->rxapp);
681 }
682 }
683 enet_update_irq(s);
684}
685
4e68f7a0 686static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
93f1e401 687{
545129e5 688 XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
93f1e401
EI
689 static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
690 0xff, 0xff, 0xff};
691 static const unsigned char sa_ipmcast[3] = {0x01, 0x00, 0x52};
692 uint32_t app[6] = {0};
693 int promisc = s->fmi & (1 << 31);
694 int unicast, broadcast, multicast, ip_multicast = 0;
695 uint32_t csum32;
696 uint16_t csum16;
697 int i;
698
93f1e401
EI
699 DENET(qemu_log("%s: %zd bytes\n", __func__, size));
700
701 unicast = ~buf[0] & 0x1;
702 broadcast = memcmp(buf, sa_bcast, 6) == 0;
703 multicast = !unicast && !broadcast;
704 if (multicast && (memcmp(sa_ipmcast, buf, sizeof sa_ipmcast) == 0)) {
705 ip_multicast = 1;
706 }
707
708 /* Jumbo or vlan sizes ? */
709 if (!(s->rcw[1] & RCW1_JUM)) {
710 if (size > 1518 && size <= 1522 && !(s->rcw[1] & RCW1_VLAN)) {
711 return size;
712 }
713 }
714
715 /* Basic Address filters. If you want to use the extended filters
716 you'll generally have to place the ethernet mac into promiscuous mode
717 to avoid the basic filtering from dropping most frames. */
718 if (!promisc) {
719 if (unicast) {
720 if (!enet_match_addr(buf, s->uaw[0], s->uaw[1])) {
721 return size;
722 }
723 } else {
724 if (broadcast) {
725 /* Broadcast. */
726 if (s->regs[R_RAF] & RAF_BCAST_REJ) {
727 return size;
728 }
729 } else {
730 int drop = 1;
731
732 /* Multicast. */
733 if (s->regs[R_RAF] & RAF_MCAST_REJ) {
734 return size;
735 }
736
737 for (i = 0; i < 4; i++) {
738 if (enet_match_addr(buf, s->maddr[i][0], s->maddr[i][1])) {
739 drop = 0;
740 break;
741 }
742 }
743
744 if (drop) {
745 return size;
746 }
747 }
748 }
749 }
750
751 /* Extended mcast filtering enabled? */
752 if (axienet_newfunc_enabled(s) && axienet_extmcf_enabled(s)) {
753 if (unicast) {
754 if (!enet_match_addr(buf, s->ext_uaw[0], s->ext_uaw[1])) {
755 return size;
756 }
757 } else {
758 if (broadcast) {
759 /* Broadcast. ??? */
760 if (s->regs[R_RAF] & RAF_BCAST_REJ) {
761 return size;
762 }
763 } else {
764 int idx, bit;
765
766 /* Multicast. */
767 if (!memcmp(buf, sa_ipmcast, 3)) {
768 return size;
769 }
770
771 idx = (buf[4] & 0x7f) << 8;
772 idx |= buf[5];
773
774 bit = 1 << (idx & 0x1f);
775 idx >>= 5;
776
777 if (!(s->ext_mtable[idx] & bit)) {
778 return size;
779 }
780 }
781 }
782 }
783
784 if (size < 12) {
785 s->regs[R_IS] |= IS_RX_REJECT;
786 enet_update_irq(s);
787 return -1;
788 }
789
790 if (size > (s->c_rxmem - 4)) {
791 size = s->c_rxmem - 4;
792 }
793
794 memcpy(s->rxmem, buf, size);
795 memset(s->rxmem + size, 0, 4); /* Clear the FCS. */
796
797 if (s->rcw[1] & RCW1_FCS) {
798 size += 4; /* fcs is inband. */
799 }
800
801 app[0] = 5 << 28;
802 csum32 = net_checksum_add(size - 14, (uint8_t *)s->rxmem + 14);
803 /* Fold it once. */
804 csum32 = (csum32 & 0xffff) + (csum32 >> 16);
805 /* And twice to get rid of possible carries. */
806 csum16 = (csum32 & 0xffff) + (csum32 >> 16);
807 app[3] = csum16;
808 app[4] = size & 0xffff;
809
810 s->stats.rx_bytes += size;
811 s->stats.rx++;
812 if (multicast) {
813 s->stats.rx_mcast++;
814 app[2] |= 1 | (ip_multicast << 1);
815 } else if (broadcast) {
816 s->stats.rx_bcast++;
817 app[2] |= 1 << 3;
818 }
819
820 /* Good frame. */
821 app[2] |= 1 << 6;
822
3630ae95
PC
823 s->rxsize = size;
824 s->rxpos = 0;
825 s->rxapp = g_memdup(app, sizeof(app));
826 axienet_eth_rx_notify(s);
93f1e401 827
93f1e401
EI
828 enet_update_irq(s);
829 return size;
830}
831
4e68f7a0 832static void eth_cleanup(NetClientState *nc)
93f1e401
EI
833{
834 /* FIXME. */
545129e5 835 XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
7267c094
AL
836 g_free(s->rxmem);
837 g_free(s);
93f1e401
EI
838}
839
35e60bfd 840static size_t
55b3e0c2
PC
841xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
842 uint32_t *hdr)
93f1e401 843{
55b3e0c2
PC
844 XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
845 XilinxAXIEnet *s = ds->enet;
93f1e401
EI
846
847 /* TX enable ? */
848 if (!(s->tc & TC_TX)) {
35e60bfd 849 return size;
93f1e401
EI
850 }
851
852 /* Jumbo or vlan sizes ? */
853 if (!(s->tc & TC_JUM)) {
854 if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) {
35e60bfd 855 return size;
93f1e401
EI
856 }
857 }
858
859 if (hdr[0] & 1) {
860 unsigned int start_off = hdr[1] >> 16;
861 unsigned int write_off = hdr[1] & 0xffff;
862 uint32_t tmp_csum;
863 uint16_t csum;
864
865 tmp_csum = net_checksum_add(size - start_off,
866 (uint8_t *)buf + start_off);
867 /* Accumulate the seed. */
868 tmp_csum += hdr[2] & 0xffff;
869
870 /* Fold the 32bit partial checksum. */
871 csum = net_checksum_finish(tmp_csum);
872
873 /* Writeback. */
874 buf[write_off] = csum >> 8;
875 buf[write_off + 1] = csum & 0xff;
876 }
877
b356f76d 878 qemu_send_packet(qemu_get_queue(s->nic), buf, size);
93f1e401
EI
879
880 s->stats.tx_bytes += size;
881 s->regs[R_IS] |= IS_TX_COMPLETE;
882 enet_update_irq(s);
35e60bfd
PC
883
884 return size;
93f1e401
EI
885}
886
887static NetClientInfo net_xilinx_enet_info = {
2be64a68 888 .type = NET_CLIENT_OPTIONS_KIND_NIC,
93f1e401
EI
889 .size = sizeof(NICState),
890 .can_receive = eth_can_rx,
891 .receive = eth_rx,
892 .cleanup = eth_cleanup,
893};
894
b2d9dfe9 895static void xilinx_enet_realize(DeviceState *dev, Error **errp)
93f1e401 896{
f0e7a81c 897 XilinxAXIEnet *s = XILINX_AXI_ENET(dev);
55b3e0c2
PC
898 XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
899 Error *local_errp = NULL;
900
901 object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
902 (Object **) &ds->enet, &local_errp);
903 if (local_errp) {
904 goto xilinx_enet_realize_fail;
905 }
906 object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_errp);
907 if (local_errp) {
908 goto xilinx_enet_realize_fail;
909 }
93f1e401 910
93f1e401
EI
911 qemu_macaddr_default_if_unset(&s->conf.macaddr);
912 s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
b2d9dfe9 913 object_get_typename(OBJECT(dev)), dev->id, s);
b356f76d 914 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
93f1e401
EI
915
916 tdk_init(&s->TEMAC.phy);
917 mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);
918
919 s->TEMAC.parent = s;
920
7267c094 921 s->rxmem = g_malloc(s->c_rxmem);
55b3e0c2
PC
922 return;
923
924xilinx_enet_realize_fail:
925 if (!*errp) {
926 *errp = local_errp;
927 }
93f1e401
EI
928}
929
b2d9dfe9 930static void xilinx_enet_init(Object *obj)
669b4983 931{
f0e7a81c 932 XilinxAXIEnet *s = XILINX_AXI_ENET(obj);
b2d9dfe9 933 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
b15aaca4 934 Error *errp = NULL;
669b4983
PC
935
936 object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
b15aaca4
PC
937 (Object **) &s->tx_dev, &errp);
938 assert_no_error(errp);
b2d9dfe9 939
55b3e0c2
PC
940 object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_ENET_DATA_STREAM);
941 object_property_add_child(OBJECT(s), "axistream-connected-target",
942 (Object *)&s->rx_data_dev, &errp);
943 assert_no_error(errp);
944
b2d9dfe9
PC
945 sysbus_init_irq(sbd, &s->irq);
946
947 memory_region_init_io(&s->iomem, &enet_ops, s, "enet", 0x40000);
948 sysbus_init_mmio(sbd, &s->iomem);
669b4983
PC
949}
950
999e12bb 951static Property xilinx_enet_properties[] = {
545129e5
PC
952 DEFINE_PROP_UINT32("phyaddr", XilinxAXIEnet, c_phyaddr, 7),
953 DEFINE_PROP_UINT32("rxmem", XilinxAXIEnet, c_rxmem, 0x1000),
954 DEFINE_PROP_UINT32("txmem", XilinxAXIEnet, c_txmem, 0x1000),
955 DEFINE_NIC_PROPERTIES(XilinxAXIEnet, conf),
999e12bb
AL
956 DEFINE_PROP_END_OF_LIST(),
957};
958
959static void xilinx_enet_class_init(ObjectClass *klass, void *data)
960{
39bffca2 961 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 962
b2d9dfe9 963 dc->realize = xilinx_enet_realize;
39bffca2 964 dc->props = xilinx_enet_properties;
9ee0ceb7 965 dc->reset = xilinx_axienet_reset;
55b3e0c2
PC
966}
967
968static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
969{
970 StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
971
972 ssc->push = data;
999e12bb
AL
973}
974
8c43a6f0 975static const TypeInfo xilinx_enet_info = {
f0e7a81c 976 .name = TYPE_XILINX_AXI_ENET,
39bffca2 977 .parent = TYPE_SYS_BUS_DEVICE,
545129e5 978 .instance_size = sizeof(XilinxAXIEnet),
39bffca2 979 .class_init = xilinx_enet_class_init,
b2d9dfe9 980 .instance_init = xilinx_enet_init,
55b3e0c2
PC
981};
982
983static const TypeInfo xilinx_enet_data_stream_info = {
984 .name = TYPE_XILINX_AXI_ENET_DATA_STREAM,
985 .parent = TYPE_OBJECT,
986 .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
987 .class_init = xilinx_enet_stream_class_init,
988 .class_data = xilinx_axienet_data_stream_push,
669b4983
PC
989 .interfaces = (InterfaceInfo[]) {
990 { TYPE_STREAM_SLAVE },
991 { }
992 }
93f1e401 993};
83f7d43a
AF
994
995static void xilinx_enet_register_types(void)
93f1e401 996{
39bffca2 997 type_register_static(&xilinx_enet_info);
55b3e0c2 998 type_register_static(&xilinx_enet_data_stream_info);
93f1e401
EI
999}
1000
83f7d43a 1001type_init(xilinx_enet_register_types)
This page took 0.510219 seconds and 4 git commands to generate.