2 * QEMU model of the Smartfusion2 Ethernet MAC.
4 * Copyright (c) 2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 * Refer to section Ethernet MAC in the document:
25 * UG0331: SmartFusion2 Microcontroller Subsystem User Guide
27 * https://www.microsemi.com/document-portal/cat_view/56661-internal-documents/
28 * 56758-soc?lang=en&limit=20&limitstart=220
31 #include "qemu/osdep.h"
33 #include "qapi/error.h"
34 #include "hw/registerfields.h"
35 #include "hw/net/msf2-emac.h"
36 #include "hw/net/mii.h"
38 #include "hw/qdev-properties.h"
39 #include "migration/vmstate.h"
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)
48 REG32(HALF_DUPLEX
, 0xc)
49 REG32(MAX_FRAME_LENGTH
, 0x10)
51 FIELD(MII_CMD
, READ
, 0, 1)
53 FIELD(MII_ADDR
, REGADDR
, 0, 5)
54 FIELD(MII_ADDR
, PHYADDR
, 8, 5)
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)
83 #define EMPTY_MASK (1 << 31)
84 #define PKT_SIZE 0x7FF
86 #define MAX_PKT_SIZE 2048
94 static uint32_t emac_get_isr(MSF2EmacState
*s
)
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
;
101 s
->regs
[R_DMA_IRQ
] = ier
& isr
;
102 return s
->regs
[R_DMA_IRQ
];
105 static void emac_update_irq(MSF2EmacState
*s
)
107 bool intr
= emac_get_isr(s
);
109 qemu_set_irq(s
->irq
, intr
);
112 static void emac_load_desc(MSF2EmacState
*s
, EmacDesc
*d
, hwaddr desc
)
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
);
121 static void emac_store_desc(MSF2EmacState
*s
, EmacDesc
*d
, hwaddr desc
)
123 /* Convert from host endianness into LE. */
124 d
->pktaddr
= cpu_to_le32(d
->pktaddr
);
125 d
->pktsize
= cpu_to_le32(d
->pktsize
);
126 d
->next
= cpu_to_le32(d
->next
);
128 address_space_write(&s
->dma_as
, desc
, MEMTXATTRS_UNSPECIFIED
, d
, sizeof *d
);
131 static void msf2_dma_tx(MSF2EmacState
*s
)
133 NetClientState
*nc
= qemu_get_queue(s
->nic
);
134 hwaddr desc
= s
->regs
[R_DMA_TX_DESC
];
135 uint8_t buf
[MAX_PKT_SIZE
];
141 if (!(s
->regs
[R_CFG1
] & R_CFG1_TX_EN_MASK
)) {
146 emac_load_desc(s
, &d
, desc
);
147 if (d
.pktsize
& EMPTY_MASK
) {
150 size
= d
.pktsize
& PKT_SIZE
;
151 address_space_read(&s
->dma_as
, d
.pktaddr
, MEMTXATTRS_UNSPECIFIED
,
154 * This is very basic way to send packets. Ideally there should be
155 * a FIFO and packets should be sent out from FIFO only when
156 * R_CFG1 bit 0 is set.
158 if (s
->regs
[R_CFG1
] & R_CFG1_LB_EN_MASK
) {
159 qemu_receive_packet(nc
, buf
, size
);
161 qemu_send_packet(nc
, buf
, size
);
163 d
.pktsize
|= EMPTY_MASK
;
164 emac_store_desc(s
, &d
, desc
);
165 /* update sent packets count */
166 status
= s
->regs
[R_DMA_TX_STATUS
];
167 pktcnt
= FIELD_EX32(status
, DMA_TX_STATUS
, PKTCNT
);
169 s
->regs
[R_DMA_TX_STATUS
] = FIELD_DP32(status
, DMA_TX_STATUS
,
171 s
->regs
[R_DMA_TX_STATUS
] |= R_DMA_TX_STATUS_PKT_SENT_MASK
;
174 s
->regs
[R_DMA_TX_STATUS
] |= R_DMA_TX_STATUS_UNDERRUN_MASK
;
175 s
->regs
[R_DMA_TX_CTL
] &= ~R_DMA_TX_CTL_EN_MASK
;
178 static void msf2_phy_update_link(MSF2EmacState
*s
)
180 /* Autonegotiation status mirrors link status. */
181 if (qemu_get_queue(s
->nic
)->link_down
) {
182 s
->phy_regs
[MII_BMSR
] &= ~(MII_BMSR_AN_COMP
|
185 s
->phy_regs
[MII_BMSR
] |= (MII_BMSR_AN_COMP
|
190 static void msf2_phy_reset(MSF2EmacState
*s
)
192 memset(&s
->phy_regs
[0], 0, sizeof(s
->phy_regs
));
193 s
->phy_regs
[MII_BMCR
] = 0x1140;
194 s
->phy_regs
[MII_BMSR
] = 0x7968;
195 s
->phy_regs
[MII_PHYID1
] = 0x0022;
196 s
->phy_regs
[MII_PHYID2
] = 0x1550;
197 s
->phy_regs
[MII_ANAR
] = 0x01E1;
198 s
->phy_regs
[MII_ANLPAR
] = 0xCDE1;
200 msf2_phy_update_link(s
);
203 static void write_to_phy(MSF2EmacState
*s
)
205 uint8_t reg_addr
= s
->regs
[R_MII_ADDR
] & R_MII_ADDR_REGADDR_MASK
;
206 uint8_t phy_addr
= (s
->regs
[R_MII_ADDR
] >> R_MII_ADDR_PHYADDR_SHIFT
) &
207 R_MII_ADDR_REGADDR_MASK
;
208 uint16_t data
= s
->regs
[R_MII_CTL
] & 0xFFFF;
210 if (phy_addr
!= PHYADDR
) {
216 if (data
& MII_BMCR_RESET
) {
219 data
&= ~MII_BMCR_RESET
;
221 if (data
& MII_BMCR_AUTOEN
) {
222 /* Complete autonegotiation immediately */
223 data
&= ~MII_BMCR_AUTOEN
;
224 s
->phy_regs
[MII_BMSR
] |= MII_BMSR_AN_COMP
;
229 s
->phy_regs
[reg_addr
] = data
;
232 static uint16_t read_from_phy(MSF2EmacState
*s
)
234 uint8_t reg_addr
= s
->regs
[R_MII_ADDR
] & R_MII_ADDR_REGADDR_MASK
;
235 uint8_t phy_addr
= (s
->regs
[R_MII_ADDR
] >> R_MII_ADDR_PHYADDR_SHIFT
) &
236 R_MII_ADDR_REGADDR_MASK
;
238 if (phy_addr
== PHYADDR
) {
239 return s
->phy_regs
[reg_addr
];
245 static void msf2_emac_do_reset(MSF2EmacState
*s
)
247 memset(&s
->regs
[0], 0, sizeof(s
->regs
));
248 s
->regs
[R_CFG1
] = 0x80000000;
249 s
->regs
[R_CFG2
] = 0x00007000;
250 s
->regs
[R_IFG
] = 0x40605060;
251 s
->regs
[R_HALF_DUPLEX
] = 0x00A1F037;
252 s
->regs
[R_MAX_FRAME_LENGTH
] = 0x00000600;
253 s
->regs
[R_FIFO_CFG5
] = 0X3FFFF;
258 static uint64_t emac_read(void *opaque
, hwaddr addr
, unsigned int size
)
260 MSF2EmacState
*s
= opaque
;
270 if (addr
>= ARRAY_SIZE(s
->regs
)) {
271 qemu_log_mask(LOG_GUEST_ERROR
,
272 "%s: Bad offset 0x%" HWADDR_PRIx
"\n", __func__
,
282 static void emac_write(void *opaque
, hwaddr addr
, uint64_t val64
,
285 MSF2EmacState
*s
= opaque
;
286 uint32_t value
= val64
;
293 s
->regs
[addr
] = value
;
294 if (value
& R_DMA_TX_CTL_EN_MASK
) {
299 s
->regs
[addr
] = value
;
300 if (value
& R_DMA_RX_CTL_EN_MASK
) {
301 s
->rx_desc
= s
->regs
[R_DMA_RX_DESC
];
302 qemu_flush_queued_packets(qemu_get_queue(s
->nic
));
306 s
->regs
[addr
] = value
;
307 if (value
& R_CFG1_RESET_MASK
) {
308 msf2_emac_do_reset(s
);
313 * For our implementation, turning on modules is instantaneous,
314 * so the states requested via the *ENREQ bits appear in the
315 * *ENRPLY bits immediately. Also the reset bits to reset PE-MCXMAC
316 * module are not emulated here since it deals with start of frames,
317 * inter-packet gap and control frames.
319 enreqbits
= extract32(value
, 8, 5);
320 s
->regs
[addr
] = deposit32(value
, 16, 5, enreqbits
);
324 qemu_log_mask(LOG_GUEST_ERROR
, "Tx Descriptor address should be"
325 " 32 bit aligned\n");
327 /* Ignore [1:0] bits */
328 s
->regs
[addr
] = value
& ~3;
332 qemu_log_mask(LOG_GUEST_ERROR
, "Rx Descriptor address should be"
333 " 32 bit aligned\n");
335 /* Ignore [1:0] bits */
336 s
->regs
[addr
] = value
& ~3;
338 case R_DMA_TX_STATUS
:
339 if (value
& R_DMA_TX_STATUS_UNDERRUN_MASK
) {
340 s
->regs
[addr
] &= ~R_DMA_TX_STATUS_UNDERRUN_MASK
;
342 if (value
& R_DMA_TX_STATUS_PKT_SENT_MASK
) {
343 pktcnt
= FIELD_EX32(s
->regs
[addr
], DMA_TX_STATUS
, PKTCNT
);
345 s
->regs
[addr
] = FIELD_DP32(s
->regs
[addr
], DMA_TX_STATUS
,
348 s
->regs
[addr
] &= ~R_DMA_TX_STATUS_PKT_SENT_MASK
;
352 case R_DMA_RX_STATUS
:
353 if (value
& R_DMA_RX_STATUS_OVERFLOW_MASK
) {
354 s
->regs
[addr
] &= ~R_DMA_RX_STATUS_OVERFLOW_MASK
;
356 if (value
& R_DMA_RX_STATUS_PKT_RCVD_MASK
) {
357 pktcnt
= FIELD_EX32(s
->regs
[addr
], DMA_RX_STATUS
, PKTCNT
);
359 s
->regs
[addr
] = FIELD_DP32(s
->regs
[addr
], DMA_RX_STATUS
,
362 s
->regs
[addr
] &= ~R_DMA_RX_STATUS_PKT_RCVD_MASK
;
369 if (value
& R_MII_CMD_READ_MASK
) {
370 s
->regs
[R_MII_STS
] = read_from_phy(s
);
374 s
->regs
[addr
] = value
;
378 s
->regs
[addr
] = value
;
380 * R_STA1 [31:24] : octet 1 of mac address
381 * R_STA1 [23:16] : octet 2 of mac address
382 * R_STA1 [15:8] : octet 3 of mac address
383 * R_STA1 [7:0] : octet 4 of mac address
385 stl_be_p(s
->mac_addr
, value
);
388 s
->regs
[addr
] = value
;
390 * R_STA2 [31:24] : octet 5 of mac address
391 * R_STA2 [23:16] : octet 6 of mac address
393 stw_be_p(s
->mac_addr
+ 4, value
>> 16);
396 if (addr
>= ARRAY_SIZE(s
->regs
)) {
397 qemu_log_mask(LOG_GUEST_ERROR
,
398 "%s: Bad offset 0x%" HWADDR_PRIx
"\n", __func__
,
402 s
->regs
[addr
] = value
;
408 static const MemoryRegionOps emac_ops
= {
411 .endianness
= DEVICE_NATIVE_ENDIAN
,
413 .min_access_size
= 4,
418 static bool emac_can_rx(NetClientState
*nc
)
420 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
422 return (s
->regs
[R_CFG1
] & R_CFG1_RX_EN_MASK
) &&
423 (s
->regs
[R_DMA_RX_CTL
] & R_DMA_RX_CTL_EN_MASK
);
426 static bool addr_filter_ok(MSF2EmacState
*s
, const uint8_t *buf
)
428 /* The broadcast MAC address: FF:FF:FF:FF:FF:FF */
429 const uint8_t broadcast_addr
[] = { 0xFF, 0xFF, 0xFF, 0xFF,
431 bool bcast_en
= true;
432 bool mcast_en
= true;
434 if (s
->regs
[R_FIFO_CFG5
] & R_FIFO_CFG5_BCAST_MASK
) {
435 bcast_en
= true; /* Broadcast dont care for drop circuitry */
436 } else if (s
->regs
[R_FIFO_CFG4
] & R_FIFO_CFG4_BCAST_MASK
) {
440 if (s
->regs
[R_FIFO_CFG5
] & R_FIFO_CFG5_MCAST_MASK
) {
441 mcast_en
= true; /* Multicast dont care for drop circuitry */
442 } else if (s
->regs
[R_FIFO_CFG4
] & R_FIFO_CFG4_MCAST_MASK
) {
446 if (!memcmp(buf
, broadcast_addr
, sizeof(broadcast_addr
))) {
454 return !memcmp(buf
, s
->mac_addr
, sizeof(s
->mac_addr
));
457 static ssize_t
emac_rx(NetClientState
*nc
, const uint8_t *buf
, size_t size
)
459 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
464 if (size
> (s
->regs
[R_MAX_FRAME_LENGTH
] & 0xFFFF)) {
467 if (!addr_filter_ok(s
, buf
)) {
471 emac_load_desc(s
, &d
, s
->rx_desc
);
473 if (d
.pktsize
& EMPTY_MASK
) {
474 address_space_write(&s
->dma_as
, d
.pktaddr
, MEMTXATTRS_UNSPECIFIED
,
475 buf
, size
& PKT_SIZE
);
476 d
.pktsize
= size
& PKT_SIZE
;
477 emac_store_desc(s
, &d
, s
->rx_desc
);
478 /* update received packets count */
479 status
= s
->regs
[R_DMA_RX_STATUS
];
480 pktcnt
= FIELD_EX32(status
, DMA_RX_STATUS
, PKTCNT
);
482 s
->regs
[R_DMA_RX_STATUS
] = FIELD_DP32(status
, DMA_RX_STATUS
,
484 s
->regs
[R_DMA_RX_STATUS
] |= R_DMA_RX_STATUS_PKT_RCVD_MASK
;
487 s
->regs
[R_DMA_RX_CTL
] &= ~R_DMA_RX_CTL_EN_MASK
;
488 s
->regs
[R_DMA_RX_STATUS
] |= R_DMA_RX_STATUS_OVERFLOW_MASK
;
494 static void msf2_emac_reset(DeviceState
*dev
)
496 MSF2EmacState
*s
= MSS_EMAC(dev
);
498 msf2_emac_do_reset(s
);
501 static void emac_set_link(NetClientState
*nc
)
503 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
505 msf2_phy_update_link(s
);
508 static NetClientInfo net_msf2_emac_info
= {
509 .type
= NET_CLIENT_DRIVER_NIC
,
510 .size
= sizeof(NICState
),
511 .can_receive
= emac_can_rx
,
513 .link_status_changed
= emac_set_link
,
516 static void msf2_emac_realize(DeviceState
*dev
, Error
**errp
)
518 MSF2EmacState
*s
= MSS_EMAC(dev
);
521 error_setg(errp
, "MSS_EMAC 'ahb-bus' link not set");
525 address_space_init(&s
->dma_as
, s
->dma_mr
, "emac-ahb");
527 qemu_macaddr_default_if_unset(&s
->conf
.macaddr
);
528 s
->nic
= qemu_new_nic(&net_msf2_emac_info
, &s
->conf
,
529 object_get_typename(OBJECT(dev
)), dev
->id
, s
);
530 qemu_format_nic_info_str(qemu_get_queue(s
->nic
), s
->conf
.macaddr
.a
);
533 static void msf2_emac_init(Object
*obj
)
535 MSF2EmacState
*s
= MSS_EMAC(obj
);
537 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->irq
);
539 memory_region_init_io(&s
->mmio
, obj
, &emac_ops
, s
,
540 "msf2-emac", R_MAX
* 4);
541 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
544 static Property msf2_emac_properties
[] = {
545 DEFINE_PROP_LINK("ahb-bus", MSF2EmacState
, dma_mr
,
546 TYPE_MEMORY_REGION
, MemoryRegion
*),
547 DEFINE_NIC_PROPERTIES(MSF2EmacState
, conf
),
548 DEFINE_PROP_END_OF_LIST(),
551 static const VMStateDescription vmstate_msf2_emac
= {
552 .name
= TYPE_MSS_EMAC
,
554 .minimum_version_id
= 1,
555 .fields
= (VMStateField
[]) {
556 VMSTATE_UINT8_ARRAY(mac_addr
, MSF2EmacState
, ETH_ALEN
),
557 VMSTATE_UINT32(rx_desc
, MSF2EmacState
),
558 VMSTATE_UINT16_ARRAY(phy_regs
, MSF2EmacState
, PHY_MAX_REGS
),
559 VMSTATE_UINT32_ARRAY(regs
, MSF2EmacState
, R_MAX
),
560 VMSTATE_END_OF_LIST()
564 static void msf2_emac_class_init(ObjectClass
*klass
, void *data
)
566 DeviceClass
*dc
= DEVICE_CLASS(klass
);
568 dc
->realize
= msf2_emac_realize
;
569 dc
->reset
= msf2_emac_reset
;
570 dc
->vmsd
= &vmstate_msf2_emac
;
571 device_class_set_props(dc
, msf2_emac_properties
);
574 static const TypeInfo msf2_emac_info
= {
575 .name
= TYPE_MSS_EMAC
,
576 .parent
= TYPE_SYS_BUS_DEVICE
,
577 .instance_size
= sizeof(MSF2EmacState
),
578 .instance_init
= msf2_emac_init
,
579 .class_init
= msf2_emac_class_init
,
582 static void msf2_emac_register_types(void)
584 type_register_static(&msf2_emac_info
);
587 type_init(msf2_emac_register_types
)