xref: /openbmc/qemu/hw/net/fsl_etsec/etsec.c (revision 0430891c)
1 /*
2  * QEMU Freescale eTSEC Emulator
3  *
4  * Copyright (c) 2011-2013 AdaCore
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 /*
26  * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
27  */
28 
29 #include "qemu/osdep.h"
30 #include "sysemu/sysemu.h"
31 #include "hw/sysbus.h"
32 #include "trace.h"
33 #include "hw/ptimer.h"
34 #include "etsec.h"
35 #include "registers.h"
36 
37 /* #define HEX_DUMP */
38 /* #define DEBUG_REGISTER */
39 
40 #ifdef DEBUG_REGISTER
41 static const int debug_etsec = 1;
42 #else
43 static const int debug_etsec;
44 #endif
45 
46 #define DPRINTF(fmt, ...) do {                 \
47     if (debug_etsec) {                         \
48         qemu_log(fmt , ## __VA_ARGS__);        \
49     }                                          \
50     } while (0)
51 
52 static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size)
53 {
54     eTSEC          *etsec     = opaque;
55     uint32_t        reg_index = addr / 4;
56     eTSEC_Register *reg       = NULL;
57     uint32_t        ret       = 0x0;
58 
59     assert(reg_index < ETSEC_REG_NUMBER);
60 
61     reg = &etsec->regs[reg_index];
62 
63 
64     switch (reg->access) {
65     case ACC_WO:
66         ret = 0x00000000;
67         break;
68 
69     case ACC_RW:
70     case ACC_W1C:
71     case ACC_RO:
72     default:
73         ret = reg->value;
74         break;
75     }
76 
77     DPRINTF("Read  0x%08x @ 0x" TARGET_FMT_plx
78             "                            : %s (%s)\n",
79             ret, addr, reg->name, reg->desc);
80 
81     return ret;
82 }
83 
84 static void write_tstat(eTSEC          *etsec,
85                         eTSEC_Register *reg,
86                         uint32_t        reg_index,
87                         uint32_t        value)
88 {
89     int i = 0;
90 
91     for (i = 0; i < 8; i++) {
92         /* Check THLTi flag in TSTAT */
93         if (value & (1 << (31 - i))) {
94             etsec_walk_tx_ring(etsec, i);
95         }
96     }
97 
98     /* Write 1 to clear */
99     reg->value &= ~value;
100 }
101 
102 static void write_rstat(eTSEC          *etsec,
103                         eTSEC_Register *reg,
104                         uint32_t        reg_index,
105                         uint32_t        value)
106 {
107     int i = 0;
108 
109     for (i = 0; i < 8; i++) {
110         /* Check QHLTi flag in RSTAT */
111         if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) {
112             etsec_walk_rx_ring(etsec, i);
113         }
114     }
115 
116     /* Write 1 to clear */
117     reg->value &= ~value;
118 }
119 
120 static void write_tbasex(eTSEC          *etsec,
121                          eTSEC_Register *reg,
122                          uint32_t        reg_index,
123                          uint32_t        value)
124 {
125     reg->value = value & ~0x7;
126 
127     /* Copy this value in the ring's TxBD pointer */
128     etsec->regs[TBPTR0 + (reg_index - TBASE0)].value = value & ~0x7;
129 }
130 
131 static void write_rbasex(eTSEC          *etsec,
132                          eTSEC_Register *reg,
133                          uint32_t        reg_index,
134                          uint32_t        value)
135 {
136     reg->value = value & ~0x7;
137 
138     /* Copy this value in the ring's RxBD pointer */
139     etsec->regs[RBPTR0 + (reg_index - RBASE0)].value = value & ~0x7;
140 }
141 
142 static void write_ievent(eTSEC          *etsec,
143                          eTSEC_Register *reg,
144                          uint32_t        reg_index,
145                          uint32_t        value)
146 {
147     /* Write 1 to clear */
148     reg->value &= ~value;
149 
150     if (!(reg->value & (IEVENT_TXF | IEVENT_TXF))) {
151         qemu_irq_lower(etsec->tx_irq);
152     }
153     if (!(reg->value & (IEVENT_RXF | IEVENT_RXF))) {
154         qemu_irq_lower(etsec->rx_irq);
155     }
156 
157     if (!(reg->value & (IEVENT_MAG | IEVENT_GTSC | IEVENT_GRSC | IEVENT_TXC |
158                         IEVENT_RXC | IEVENT_BABR | IEVENT_BABT | IEVENT_LC |
159                         IEVENT_CRL | IEVENT_FGPI | IEVENT_FIR | IEVENT_FIQ |
160                         IEVENT_DPE | IEVENT_PERR | IEVENT_EBERR | IEVENT_TXE |
161                         IEVENT_XFUN | IEVENT_BSY | IEVENT_MSRO | IEVENT_MMRD |
162                         IEVENT_MMRW))) {
163         qemu_irq_lower(etsec->err_irq);
164     }
165 }
166 
167 static void write_dmactrl(eTSEC          *etsec,
168                           eTSEC_Register *reg,
169                           uint32_t        reg_index,
170                           uint32_t        value)
171 {
172     reg->value = value;
173 
174     if (value & DMACTRL_GRS) {
175 
176         if (etsec->rx_buffer_len != 0) {
177             /* Graceful receive stop delayed until end of frame */
178         } else {
179             /* Graceful receive stop now */
180             etsec->regs[IEVENT].value |= IEVENT_GRSC;
181             if (etsec->regs[IMASK].value & IMASK_GRSCEN) {
182                 qemu_irq_raise(etsec->err_irq);
183             }
184         }
185     }
186 
187     if (value & DMACTRL_GTS) {
188 
189         if (etsec->tx_buffer_len != 0) {
190             /* Graceful transmit stop delayed until end of frame */
191         } else {
192             /* Graceful transmit stop now */
193             etsec->regs[IEVENT].value |= IEVENT_GTSC;
194             if (etsec->regs[IMASK].value & IMASK_GTSCEN) {
195                 qemu_irq_raise(etsec->err_irq);
196             }
197         }
198     }
199 
200     if (!(value & DMACTRL_WOP)) {
201         /* Start polling */
202         ptimer_stop(etsec->ptimer);
203         ptimer_set_count(etsec->ptimer, 1);
204         ptimer_run(etsec->ptimer, 1);
205     }
206 }
207 
208 static void etsec_write(void     *opaque,
209                         hwaddr    addr,
210                         uint64_t  value,
211                         unsigned  size)
212 {
213     eTSEC          *etsec     = opaque;
214     uint32_t        reg_index = addr / 4;
215     eTSEC_Register *reg       = NULL;
216     uint32_t        before    = 0x0;
217 
218     assert(reg_index < ETSEC_REG_NUMBER);
219 
220     reg = &etsec->regs[reg_index];
221     before = reg->value;
222 
223     switch (reg_index) {
224     case IEVENT:
225         write_ievent(etsec, reg, reg_index, value);
226         break;
227 
228     case DMACTRL:
229         write_dmactrl(etsec, reg, reg_index, value);
230         break;
231 
232     case TSTAT:
233         write_tstat(etsec, reg, reg_index, value);
234         break;
235 
236     case RSTAT:
237         write_rstat(etsec, reg, reg_index, value);
238         break;
239 
240     case TBASE0 ... TBASE7:
241         write_tbasex(etsec, reg, reg_index, value);
242         break;
243 
244     case RBASE0 ... RBASE7:
245         write_rbasex(etsec, reg, reg_index, value);
246         break;
247 
248     case MIIMCFG ... MIIMIND:
249         etsec_write_miim(etsec, reg, reg_index, value);
250         break;
251 
252     default:
253         /* Default handling */
254         switch (reg->access) {
255 
256         case ACC_RW:
257         case ACC_WO:
258             reg->value = value;
259             break;
260 
261         case ACC_W1C:
262             reg->value &= ~value;
263             break;
264 
265         case ACC_RO:
266         default:
267             /* Read Only or Unknown register */
268             break;
269         }
270     }
271 
272     DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx
273             " val:0x%08x->0x%08x : %s (%s)\n",
274             (unsigned int)value, addr, before, reg->value,
275             reg->name, reg->desc);
276 }
277 
278 static const MemoryRegionOps etsec_ops = {
279     .read = etsec_read,
280     .write = etsec_write,
281     .endianness = DEVICE_NATIVE_ENDIAN,
282     .impl = {
283         .min_access_size = 4,
284         .max_access_size = 4,
285     },
286 };
287 
288 static void etsec_timer_hit(void *opaque)
289 {
290     eTSEC *etsec = opaque;
291 
292     ptimer_stop(etsec->ptimer);
293 
294     if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) {
295 
296         if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) {
297             etsec_walk_tx_ring(etsec, 0);
298         }
299         ptimer_set_count(etsec->ptimer, 1);
300         ptimer_run(etsec->ptimer, 1);
301     }
302 }
303 
304 static void etsec_reset(DeviceState *d)
305 {
306     eTSEC *etsec = ETSEC_COMMON(d);
307     int i = 0;
308     int reg_index = 0;
309 
310     /* Default value for all registers */
311     for (i = 0; i < ETSEC_REG_NUMBER; i++) {
312         etsec->regs[i].name   = "Reserved";
313         etsec->regs[i].desc   = "";
314         etsec->regs[i].access = ACC_UNKNOWN;
315         etsec->regs[i].value  = 0x00000000;
316     }
317 
318     /* Set-up known registers */
319     for (i = 0; eTSEC_registers_def[i].name != NULL; i++) {
320 
321         reg_index = eTSEC_registers_def[i].offset / 4;
322 
323         etsec->regs[reg_index].name   = eTSEC_registers_def[i].name;
324         etsec->regs[reg_index].desc   = eTSEC_registers_def[i].desc;
325         etsec->regs[reg_index].access = eTSEC_registers_def[i].access;
326         etsec->regs[reg_index].value  = eTSEC_registers_def[i].reset;
327     }
328 
329     etsec->tx_buffer     = NULL;
330     etsec->tx_buffer_len = 0;
331     etsec->rx_buffer     = NULL;
332     etsec->rx_buffer_len = 0;
333 
334     etsec->phy_status =
335         MII_SR_EXTENDED_CAPS    | MII_SR_LINK_STATUS   | MII_SR_AUTONEG_CAPS  |
336         MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
337         MII_SR_EXTENDED_STATUS  | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
338         MII_SR_10T_HD_CAPS      | MII_SR_10T_FD_CAPS   | MII_SR_100X_HD_CAPS  |
339         MII_SR_100X_FD_CAPS     | MII_SR_100T4_CAPS;
340 }
341 
342 static ssize_t etsec_receive(NetClientState *nc,
343                              const uint8_t  *buf,
344                              size_t          size)
345 {
346     ssize_t ret;
347     eTSEC *etsec = qemu_get_nic_opaque(nc);
348 
349 #if defined(HEX_DUMP)
350     fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size);
351     qemu_hexdump(buf, stderr, "", size);
352 #endif
353     /* Flush is unnecessary as are already in receiving path */
354     etsec->need_flush = false;
355     ret = etsec_rx_ring_write(etsec, buf, size);
356     if (ret == 0) {
357         /* The packet will be queued, let's flush it when buffer is available
358          * again. */
359         etsec->need_flush = true;
360     }
361     return ret;
362 }
363 
364 
365 static void etsec_set_link_status(NetClientState *nc)
366 {
367     eTSEC *etsec = qemu_get_nic_opaque(nc);
368 
369     etsec_miim_link_status(etsec, nc);
370 }
371 
372 static NetClientInfo net_etsec_info = {
373     .type = NET_CLIENT_OPTIONS_KIND_NIC,
374     .size = sizeof(NICState),
375     .receive = etsec_receive,
376     .link_status_changed = etsec_set_link_status,
377 };
378 
379 static void etsec_realize(DeviceState *dev, Error **errp)
380 {
381     eTSEC        *etsec = ETSEC_COMMON(dev);
382 
383     etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
384                               object_get_typename(OBJECT(dev)), dev->id, etsec);
385     qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
386 
387 
388     etsec->bh     = qemu_bh_new(etsec_timer_hit, etsec);
389     etsec->ptimer = ptimer_init(etsec->bh);
390     ptimer_set_freq(etsec->ptimer, 100);
391 }
392 
393 static void etsec_instance_init(Object *obj)
394 {
395     eTSEC        *etsec = ETSEC_COMMON(obj);
396     SysBusDevice *sbd   = SYS_BUS_DEVICE(obj);
397 
398     memory_region_init_io(&etsec->io_area, OBJECT(etsec), &etsec_ops, etsec,
399                           "eTSEC", 0x1000);
400     sysbus_init_mmio(sbd, &etsec->io_area);
401 
402     sysbus_init_irq(sbd, &etsec->tx_irq);
403     sysbus_init_irq(sbd, &etsec->rx_irq);
404     sysbus_init_irq(sbd, &etsec->err_irq);
405 }
406 
407 static Property etsec_properties[] = {
408     DEFINE_NIC_PROPERTIES(eTSEC, conf),
409     DEFINE_PROP_END_OF_LIST(),
410 };
411 
412 static void etsec_class_init(ObjectClass *klass, void *data)
413 {
414     DeviceClass *dc = DEVICE_CLASS(klass);
415 
416     dc->realize = etsec_realize;
417     dc->reset = etsec_reset;
418     dc->props = etsec_properties;
419 }
420 
421 static TypeInfo etsec_info = {
422     .name                  = "eTSEC",
423     .parent                = TYPE_SYS_BUS_DEVICE,
424     .instance_size         = sizeof(eTSEC),
425     .class_init            = etsec_class_init,
426     .instance_init         = etsec_instance_init,
427 };
428 
429 static void etsec_register_types(void)
430 {
431     type_register_static(&etsec_info);
432 }
433 
434 type_init(etsec_register_types)
435 
436 DeviceState *etsec_create(hwaddr         base,
437                           MemoryRegion * mr,
438                           NICInfo      * nd,
439                           qemu_irq       tx_irq,
440                           qemu_irq       rx_irq,
441                           qemu_irq       err_irq)
442 {
443     DeviceState *dev;
444 
445     dev = qdev_create(NULL, "eTSEC");
446     qdev_set_nic_properties(dev, nd);
447     qdev_init_nofail(dev);
448 
449     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq);
450     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq);
451     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);
452 
453     memory_region_add_subregion(mr, base,
454                                 SYS_BUS_DEVICE(dev)->mmio[0].memory);
455 
456     return dev;
457 }
458