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