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