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