xref: /openbmc/qemu/hw/net/fsl_etsec/etsec.c (revision f7ceab1e)
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 
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" HWADDR_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_transaction_begin(etsec->ptimer);
199         ptimer_stop(etsec->ptimer);
200         ptimer_set_count(etsec->ptimer, 1);
201         ptimer_run(etsec->ptimer, 1);
202         ptimer_transaction_commit(etsec->ptimer);
203     }
204 }
205 
206 static void etsec_write(void     *opaque,
207                         hwaddr    addr,
208                         uint64_t  value,
209                         unsigned  size)
210 {
211     eTSEC          *etsec     = opaque;
212     uint32_t        reg_index = addr / 4;
213     eTSEC_Register *reg       = NULL;
214     uint32_t        before    = 0x0;
215 
216     assert(reg_index < ETSEC_REG_NUMBER);
217 
218     reg = &etsec->regs[reg_index];
219     before = reg->value;
220 
221     switch (reg_index) {
222     case IEVENT:
223         /* Write 1 to clear */
224         reg->value &= ~value;
225 
226         etsec_update_irq(etsec);
227         break;
228 
229     case IMASK:
230         reg->value = value;
231 
232         etsec_update_irq(etsec);
233         break;
234 
235     case DMACTRL:
236         write_dmactrl(etsec, reg, reg_index, value);
237         break;
238 
239     case TSTAT:
240         write_tstat(etsec, reg, reg_index, value);
241         break;
242 
243     case RSTAT:
244         write_rstat(etsec, reg, reg_index, value);
245         break;
246 
247     case TBASE0 ... TBASE7:
248         write_tbasex(etsec, reg, reg_index, value);
249         break;
250 
251     case RBASE0 ... RBASE7:
252         write_rbasex(etsec, reg, reg_index, value);
253         break;
254 
255     case MIIMCFG ... MIIMIND:
256         etsec_write_miim(etsec, reg, reg_index, value);
257         break;
258 
259     default:
260         /* Default handling */
261         switch (reg->access) {
262 
263         case ACC_RW:
264         case ACC_WO:
265             reg->value = value;
266             break;
267 
268         case ACC_W1C:
269             reg->value &= ~value;
270             break;
271 
272         case ACC_RO:
273         default:
274             /* Read Only or Unknown register */
275             break;
276         }
277     }
278 
279     DPRINTF("Write 0x%08x @ 0x" HWADDR_FMT_plx
280             " val:0x%08x->0x%08x : %s (%s)\n",
281             (unsigned int)value, addr, before, reg->value,
282             reg->name, reg->desc);
283 }
284 
285 static const MemoryRegionOps etsec_ops = {
286     .read = etsec_read,
287     .write = etsec_write,
288     .endianness = DEVICE_NATIVE_ENDIAN,
289     .impl = {
290         .min_access_size = 4,
291         .max_access_size = 4,
292     },
293 };
294 
295 static void etsec_timer_hit(void *opaque)
296 {
297     eTSEC *etsec = opaque;
298 
299     ptimer_stop(etsec->ptimer);
300 
301     if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) {
302 
303         if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) {
304             etsec_walk_tx_ring(etsec, 0);
305         }
306         ptimer_set_count(etsec->ptimer, 1);
307         ptimer_run(etsec->ptimer, 1);
308     }
309 }
310 
311 static void etsec_reset(DeviceState *d)
312 {
313     eTSEC *etsec = ETSEC_COMMON(d);
314     int i = 0;
315     int reg_index = 0;
316 
317     /* Default value for all registers */
318     for (i = 0; i < ETSEC_REG_NUMBER; i++) {
319         etsec->regs[i].name   = "Reserved";
320         etsec->regs[i].desc   = "";
321         etsec->regs[i].access = ACC_UNKNOWN;
322         etsec->regs[i].value  = 0x00000000;
323     }
324 
325     /* Set-up known registers */
326     for (i = 0; eTSEC_registers_def[i].name != NULL; i++) {
327 
328         reg_index = eTSEC_registers_def[i].offset / 4;
329 
330         etsec->regs[reg_index].name   = eTSEC_registers_def[i].name;
331         etsec->regs[reg_index].desc   = eTSEC_registers_def[i].desc;
332         etsec->regs[reg_index].access = eTSEC_registers_def[i].access;
333         etsec->regs[reg_index].value  = eTSEC_registers_def[i].reset;
334     }
335 
336     etsec->tx_buffer     = NULL;
337     etsec->tx_buffer_len = 0;
338     etsec->rx_buffer     = NULL;
339     etsec->rx_buffer_len = 0;
340 
341     etsec->phy_status =
342         MII_BMSR_EXTCAP   | MII_BMSR_LINK_ST  | MII_BMSR_AUTONEG  |
343         MII_BMSR_AN_COMP  | MII_BMSR_MFPS     | MII_BMSR_EXTSTAT  |
344         MII_BMSR_100T2_HD | MII_BMSR_100T2_FD |
345         MII_BMSR_10T_HD   | MII_BMSR_10T_FD   |
346         MII_BMSR_100TX_HD | MII_BMSR_100TX_FD | MII_BMSR_100T4;
347 
348     etsec_update_irq(etsec);
349 }
350 
351 static ssize_t etsec_receive(NetClientState *nc,
352                              const uint8_t  *buf,
353                              size_t          size)
354 {
355     ssize_t ret;
356     eTSEC *etsec = qemu_get_nic_opaque(nc);
357 
358 #if defined(HEX_DUMP)
359     fprintf(stderr, "%s receive size:%zd\n", nc->name, size);
360     qemu_hexdump(stderr, "", buf, size);
361 #endif
362     /* Flush is unnecessary as are already in receiving path */
363     etsec->need_flush = false;
364     ret = etsec_rx_ring_write(etsec, buf, size);
365     if (ret == 0) {
366         /* The packet will be queued, let's flush it when buffer is available
367          * again. */
368         etsec->need_flush = true;
369     }
370     return ret;
371 }
372 
373 
374 static void etsec_set_link_status(NetClientState *nc)
375 {
376     eTSEC *etsec = qemu_get_nic_opaque(nc);
377 
378     etsec_miim_link_status(etsec, nc);
379 }
380 
381 static NetClientInfo net_etsec_info = {
382     .type = NET_CLIENT_DRIVER_NIC,
383     .size = sizeof(NICState),
384     .receive = etsec_receive,
385     .link_status_changed = etsec_set_link_status,
386 };
387 
388 static void etsec_realize(DeviceState *dev, Error **errp)
389 {
390     eTSEC        *etsec = ETSEC_COMMON(dev);
391 
392     etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
393                               object_get_typename(OBJECT(dev)), dev->id,
394                               &dev->mem_reentrancy_guard, 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     device_class_set_legacy_reset(dc, 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_types[] = {
434     {
435         .name          = TYPE_ETSEC_COMMON,
436         .parent        = TYPE_SYS_BUS_DEVICE,
437         .instance_size = sizeof(eTSEC),
438         .class_init    = etsec_class_init,
439         .instance_init = etsec_instance_init,
440     },
441 };
442 
443 DEFINE_TYPES(etsec_types)
444