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