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"
32 #include "qemu-common.h"
34 #include "qapi/error.h"
35 #include "hw/registerfields.h"
36 #include "hw/net/msf2-emac.h"
37 #include "hw/net/mii.h"
39 #include "hw/qdev-properties.h"
40 #include "migration/vmstate.h"
43 FIELD(CFG1
, RESET
, 31, 1)
44 FIELD(CFG1
, RX_EN
, 2, 1)
45 FIELD(CFG1
, TX_EN
, 0, 1)
46 FIELD(CFG1
, LB_EN
, 8, 1)
49 REG32(HALF_DUPLEX
, 0xc)
50 REG32(MAX_FRAME_LENGTH
, 0x10)
52 FIELD(MII_CMD
, READ
, 0, 1)
54 FIELD(MII_ADDR
, REGADDR
, 0, 5)
55 FIELD(MII_ADDR
, PHYADDR
, 8, 5)
60 REG32(FIFO_CFG0
, 0x48)
61 REG32(FIFO_CFG4
, 0x58)
62 FIELD(FIFO_CFG4
, BCAST
, 9, 1)
63 FIELD(FIFO_CFG4
, MCAST
, 8, 1)
64 REG32(FIFO_CFG5
, 0x5C)
65 FIELD(FIFO_CFG5
, BCAST
, 9, 1)
66 FIELD(FIFO_CFG5
, MCAST
, 8, 1)
67 REG32(DMA_TX_CTL
, 0x180)
68 FIELD(DMA_TX_CTL
, EN
, 0, 1)
69 REG32(DMA_TX_DESC
, 0x184)
70 REG32(DMA_TX_STATUS
, 0x188)
71 FIELD(DMA_TX_STATUS
, PKTCNT
, 16, 8)
72 FIELD(DMA_TX_STATUS
, UNDERRUN
, 1, 1)
73 FIELD(DMA_TX_STATUS
, PKT_SENT
, 0, 1)
74 REG32(DMA_RX_CTL
, 0x18c)
75 FIELD(DMA_RX_CTL
, EN
, 0, 1)
76 REG32(DMA_RX_DESC
, 0x190)
77 REG32(DMA_RX_STATUS
, 0x194)
78 FIELD(DMA_RX_STATUS
, PKTCNT
, 16, 8)
79 FIELD(DMA_RX_STATUS
, OVERFLOW
, 2, 1)
80 FIELD(DMA_RX_STATUS
, PKT_RCVD
, 0, 1)
81 REG32(DMA_IRQ_MASK
, 0x198)
84 #define EMPTY_MASK (1 << 31)
85 #define PKT_SIZE 0x7FF
87 #define MAX_PKT_SIZE 2048
95 static uint32_t emac_get_isr(MSF2EmacState
*s
)
97 uint32_t ier
= s
->regs
[R_DMA_IRQ_MASK
];
98 uint32_t tx
= s
->regs
[R_DMA_TX_STATUS
] & 0xF;
99 uint32_t rx
= s
->regs
[R_DMA_RX_STATUS
] & 0xF;
100 uint32_t isr
= (rx
<< 4) | tx
;
102 s
->regs
[R_DMA_IRQ
] = ier
& isr
;
103 return s
->regs
[R_DMA_IRQ
];
106 static void emac_update_irq(MSF2EmacState
*s
)
108 bool intr
= emac_get_isr(s
);
110 qemu_set_irq(s
->irq
, intr
);
113 static void emac_load_desc(MSF2EmacState
*s
, EmacDesc
*d
, hwaddr desc
)
115 address_space_read(&s
->dma_as
, desc
, MEMTXATTRS_UNSPECIFIED
, d
, sizeof *d
);
116 /* Convert from LE into host endianness. */
117 d
->pktaddr
= le32_to_cpu(d
->pktaddr
);
118 d
->pktsize
= le32_to_cpu(d
->pktsize
);
119 d
->next
= le32_to_cpu(d
->next
);
122 static void emac_store_desc(MSF2EmacState
*s
, EmacDesc
*d
, hwaddr desc
)
124 /* Convert from host endianness into LE. */
125 d
->pktaddr
= cpu_to_le32(d
->pktaddr
);
126 d
->pktsize
= cpu_to_le32(d
->pktsize
);
127 d
->next
= cpu_to_le32(d
->next
);
129 address_space_write(&s
->dma_as
, desc
, MEMTXATTRS_UNSPECIFIED
, d
, sizeof *d
);
132 static void msf2_dma_tx(MSF2EmacState
*s
)
134 NetClientState
*nc
= qemu_get_queue(s
->nic
);
135 hwaddr desc
= s
->regs
[R_DMA_TX_DESC
];
136 uint8_t buf
[MAX_PKT_SIZE
];
142 if (!(s
->regs
[R_CFG1
] & R_CFG1_TX_EN_MASK
)) {
147 emac_load_desc(s
, &d
, desc
);
148 if (d
.pktsize
& EMPTY_MASK
) {
151 size
= d
.pktsize
& PKT_SIZE
;
152 address_space_read(&s
->dma_as
, d
.pktaddr
, MEMTXATTRS_UNSPECIFIED
,
155 * This is very basic way to send packets. Ideally there should be
156 * a FIFO and packets should be sent out from FIFO only when
157 * R_CFG1 bit 0 is set.
159 if (s
->regs
[R_CFG1
] & R_CFG1_LB_EN_MASK
) {
160 qemu_receive_packet(nc
, buf
, size
);
162 qemu_send_packet(nc
, buf
, size
);
164 d
.pktsize
|= EMPTY_MASK
;
165 emac_store_desc(s
, &d
, desc
);
166 /* update sent packets count */
167 status
= s
->regs
[R_DMA_TX_STATUS
];
168 pktcnt
= FIELD_EX32(status
, DMA_TX_STATUS
, PKTCNT
);
170 s
->regs
[R_DMA_TX_STATUS
] = FIELD_DP32(status
, DMA_TX_STATUS
,
172 s
->regs
[R_DMA_TX_STATUS
] |= R_DMA_TX_STATUS_PKT_SENT_MASK
;
175 s
->regs
[R_DMA_TX_STATUS
] |= R_DMA_TX_STATUS_UNDERRUN_MASK
;
176 s
->regs
[R_DMA_TX_CTL
] &= ~R_DMA_TX_CTL_EN_MASK
;
179 static void msf2_phy_update_link(MSF2EmacState
*s
)
181 /* Autonegotiation status mirrors link status. */
182 if (qemu_get_queue(s
->nic
)->link_down
) {
183 s
->phy_regs
[MII_BMSR
] &= ~(MII_BMSR_AN_COMP
|
186 s
->phy_regs
[MII_BMSR
] |= (MII_BMSR_AN_COMP
|
191 static void msf2_phy_reset(MSF2EmacState
*s
)
193 memset(&s
->phy_regs
[0], 0, sizeof(s
->phy_regs
));
194 s
->phy_regs
[MII_BMCR
] = 0x1140;
195 s
->phy_regs
[MII_BMSR
] = 0x7968;
196 s
->phy_regs
[MII_PHYID1
] = 0x0022;
197 s
->phy_regs
[MII_PHYID2
] = 0x1550;
198 s
->phy_regs
[MII_ANAR
] = 0x01E1;
199 s
->phy_regs
[MII_ANLPAR
] = 0xCDE1;
201 msf2_phy_update_link(s
);
204 static void write_to_phy(MSF2EmacState
*s
)
206 uint8_t reg_addr
= s
->regs
[R_MII_ADDR
] & R_MII_ADDR_REGADDR_MASK
;
207 uint8_t phy_addr
= (s
->regs
[R_MII_ADDR
] >> R_MII_ADDR_PHYADDR_SHIFT
) &
208 R_MII_ADDR_REGADDR_MASK
;
209 uint16_t data
= s
->regs
[R_MII_CTL
] & 0xFFFF;
211 if (phy_addr
!= PHYADDR
) {
217 if (data
& MII_BMCR_RESET
) {
220 data
&= ~MII_BMCR_RESET
;
222 if (data
& MII_BMCR_AUTOEN
) {
223 /* Complete autonegotiation immediately */
224 data
&= ~MII_BMCR_AUTOEN
;
225 s
->phy_regs
[MII_BMSR
] |= MII_BMSR_AN_COMP
;
230 s
->phy_regs
[reg_addr
] = data
;
233 static uint16_t read_from_phy(MSF2EmacState
*s
)
235 uint8_t reg_addr
= s
->regs
[R_MII_ADDR
] & R_MII_ADDR_REGADDR_MASK
;
236 uint8_t phy_addr
= (s
->regs
[R_MII_ADDR
] >> R_MII_ADDR_PHYADDR_SHIFT
) &
237 R_MII_ADDR_REGADDR_MASK
;
239 if (phy_addr
== PHYADDR
) {
240 return s
->phy_regs
[reg_addr
];
246 static void msf2_emac_do_reset(MSF2EmacState
*s
)
248 memset(&s
->regs
[0], 0, sizeof(s
->regs
));
249 s
->regs
[R_CFG1
] = 0x80000000;
250 s
->regs
[R_CFG2
] = 0x00007000;
251 s
->regs
[R_IFG
] = 0x40605060;
252 s
->regs
[R_HALF_DUPLEX
] = 0x00A1F037;
253 s
->regs
[R_MAX_FRAME_LENGTH
] = 0x00000600;
254 s
->regs
[R_FIFO_CFG5
] = 0X3FFFF;
259 static uint64_t emac_read(void *opaque
, hwaddr addr
, unsigned int size
)
261 MSF2EmacState
*s
= opaque
;
271 if (addr
>= ARRAY_SIZE(s
->regs
)) {
272 qemu_log_mask(LOG_GUEST_ERROR
,
273 "%s: Bad offset 0x%" HWADDR_PRIx
"\n", __func__
,
283 static void emac_write(void *opaque
, hwaddr addr
, uint64_t val64
,
286 MSF2EmacState
*s
= opaque
;
287 uint32_t value
= val64
;
294 s
->regs
[addr
] = value
;
295 if (value
& R_DMA_TX_CTL_EN_MASK
) {
300 s
->regs
[addr
] = value
;
301 if (value
& R_DMA_RX_CTL_EN_MASK
) {
302 s
->rx_desc
= s
->regs
[R_DMA_RX_DESC
];
303 qemu_flush_queued_packets(qemu_get_queue(s
->nic
));
307 s
->regs
[addr
] = value
;
308 if (value
& R_CFG1_RESET_MASK
) {
309 msf2_emac_do_reset(s
);
314 * For our implementation, turning on modules is instantaneous,
315 * so the states requested via the *ENREQ bits appear in the
316 * *ENRPLY bits immediately. Also the reset bits to reset PE-MCXMAC
317 * module are not emulated here since it deals with start of frames,
318 * inter-packet gap and control frames.
320 enreqbits
= extract32(value
, 8, 5);
321 s
->regs
[addr
] = deposit32(value
, 16, 5, enreqbits
);
325 qemu_log_mask(LOG_GUEST_ERROR
, "Tx Descriptor address should be"
326 " 32 bit aligned\n");
328 /* Ignore [1:0] bits */
329 s
->regs
[addr
] = value
& ~3;
333 qemu_log_mask(LOG_GUEST_ERROR
, "Rx Descriptor address should be"
334 " 32 bit aligned\n");
336 /* Ignore [1:0] bits */
337 s
->regs
[addr
] = value
& ~3;
339 case R_DMA_TX_STATUS
:
340 if (value
& R_DMA_TX_STATUS_UNDERRUN_MASK
) {
341 s
->regs
[addr
] &= ~R_DMA_TX_STATUS_UNDERRUN_MASK
;
343 if (value
& R_DMA_TX_STATUS_PKT_SENT_MASK
) {
344 pktcnt
= FIELD_EX32(s
->regs
[addr
], DMA_TX_STATUS
, PKTCNT
);
346 s
->regs
[addr
] = FIELD_DP32(s
->regs
[addr
], DMA_TX_STATUS
,
349 s
->regs
[addr
] &= ~R_DMA_TX_STATUS_PKT_SENT_MASK
;
353 case R_DMA_RX_STATUS
:
354 if (value
& R_DMA_RX_STATUS_OVERFLOW_MASK
) {
355 s
->regs
[addr
] &= ~R_DMA_RX_STATUS_OVERFLOW_MASK
;
357 if (value
& R_DMA_RX_STATUS_PKT_RCVD_MASK
) {
358 pktcnt
= FIELD_EX32(s
->regs
[addr
], DMA_RX_STATUS
, PKTCNT
);
360 s
->regs
[addr
] = FIELD_DP32(s
->regs
[addr
], DMA_RX_STATUS
,
363 s
->regs
[addr
] &= ~R_DMA_RX_STATUS_PKT_RCVD_MASK
;
370 if (value
& R_MII_CMD_READ_MASK
) {
371 s
->regs
[R_MII_STS
] = read_from_phy(s
);
375 s
->regs
[addr
] = value
;
379 s
->regs
[addr
] = value
;
381 * R_STA1 [31:24] : octet 1 of mac address
382 * R_STA1 [23:16] : octet 2 of mac address
383 * R_STA1 [15:8] : octet 3 of mac address
384 * R_STA1 [7:0] : octet 4 of mac address
386 stl_be_p(s
->mac_addr
, value
);
389 s
->regs
[addr
] = value
;
391 * R_STA2 [31:24] : octet 5 of mac address
392 * R_STA2 [23:16] : octet 6 of mac address
394 stw_be_p(s
->mac_addr
+ 4, value
>> 16);
397 if (addr
>= ARRAY_SIZE(s
->regs
)) {
398 qemu_log_mask(LOG_GUEST_ERROR
,
399 "%s: Bad offset 0x%" HWADDR_PRIx
"\n", __func__
,
403 s
->regs
[addr
] = value
;
409 static const MemoryRegionOps emac_ops
= {
412 .endianness
= DEVICE_NATIVE_ENDIAN
,
414 .min_access_size
= 4,
419 static bool emac_can_rx(NetClientState
*nc
)
421 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
423 return (s
->regs
[R_CFG1
] & R_CFG1_RX_EN_MASK
) &&
424 (s
->regs
[R_DMA_RX_CTL
] & R_DMA_RX_CTL_EN_MASK
);
427 static bool addr_filter_ok(MSF2EmacState
*s
, const uint8_t *buf
)
429 /* The broadcast MAC address: FF:FF:FF:FF:FF:FF */
430 const uint8_t broadcast_addr
[] = { 0xFF, 0xFF, 0xFF, 0xFF,
432 bool bcast_en
= true;
433 bool mcast_en
= true;
435 if (s
->regs
[R_FIFO_CFG5
] & R_FIFO_CFG5_BCAST_MASK
) {
436 bcast_en
= true; /* Broadcast dont care for drop circuitry */
437 } else if (s
->regs
[R_FIFO_CFG4
] & R_FIFO_CFG4_BCAST_MASK
) {
441 if (s
->regs
[R_FIFO_CFG5
] & R_FIFO_CFG5_MCAST_MASK
) {
442 mcast_en
= true; /* Multicast dont care for drop circuitry */
443 } else if (s
->regs
[R_FIFO_CFG4
] & R_FIFO_CFG4_MCAST_MASK
) {
447 if (!memcmp(buf
, broadcast_addr
, sizeof(broadcast_addr
))) {
455 return !memcmp(buf
, s
->mac_addr
, sizeof(s
->mac_addr
));
458 static ssize_t
emac_rx(NetClientState
*nc
, const uint8_t *buf
, size_t size
)
460 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
465 if (size
> (s
->regs
[R_MAX_FRAME_LENGTH
] & 0xFFFF)) {
468 if (!addr_filter_ok(s
, buf
)) {
472 emac_load_desc(s
, &d
, s
->rx_desc
);
474 if (d
.pktsize
& EMPTY_MASK
) {
475 address_space_write(&s
->dma_as
, d
.pktaddr
, MEMTXATTRS_UNSPECIFIED
,
476 buf
, size
& PKT_SIZE
);
477 d
.pktsize
= size
& PKT_SIZE
;
478 emac_store_desc(s
, &d
, s
->rx_desc
);
479 /* update received packets count */
480 status
= s
->regs
[R_DMA_RX_STATUS
];
481 pktcnt
= FIELD_EX32(status
, DMA_RX_STATUS
, PKTCNT
);
483 s
->regs
[R_DMA_RX_STATUS
] = FIELD_DP32(status
, DMA_RX_STATUS
,
485 s
->regs
[R_DMA_RX_STATUS
] |= R_DMA_RX_STATUS_PKT_RCVD_MASK
;
488 s
->regs
[R_DMA_RX_CTL
] &= ~R_DMA_RX_CTL_EN_MASK
;
489 s
->regs
[R_DMA_RX_STATUS
] |= R_DMA_RX_STATUS_OVERFLOW_MASK
;
495 static void msf2_emac_reset(DeviceState
*dev
)
497 MSF2EmacState
*s
= MSS_EMAC(dev
);
499 msf2_emac_do_reset(s
);
502 static void emac_set_link(NetClientState
*nc
)
504 MSF2EmacState
*s
= qemu_get_nic_opaque(nc
);
506 msf2_phy_update_link(s
);
509 static NetClientInfo net_msf2_emac_info
= {
510 .type
= NET_CLIENT_DRIVER_NIC
,
511 .size
= sizeof(NICState
),
512 .can_receive
= emac_can_rx
,
514 .link_status_changed
= emac_set_link
,
517 static void msf2_emac_realize(DeviceState
*dev
, Error
**errp
)
519 MSF2EmacState
*s
= MSS_EMAC(dev
);
522 error_setg(errp
, "MSS_EMAC 'ahb-bus' link not set");
526 address_space_init(&s
->dma_as
, s
->dma_mr
, "emac-ahb");
528 qemu_macaddr_default_if_unset(&s
->conf
.macaddr
);
529 s
->nic
= qemu_new_nic(&net_msf2_emac_info
, &s
->conf
,
530 object_get_typename(OBJECT(dev
)), dev
->id
, s
);
531 qemu_format_nic_info_str(qemu_get_queue(s
->nic
), s
->conf
.macaddr
.a
);
534 static void msf2_emac_init(Object
*obj
)
536 MSF2EmacState
*s
= MSS_EMAC(obj
);
538 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->irq
);
540 memory_region_init_io(&s
->mmio
, obj
, &emac_ops
, s
,
541 "msf2-emac", R_MAX
* 4);
542 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
545 static Property msf2_emac_properties
[] = {
546 DEFINE_PROP_LINK("ahb-bus", MSF2EmacState
, dma_mr
,
547 TYPE_MEMORY_REGION
, MemoryRegion
*),
548 DEFINE_NIC_PROPERTIES(MSF2EmacState
, conf
),
549 DEFINE_PROP_END_OF_LIST(),
552 static const VMStateDescription vmstate_msf2_emac
= {
553 .name
= TYPE_MSS_EMAC
,
555 .minimum_version_id
= 1,
556 .fields
= (VMStateField
[]) {
557 VMSTATE_UINT8_ARRAY(mac_addr
, MSF2EmacState
, ETH_ALEN
),
558 VMSTATE_UINT32(rx_desc
, MSF2EmacState
),
559 VMSTATE_UINT16_ARRAY(phy_regs
, MSF2EmacState
, PHY_MAX_REGS
),
560 VMSTATE_UINT32_ARRAY(regs
, MSF2EmacState
, R_MAX
),
561 VMSTATE_END_OF_LIST()
565 static void msf2_emac_class_init(ObjectClass
*klass
, void *data
)
567 DeviceClass
*dc
= DEVICE_CLASS(klass
);
569 dc
->realize
= msf2_emac_realize
;
570 dc
->reset
= msf2_emac_reset
;
571 dc
->vmsd
= &vmstate_msf2_emac
;
572 device_class_set_props(dc
, msf2_emac_properties
);
575 static const TypeInfo msf2_emac_info
= {
576 .name
= TYPE_MSS_EMAC
,
577 .parent
= TYPE_SYS_BUS_DEVICE
,
578 .instance_size
= sizeof(MSF2EmacState
),
579 .instance_init
= msf2_emac_init
,
580 .class_init
= msf2_emac_class_init
,
583 static void msf2_emac_register_types(void)
585 type_register_static(&msf2_emac_info
);
588 type_init(msf2_emac_register_types
)