xref: /openbmc/qemu/hw/net/msf2-emac.c (revision 06d4c71f)
1 /*
2  * QEMU model of the Smartfusion2 Ethernet MAC.
3  *
4  * Copyright (c) 2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
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  * Refer to section Ethernet MAC in the document:
25  * UG0331: SmartFusion2 Microcontroller Subsystem User Guide
26  * Datasheet URL:
27  * https://www.microsemi.com/document-portal/cat_view/56661-internal-documents/
28  * 56758-soc?lang=en&limit=20&limitstart=220
29  */
30 
31 #include "qemu/osdep.h"
32 #include "qemu-common.h"
33 #include "qemu/log.h"
34 #include "qapi/error.h"
35 #include "exec/address-spaces.h"
36 #include "hw/registerfields.h"
37 #include "hw/net/msf2-emac.h"
38 #include "hw/net/mii.h"
39 #include "hw/irq.h"
40 #include "hw/qdev-properties.h"
41 #include "migration/vmstate.h"
42 
43 REG32(CFG1, 0x0)
44     FIELD(CFG1, RESET, 31, 1)
45     FIELD(CFG1, RX_EN, 2, 1)
46     FIELD(CFG1, TX_EN, 0, 1)
47     FIELD(CFG1, LB_EN, 8, 1)
48 REG32(CFG2, 0x4)
49 REG32(IFG, 0x8)
50 REG32(HALF_DUPLEX, 0xc)
51 REG32(MAX_FRAME_LENGTH, 0x10)
52 REG32(MII_CMD, 0x24)
53     FIELD(MII_CMD, READ, 0, 1)
54 REG32(MII_ADDR, 0x28)
55     FIELD(MII_ADDR, REGADDR, 0, 5)
56     FIELD(MII_ADDR, PHYADDR, 8, 5)
57 REG32(MII_CTL, 0x2c)
58 REG32(MII_STS, 0x30)
59 REG32(STA1, 0x40)
60 REG32(STA2, 0x44)
61 REG32(FIFO_CFG0, 0x48)
62 REG32(FIFO_CFG4, 0x58)
63     FIELD(FIFO_CFG4, BCAST, 9, 1)
64     FIELD(FIFO_CFG4, MCAST, 8, 1)
65 REG32(FIFO_CFG5, 0x5C)
66     FIELD(FIFO_CFG5, BCAST, 9, 1)
67     FIELD(FIFO_CFG5, MCAST, 8, 1)
68 REG32(DMA_TX_CTL, 0x180)
69     FIELD(DMA_TX_CTL, EN, 0, 1)
70 REG32(DMA_TX_DESC, 0x184)
71 REG32(DMA_TX_STATUS, 0x188)
72     FIELD(DMA_TX_STATUS, PKTCNT, 16, 8)
73     FIELD(DMA_TX_STATUS, UNDERRUN, 1, 1)
74     FIELD(DMA_TX_STATUS, PKT_SENT, 0, 1)
75 REG32(DMA_RX_CTL, 0x18c)
76     FIELD(DMA_RX_CTL, EN, 0, 1)
77 REG32(DMA_RX_DESC, 0x190)
78 REG32(DMA_RX_STATUS, 0x194)
79     FIELD(DMA_RX_STATUS, PKTCNT, 16, 8)
80     FIELD(DMA_RX_STATUS, OVERFLOW, 2, 1)
81     FIELD(DMA_RX_STATUS, PKT_RCVD, 0, 1)
82 REG32(DMA_IRQ_MASK, 0x198)
83 REG32(DMA_IRQ, 0x19c)
84 
85 #define EMPTY_MASK              (1 << 31)
86 #define PKT_SIZE                0x7FF
87 #define PHYADDR                 0x1
88 #define MAX_PKT_SIZE            2048
89 
90 typedef struct {
91     uint32_t pktaddr;
92     uint32_t pktsize;
93     uint32_t next;
94 } EmacDesc;
95 
96 static uint32_t emac_get_isr(MSF2EmacState *s)
97 {
98     uint32_t ier = s->regs[R_DMA_IRQ_MASK];
99     uint32_t tx = s->regs[R_DMA_TX_STATUS] & 0xF;
100     uint32_t rx = s->regs[R_DMA_RX_STATUS] & 0xF;
101     uint32_t isr = (rx << 4) | tx;
102 
103     s->regs[R_DMA_IRQ] = ier & isr;
104     return s->regs[R_DMA_IRQ];
105 }
106 
107 static void emac_update_irq(MSF2EmacState *s)
108 {
109     bool intr = emac_get_isr(s);
110 
111     qemu_set_irq(s->irq, intr);
112 }
113 
114 static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
115 {
116     address_space_read(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
117     /* Convert from LE into host endianness. */
118     d->pktaddr = le32_to_cpu(d->pktaddr);
119     d->pktsize = le32_to_cpu(d->pktsize);
120     d->next = le32_to_cpu(d->next);
121 }
122 
123 static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
124 {
125     /* Convert from host endianness into LE. */
126     d->pktaddr = cpu_to_le32(d->pktaddr);
127     d->pktsize = cpu_to_le32(d->pktsize);
128     d->next = cpu_to_le32(d->next);
129 
130     address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
131 }
132 
133 static void msf2_dma_tx(MSF2EmacState *s)
134 {
135     NetClientState *nc = qemu_get_queue(s->nic);
136     hwaddr desc = s->regs[R_DMA_TX_DESC];
137     uint8_t buf[MAX_PKT_SIZE];
138     EmacDesc d;
139     int size;
140     uint8_t pktcnt;
141     uint32_t status;
142 
143     if (!(s->regs[R_CFG1] & R_CFG1_TX_EN_MASK)) {
144         return;
145     }
146 
147     while (1) {
148         emac_load_desc(s, &d, desc);
149         if (d.pktsize & EMPTY_MASK) {
150             break;
151         }
152         size = d.pktsize & PKT_SIZE;
153         address_space_read(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
154                            buf, size);
155         /*
156          * This is very basic way to send packets. Ideally there should be
157          * a FIFO and packets should be sent out from FIFO only when
158          * R_CFG1 bit 0 is set.
159          */
160         if (s->regs[R_CFG1] & R_CFG1_LB_EN_MASK) {
161             nc->info->receive(nc, buf, size);
162         } else {
163             qemu_send_packet(nc, buf, size);
164         }
165         d.pktsize |= EMPTY_MASK;
166         emac_store_desc(s, &d, desc);
167         /* update sent packets count */
168         status = s->regs[R_DMA_TX_STATUS];
169         pktcnt = FIELD_EX32(status, DMA_TX_STATUS, PKTCNT);
170         pktcnt++;
171         s->regs[R_DMA_TX_STATUS] = FIELD_DP32(status, DMA_TX_STATUS,
172                                               PKTCNT, pktcnt);
173         s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_PKT_SENT_MASK;
174         desc = d.next;
175     }
176     s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_UNDERRUN_MASK;
177     s->regs[R_DMA_TX_CTL] &= ~R_DMA_TX_CTL_EN_MASK;
178 }
179 
180 static void msf2_phy_update_link(MSF2EmacState *s)
181 {
182     /* Autonegotiation status mirrors link status. */
183     if (qemu_get_queue(s->nic)->link_down) {
184         s->phy_regs[MII_BMSR] &= ~(MII_BMSR_AN_COMP |
185                                    MII_BMSR_LINK_ST);
186     } else {
187         s->phy_regs[MII_BMSR] |= (MII_BMSR_AN_COMP |
188                                   MII_BMSR_LINK_ST);
189     }
190 }
191 
192 static void msf2_phy_reset(MSF2EmacState *s)
193 {
194     memset(&s->phy_regs[0], 0, sizeof(s->phy_regs));
195     s->phy_regs[MII_BMCR] = 0x1140;
196     s->phy_regs[MII_BMSR] = 0x7968;
197     s->phy_regs[MII_PHYID1] = 0x0022;
198     s->phy_regs[MII_PHYID2] = 0x1550;
199     s->phy_regs[MII_ANAR] = 0x01E1;
200     s->phy_regs[MII_ANLPAR] = 0xCDE1;
201 
202     msf2_phy_update_link(s);
203 }
204 
205 static void write_to_phy(MSF2EmacState *s)
206 {
207     uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
208     uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
209                        R_MII_ADDR_REGADDR_MASK;
210     uint16_t data = s->regs[R_MII_CTL] & 0xFFFF;
211 
212     if (phy_addr != PHYADDR) {
213         return;
214     }
215 
216     switch (reg_addr) {
217     case MII_BMCR:
218         if (data & MII_BMCR_RESET) {
219             /* Phy reset */
220             msf2_phy_reset(s);
221             data &= ~MII_BMCR_RESET;
222         }
223         if (data & MII_BMCR_AUTOEN) {
224             /* Complete autonegotiation immediately */
225             data &= ~MII_BMCR_AUTOEN;
226             s->phy_regs[MII_BMSR] |= MII_BMSR_AN_COMP;
227         }
228         break;
229     }
230 
231     s->phy_regs[reg_addr] = data;
232 }
233 
234 static uint16_t read_from_phy(MSF2EmacState *s)
235 {
236     uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
237     uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
238                        R_MII_ADDR_REGADDR_MASK;
239 
240     if (phy_addr == PHYADDR) {
241         return s->phy_regs[reg_addr];
242     } else {
243         return 0xFFFF;
244     }
245 }
246 
247 static void msf2_emac_do_reset(MSF2EmacState *s)
248 {
249     memset(&s->regs[0], 0, sizeof(s->regs));
250     s->regs[R_CFG1] = 0x80000000;
251     s->regs[R_CFG2] = 0x00007000;
252     s->regs[R_IFG] = 0x40605060;
253     s->regs[R_HALF_DUPLEX] = 0x00A1F037;
254     s->regs[R_MAX_FRAME_LENGTH] = 0x00000600;
255     s->regs[R_FIFO_CFG5] = 0X3FFFF;
256 
257     msf2_phy_reset(s);
258 }
259 
260 static uint64_t emac_read(void *opaque, hwaddr addr, unsigned int size)
261 {
262     MSF2EmacState *s = opaque;
263     uint32_t r = 0;
264 
265     addr >>= 2;
266 
267     switch (addr) {
268     case R_DMA_IRQ:
269         r = emac_get_isr(s);
270         break;
271     default:
272         if (addr >= ARRAY_SIZE(s->regs)) {
273             qemu_log_mask(LOG_GUEST_ERROR,
274                           "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
275                           addr * 4);
276             return r;
277         }
278         r = s->regs[addr];
279         break;
280     }
281     return r;
282 }
283 
284 static void emac_write(void *opaque, hwaddr addr, uint64_t val64,
285         unsigned int size)
286 {
287     MSF2EmacState *s = opaque;
288     uint32_t value = val64;
289     uint32_t enreqbits;
290     uint8_t pktcnt;
291 
292     addr >>= 2;
293     switch (addr) {
294     case R_DMA_TX_CTL:
295         s->regs[addr] = value;
296         if (value & R_DMA_TX_CTL_EN_MASK) {
297             msf2_dma_tx(s);
298         }
299         break;
300     case R_DMA_RX_CTL:
301         s->regs[addr] = value;
302         if (value & R_DMA_RX_CTL_EN_MASK) {
303             s->rx_desc = s->regs[R_DMA_RX_DESC];
304             qemu_flush_queued_packets(qemu_get_queue(s->nic));
305         }
306         break;
307     case R_CFG1:
308         s->regs[addr] = value;
309         if (value & R_CFG1_RESET_MASK) {
310             msf2_emac_do_reset(s);
311         }
312         break;
313     case R_FIFO_CFG0:
314        /*
315         * For our implementation, turning on modules is instantaneous,
316         * so the states requested via the *ENREQ bits appear in the
317         * *ENRPLY bits immediately. Also the reset bits to reset PE-MCXMAC
318         * module are not emulated here since it deals with start of frames,
319         * inter-packet gap and control frames.
320         */
321         enreqbits = extract32(value, 8, 5);
322         s->regs[addr] = deposit32(value, 16, 5, enreqbits);
323         break;
324     case R_DMA_TX_DESC:
325         if (value & 0x3) {
326             qemu_log_mask(LOG_GUEST_ERROR, "Tx Descriptor address should be"
327                           " 32 bit aligned\n");
328         }
329         /* Ignore [1:0] bits */
330         s->regs[addr] = value & ~3;
331         break;
332     case R_DMA_RX_DESC:
333         if (value & 0x3) {
334             qemu_log_mask(LOG_GUEST_ERROR, "Rx Descriptor address should be"
335                           " 32 bit aligned\n");
336         }
337         /* Ignore [1:0] bits */
338         s->regs[addr] = value & ~3;
339         break;
340     case R_DMA_TX_STATUS:
341         if (value & R_DMA_TX_STATUS_UNDERRUN_MASK) {
342             s->regs[addr] &= ~R_DMA_TX_STATUS_UNDERRUN_MASK;
343         }
344         if (value & R_DMA_TX_STATUS_PKT_SENT_MASK) {
345             pktcnt = FIELD_EX32(s->regs[addr], DMA_TX_STATUS, PKTCNT);
346             pktcnt--;
347             s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_TX_STATUS,
348                                        PKTCNT, pktcnt);
349             if (pktcnt == 0) {
350                 s->regs[addr] &= ~R_DMA_TX_STATUS_PKT_SENT_MASK;
351             }
352         }
353         break;
354     case R_DMA_RX_STATUS:
355         if (value & R_DMA_RX_STATUS_OVERFLOW_MASK) {
356             s->regs[addr] &= ~R_DMA_RX_STATUS_OVERFLOW_MASK;
357         }
358         if (value & R_DMA_RX_STATUS_PKT_RCVD_MASK) {
359             pktcnt = FIELD_EX32(s->regs[addr], DMA_RX_STATUS, PKTCNT);
360             pktcnt--;
361             s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_RX_STATUS,
362                                        PKTCNT, pktcnt);
363             if (pktcnt == 0) {
364                 s->regs[addr] &= ~R_DMA_RX_STATUS_PKT_RCVD_MASK;
365             }
366         }
367         break;
368     case R_DMA_IRQ:
369         break;
370     case R_MII_CMD:
371         if (value & R_MII_CMD_READ_MASK) {
372             s->regs[R_MII_STS] = read_from_phy(s);
373         }
374         break;
375     case R_MII_CTL:
376         s->regs[addr] = value;
377         write_to_phy(s);
378         break;
379     case R_STA1:
380         s->regs[addr] = value;
381        /*
382         * R_STA1 [31:24] : octet 1 of mac address
383         * R_STA1 [23:16] : octet 2 of mac address
384         * R_STA1 [15:8] : octet 3 of mac address
385         * R_STA1 [7:0] : octet 4 of mac address
386         */
387         stl_be_p(s->mac_addr, value);
388         break;
389     case R_STA2:
390         s->regs[addr] = value;
391        /*
392         * R_STA2 [31:24] : octet 5 of mac address
393         * R_STA2 [23:16] : octet 6 of mac address
394         */
395         stw_be_p(s->mac_addr + 4, value >> 16);
396         break;
397     default:
398         if (addr >= ARRAY_SIZE(s->regs)) {
399             qemu_log_mask(LOG_GUEST_ERROR,
400                           "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
401                           addr * 4);
402             return;
403         }
404         s->regs[addr] = value;
405         break;
406     }
407     emac_update_irq(s);
408 }
409 
410 static const MemoryRegionOps emac_ops = {
411     .read = emac_read,
412     .write = emac_write,
413     .endianness = DEVICE_NATIVE_ENDIAN,
414     .impl = {
415         .min_access_size = 4,
416         .max_access_size = 4
417     }
418 };
419 
420 static bool emac_can_rx(NetClientState *nc)
421 {
422     MSF2EmacState *s = qemu_get_nic_opaque(nc);
423 
424     return (s->regs[R_CFG1] & R_CFG1_RX_EN_MASK) &&
425            (s->regs[R_DMA_RX_CTL] & R_DMA_RX_CTL_EN_MASK);
426 }
427 
428 static bool addr_filter_ok(MSF2EmacState *s, const uint8_t *buf)
429 {
430     /* The broadcast MAC address: FF:FF:FF:FF:FF:FF */
431     const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF,
432                                               0xFF, 0xFF };
433     bool bcast_en = true;
434     bool mcast_en = true;
435 
436     if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_BCAST_MASK) {
437         bcast_en = true; /* Broadcast dont care for drop circuitry */
438     } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_BCAST_MASK) {
439         bcast_en = false;
440     }
441 
442     if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_MCAST_MASK) {
443         mcast_en = true; /* Multicast dont care for drop circuitry */
444     } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_MCAST_MASK) {
445         mcast_en = false;
446     }
447 
448     if (!memcmp(buf, broadcast_addr, sizeof(broadcast_addr))) {
449         return bcast_en;
450     }
451 
452     if (buf[0] & 1) {
453         return mcast_en;
454     }
455 
456     return !memcmp(buf, s->mac_addr, sizeof(s->mac_addr));
457 }
458 
459 static ssize_t emac_rx(NetClientState *nc, const uint8_t *buf, size_t size)
460 {
461     MSF2EmacState *s = qemu_get_nic_opaque(nc);
462     EmacDesc d;
463     uint8_t pktcnt;
464     uint32_t status;
465 
466     if (size > (s->regs[R_MAX_FRAME_LENGTH] & 0xFFFF)) {
467         return size;
468     }
469     if (!addr_filter_ok(s, buf)) {
470         return size;
471     }
472 
473     emac_load_desc(s, &d, s->rx_desc);
474 
475     if (d.pktsize & EMPTY_MASK) {
476         address_space_write(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
477                             buf, size & PKT_SIZE);
478         d.pktsize = size & PKT_SIZE;
479         emac_store_desc(s, &d, s->rx_desc);
480         /* update received packets count */
481         status = s->regs[R_DMA_RX_STATUS];
482         pktcnt = FIELD_EX32(status, DMA_RX_STATUS, PKTCNT);
483         pktcnt++;
484         s->regs[R_DMA_RX_STATUS] = FIELD_DP32(status, DMA_RX_STATUS,
485                                               PKTCNT, pktcnt);
486         s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_PKT_RCVD_MASK;
487         s->rx_desc = d.next;
488     } else {
489         s->regs[R_DMA_RX_CTL] &= ~R_DMA_RX_CTL_EN_MASK;
490         s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_OVERFLOW_MASK;
491     }
492     emac_update_irq(s);
493     return size;
494 }
495 
496 static void msf2_emac_reset(DeviceState *dev)
497 {
498     MSF2EmacState *s = MSS_EMAC(dev);
499 
500     msf2_emac_do_reset(s);
501 }
502 
503 static void emac_set_link(NetClientState *nc)
504 {
505     MSF2EmacState *s = qemu_get_nic_opaque(nc);
506 
507     msf2_phy_update_link(s);
508 }
509 
510 static NetClientInfo net_msf2_emac_info = {
511     .type = NET_CLIENT_DRIVER_NIC,
512     .size = sizeof(NICState),
513     .can_receive = emac_can_rx,
514     .receive = emac_rx,
515     .link_status_changed = emac_set_link,
516 };
517 
518 static void msf2_emac_realize(DeviceState *dev, Error **errp)
519 {
520     MSF2EmacState *s = MSS_EMAC(dev);
521 
522     if (!s->dma_mr) {
523         error_setg(errp, "MSS_EMAC 'ahb-bus' link not set");
524         return;
525     }
526 
527     address_space_init(&s->dma_as, s->dma_mr, "emac-ahb");
528 
529     qemu_macaddr_default_if_unset(&s->conf.macaddr);
530     s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf,
531                           object_get_typename(OBJECT(dev)), dev->id, s);
532     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
533 }
534 
535 static void msf2_emac_init(Object *obj)
536 {
537     MSF2EmacState *s = MSS_EMAC(obj);
538 
539     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
540 
541     memory_region_init_io(&s->mmio, obj, &emac_ops, s,
542                           "msf2-emac", R_MAX * 4);
543     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
544 }
545 
546 static Property msf2_emac_properties[] = {
547     DEFINE_PROP_LINK("ahb-bus", MSF2EmacState, dma_mr,
548                      TYPE_MEMORY_REGION, MemoryRegion *),
549     DEFINE_NIC_PROPERTIES(MSF2EmacState, conf),
550     DEFINE_PROP_END_OF_LIST(),
551 };
552 
553 static const VMStateDescription vmstate_msf2_emac = {
554     .name = TYPE_MSS_EMAC,
555     .version_id = 1,
556     .minimum_version_id = 1,
557     .fields = (VMStateField[]) {
558         VMSTATE_UINT8_ARRAY(mac_addr, MSF2EmacState, ETH_ALEN),
559         VMSTATE_UINT32(rx_desc, MSF2EmacState),
560         VMSTATE_UINT16_ARRAY(phy_regs, MSF2EmacState, PHY_MAX_REGS),
561         VMSTATE_UINT32_ARRAY(regs, MSF2EmacState, R_MAX),
562         VMSTATE_END_OF_LIST()
563     }
564 };
565 
566 static void msf2_emac_class_init(ObjectClass *klass, void *data)
567 {
568     DeviceClass *dc = DEVICE_CLASS(klass);
569 
570     dc->realize = msf2_emac_realize;
571     dc->reset = msf2_emac_reset;
572     dc->vmsd = &vmstate_msf2_emac;
573     device_class_set_props(dc, msf2_emac_properties);
574 }
575 
576 static const TypeInfo msf2_emac_info = {
577     .name          = TYPE_MSS_EMAC,
578     .parent        = TYPE_SYS_BUS_DEVICE,
579     .instance_size = sizeof(MSF2EmacState),
580     .instance_init = msf2_emac_init,
581     .class_init    = msf2_emac_class_init,
582 };
583 
584 static void msf2_emac_register_types(void)
585 {
586     type_register_static(&msf2_emac_info);
587 }
588 
589 type_init(msf2_emac_register_types)
590