1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "qemu-common.h"
27#include "cpu.h"
28#include "hw/sysbus.h"
29#include "hw/hw.h"
30#include "net/net.h"
31
32#define D(x)
33#define R_TX_BUF0 0
34#define R_TX_LEN0 (0x07f4 / 4)
35#define R_TX_GIE0 (0x07f8 / 4)
36#define R_TX_CTRL0 (0x07fc / 4)
37#define R_TX_BUF1 (0x0800 / 4)
38#define R_TX_LEN1 (0x0ff4 / 4)
39#define R_TX_CTRL1 (0x0ffc / 4)
40
41#define R_RX_BUF0 (0x1000 / 4)
42#define R_RX_CTRL0 (0x17fc / 4)
43#define R_RX_BUF1 (0x1800 / 4)
44#define R_RX_CTRL1 (0x1ffc / 4)
45#define R_MAX (0x2000 / 4)
46
47#define GIE_GIE 0x80000000
48
49#define CTRL_I 0x8
50#define CTRL_P 0x2
51#define CTRL_S 0x1
52
53#define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite"
54#define XILINX_ETHLITE(obj) \
55 OBJECT_CHECK(struct xlx_ethlite, (obj), TYPE_XILINX_ETHLITE)
56
57#define R_MDIOADDR (0x07E4 / 4)
58#define R_MDIOWR (0x07E8 / 4)
59#define R_MDIORD (0x07EC / 4)
60#define R_MDIOCTRL (0x07F0 / 4)
61
62
63#define R_MDIOADDR_REGADR_MASK 0x0000001F
64#define R_MDIOADDR_PHYADR_MASK 0x000003E0
65#define R_MDIOADDR_PHYADR_SHIFT 5
66#define R_MDIOADDR_OP_MASK 0x00000400
67
68
69#define R_MDIOWR_WRDATA_MASK 0x0000FFFF
70
71
72#define R_MDIORD_RDDATA_MASK 0x0000FFFF
73
74
75#define R_MDIOCTRL_MDIOSTS_MASK 0x00000001
76#define R_MDIOCTRL_MDIOEN_MASK 0x00000008
77
78
79#define ADVERTISE_10HALF 0x0020
80#define ADVERTISE_10FULL 0x0040
81#define ADVERTISE_100HALF 0x0080
82#define ADVERTISE_100FULL 0x0100
83
84#define DPHY(x)
85
86struct PHY {
87 uint32_t regs[32];
88
89 int link;
90
91 unsigned int (*read)(struct PHY *phy, unsigned int req);
92 void (*write)(struct PHY *phy, unsigned int req,
93 unsigned int data);
94};
95
96static unsigned int tdk_read(struct PHY *phy, unsigned int req)
97{
98 int regnum;
99 unsigned r = 0;
100
101 regnum = req & 0x1f;
102
103 switch (regnum) {
104 case 1:
105 if (!phy->link) {
106 break;
107 }
108
109
110 r |= (1 << 13) | (1 << 14);
111 r |= (1 << 11) | (1 << 12);
112 r |= (1 << 5);
113 r |= (1 << 3);
114 r |= (1 << 2);
115 r |= (1 << 1);
116 break;
117 case 5:
118
119
120
121 r = 1 << 14;
122
123 r |= phy->regs[4] & (15 << 5);
124
125 r |= 1;
126 break;
127 case 17:
128
129 r = 0x4c00;
130 break;
131 case 18:
132 {
133
134 int duplex = 0;
135 int speed_100 = 0;
136 if (!phy->link) {
137 break;
138 }
139
140 speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
141 speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
142
143 duplex = !!(phy->regs[4] & ADVERTISE_100FULL);
144 duplex |= !!(phy->regs[4] & ADVERTISE_10FULL);
145 r = (speed_100 << 10) | (duplex << 11);
146 }
147 break;
148
149 default:
150 r = phy->regs[regnum];
151 break;
152 }
153 DPHY(qemu_log("\n%s %x = reg[%d]\n", __func__, r, regnum));
154 return r;
155}
156
157static void
158tdk_write(struct PHY *phy, unsigned int req, unsigned int data)
159{
160 int regnum;
161
162 regnum = req & 0x1f;
163 DPHY(qemu_log("%s reg[%d] = %x\n", __func__, regnum, data));
164 switch (regnum) {
165 default:
166 phy->regs[regnum] = data;
167 break;
168 }
169
170
171 phy->regs[0] &= ~0x8000;
172}
173
174static void
175tdk_init(struct PHY *phy)
176{
177 phy->regs[0] = 0x3100;
178
179 phy->regs[2] = 0x0141;
180 phy->regs[3] = 0x0cc2;
181
182 phy->regs[4] = 0x01E1;
183 phy->link = 1;
184
185 phy->read = tdk_read;
186 phy->write = tdk_write;
187}
188
189struct MDIOBus {
190
191 int mdc;
192 int mdio;
193
194
195 enum {
196 PREAMBLE,
197 SOF,
198 OPC,
199 ADDR,
200 REQ,
201 TURNAROUND,
202 DATA
203 } state;
204 unsigned int drive;
205
206 unsigned int cnt;
207 unsigned int addr;
208 unsigned int opc;
209 unsigned int req;
210 unsigned int data;
211
212 struct PHY *devs[32];
213};
214
215static void
216mdio_attach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
217{
218 bus->devs[addr & 0x1f] = phy;
219}
220
221#ifdef USE_THIS_DEAD_CODE
222static void
223mdio_detach(struct MDIOBus *bus, struct PHY *phy, unsigned int addr)
224{
225 bus->devs[addr & 0x1f] = NULL;
226}
227#endif
228
229static uint16_t mdio_read_req(struct MDIOBus *bus, unsigned int addr,
230 unsigned int reg)
231{
232 struct PHY *phy;
233 uint16_t data;
234
235 phy = bus->devs[addr];
236 if (phy && phy->read) {
237 data = phy->read(phy, reg);
238 } else {
239 data = 0xffff;
240 }
241 DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
242 return data;
243}
244
245static void mdio_write_req(struct MDIOBus *bus, unsigned int addr,
246 unsigned int reg, uint16_t data)
247{
248 struct PHY *phy;
249
250 DPHY(qemu_log("%s addr=%d reg=%d data=%x\n", __func__, addr, reg, data));
251 phy = bus->devs[addr];
252 if (phy && phy->write) {
253 phy->write(phy, reg, data);
254 }
255}
256
257struct TEMAC {
258 struct MDIOBus mdio_bus;
259 struct PHY phy;
260
261 void *parent;
262};
263
264struct xlx_ethlite
265{
266 SysBusDevice parent_obj;
267
268 MemoryRegion mmio;
269 qemu_irq irq;
270 NICState *nic;
271 NICConf conf;
272
273 uint32_t c_tx_pingpong;
274 uint32_t c_rx_pingpong;
275 unsigned int txbuf;
276 unsigned int rxbuf;
277
278uint32_t c_phyaddr;
279 struct TEMAC TEMAC;
280
281 uint32_t regs[R_MAX];
282};
283
284static inline void eth_pulse_irq(struct xlx_ethlite *s)
285{
286
287 if (s->regs[R_TX_GIE0] & GIE_GIE) {
288 qemu_irq_pulse(s->irq);
289 }
290}
291
292static uint64_t
293eth_read(void *opaque, hwaddr addr, unsigned int size)
294{
295 struct xlx_ethlite *s = opaque;
296 uint32_t r = 0;
297
298 addr >>= 2;
299
300 switch (addr)
301 {
302 case R_TX_GIE0:
303 case R_TX_LEN0:
304 case R_TX_LEN1:
305 case R_TX_CTRL1:
306 case R_TX_CTRL0:
307 case R_RX_CTRL1:
308 case R_RX_CTRL0:
309 r = s->regs[addr];
310 break;
311 case R_MDIOCTRL:
312 r = s->regs[addr] & (~R_MDIOCTRL_MDIOSTS_MASK);
313 break;
314
315 default:
316 r = tswap32(s->regs[addr]);
317 break;
318 }
319 D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr * 4, r));
320 return r;
321}
322
323static void
324eth_write(void *opaque, hwaddr addr,
325 uint64_t val64, unsigned int size)
326{
327 struct xlx_ethlite *s = opaque;
328 unsigned int base = 0;
329 uint32_t value = val64;
330
331 addr >>= 2;
332 switch (addr)
333 {
334 case R_TX_CTRL0:
335 case R_TX_CTRL1:
336 if (addr == R_TX_CTRL1)
337 base = 0x800 / 4;
338
339 D(qemu_log("%s addr=" TARGET_FMT_plx " val=%x\n",
340 __func__, addr * 4, value));
341 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
342 qemu_send_packet(qemu_get_queue(s->nic),
343 (void *) &s->regs[base],
344 s->regs[base + R_TX_LEN0]);
345 D(qemu_log("eth_tx %d\n", s->regs[base + R_TX_LEN0]));
346 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
347 eth_pulse_irq(s);
348 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
349 memcpy(&s->conf.macaddr.a[0], &s->regs[base], 6);
350 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
351 eth_pulse_irq(s);
352 }
353
354
355
356 s->regs[addr] = value & ~(CTRL_P | CTRL_S);
357 break;
358
359
360 case R_RX_CTRL0:
361 case R_RX_CTRL1:
362 if (!(value & CTRL_S)) {
363 qemu_flush_queued_packets(qemu_get_queue(s->nic));
364 }
365
366 case R_TX_LEN0:
367 case R_TX_LEN1:
368 case R_TX_GIE0:
369 D(qemu_log("%s addr=" TARGET_FMT_plx " val=%x\n",
370 __func__, addr * 4, value));
371 s->regs[addr] = value;
372 break;
373 case R_MDIOCTRL:
374 if (((unsigned int)value & R_MDIOCTRL_MDIOSTS_MASK) != 0) {
375 struct TEMAC *t = &s->TEMAC;
376 unsigned int op = s->regs[R_MDIOADDR] & R_MDIOADDR_OP_MASK;
377 unsigned int phyaddr = (s->regs[R_MDIOADDR] &
378 R_MDIOADDR_PHYADR_MASK) >> R_MDIOADDR_PHYADR_SHIFT;
379 unsigned int regaddr = s->regs[R_MDIOADDR] &
380 R_MDIOADDR_REGADR_MASK;
381 if (op) {
382
383 s->regs[R_MDIORD] = mdio_read_req(
384 &t->mdio_bus, phyaddr, regaddr);
385 } else {
386
387 mdio_write_req(&t->mdio_bus, phyaddr, regaddr,
388 s->regs[R_MDIOWR]);
389 }
390 }
391 s->regs[addr] = value;
392
393 default:
394 s->regs[addr] = tswap32(value);
395 break;
396 }
397}
398
399static const MemoryRegionOps eth_ops = {
400 .read = eth_read,
401 .write = eth_write,
402 .endianness = DEVICE_NATIVE_ENDIAN,
403 .valid = {
404 .min_access_size = 4,
405 .max_access_size = 4
406 }
407};
408
409static int eth_can_rx(NetClientState *nc)
410{
411 struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
412 unsigned int rxbase = s->rxbuf * (0x800 / 4);
413
414 return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
415}
416
417static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
418{
419 struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
420 unsigned int rxbase = s->rxbuf * (0x800 / 4);
421
422
423 if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6))
424 return size;
425
426 if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) {
427 D(qemu_log("ethlite lost packet %x\n", s->regs[R_RX_CTRL0]));
428 return -1;
429 }
430
431 D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase));
432 memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
433
434 s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
435 if (s->regs[R_RX_CTRL0] & CTRL_I) {
436 eth_pulse_irq(s);
437 }
438
439
440 s->rxbuf ^= s->c_rx_pingpong;
441 return size;
442}
443
444static void xilinx_ethlite_reset(DeviceState *dev)
445{
446 struct xlx_ethlite *s = XILINX_ETHLITE(dev);
447
448 s->rxbuf = 0;
449}
450
451static NetClientInfo net_xilinx_ethlite_info = {
452 .type = NET_CLIENT_OPTIONS_KIND_NIC,
453 .size = sizeof(NICState),
454 .can_receive = eth_can_rx,
455 .receive = eth_rx,
456};
457
458static void xilinx_ethlite_realize(DeviceState *dev, Error **errp)
459{
460 struct xlx_ethlite *s = XILINX_ETHLITE(dev);
461
462 qemu_macaddr_default_if_unset(&s->conf.macaddr);
463 s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
464 object_get_typename(OBJECT(dev)), dev->id, s);
465 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
466
467 tdk_init(&s->TEMAC.phy);
468 mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);
469}
470
471static void xilinx_ethlite_init(Object *obj)
472{
473 struct xlx_ethlite *s = XILINX_ETHLITE(obj);
474
475 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
476
477 memory_region_init_io(&s->mmio, obj, ð_ops, s,
478 "xlnx.xps-ethernetlite", R_MAX * 4);
479 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
480}
481
482static Property xilinx_ethlite_properties[] = {
483 DEFINE_PROP_UINT32("phyaddr", struct xlx_ethlite, c_phyaddr, 7),
484 DEFINE_PROP_UINT32("tx-ping-pong", struct xlx_ethlite, c_tx_pingpong, 1),
485 DEFINE_PROP_UINT32("rx-ping-pong", struct xlx_ethlite, c_rx_pingpong, 1),
486 DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf),
487 DEFINE_PROP_END_OF_LIST(),
488};
489
490static void xilinx_ethlite_class_init(ObjectClass *klass, void *data)
491{
492 DeviceClass *dc = DEVICE_CLASS(klass);
493
494 dc->realize = xilinx_ethlite_realize;
495 dc->reset = xilinx_ethlite_reset;
496 dc->props = xilinx_ethlite_properties;
497}
498
499static const TypeInfo xilinx_ethlite_info = {
500 .name = TYPE_XILINX_ETHLITE,
501 .parent = TYPE_SYS_BUS_DEVICE,
502 .instance_size = sizeof(struct xlx_ethlite),
503 .instance_init = xilinx_ethlite_init,
504 .class_init = xilinx_ethlite_class_init,
505};
506
507static void xilinx_ethlite_register_types(void)
508{
509 type_register_static(&xilinx_ethlite_info);
510}
511
512type_init(xilinx_ethlite_register_types)
513