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