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