git: da8a529bc01f - main - mgb: support for PCI11414.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 13 Oct 2026 17:42:43 UTC
The branch main has been updated by br:
URL: https://cgit.FreeBSD.org/src/commit/?id=da8a529bc01f5fdfdd5308ff6fd9a2bc52359069
commit da8a529bc01f5fdfdd5308ff6fd9a2bc52359069
Author: Ruslan Bukin <br@FreeBSD.org>
AuthorDate: 2026-10-13 17:39:24 +0000
Commit: Ruslan Bukin <br@FreeBSD.org>
CommitDate: 2026-10-13 17:41:14 +0000
mgb: support for PCI11414.
Add support for Microchip PCI11414 Gigabit Ethernet Controller.
The PCI11414 is used on the CHERI VITA 57.1 PCIe Extension Board.
- Add PCI11414 device ID
- Add support for SGMII mode. Read the programmed strap configuration
and enable SGMII operation when configured. Bypass the MII interface
in SGMII mode.
- Increase the DMA descriptor ring size.
Reviewed by: emaste
Sponsored by: EPSRC ("UKRI3001: CHERI Research Centre")
Differential Revision: https://reviews.freebsd.org/D60539
---
sys/dev/mgb/if_mgb.c | 110 ++++++++++++++++++++++++++++++++++++++-------------
sys/dev/mgb/if_mgb.h | 33 +++++++++++++++-
2 files changed, 115 insertions(+), 28 deletions(-)
diff --git a/sys/dev/mgb/if_mgb.c b/sys/dev/mgb/if_mgb.c
index 887d95dc457c..7fb98a85fc1a 100644
--- a/sys/dev/mgb/if_mgb.c
+++ b/sys/dev/mgb/if_mgb.c
@@ -91,6 +91,8 @@ static const pci_vendor_info_t mgb_vendor_info_array[] = {
"Microchip LAN7430 PCIe Gigabit Ethernet Controller"),
PVID(MGB_MICROCHIP_VENDOR_ID, MGB_LAN7431_DEVICE_ID,
"Microchip LAN7431 PCIe Gigabit Ethernet Controller"),
+ PVID(MGB_MICROCHIP_VENDOR_ID, MGB_PCI11414_DEVICE_ID,
+ "Microchip PCI11414 PCIe Gigabit Ethernet Controller"),
PVID_END
};
@@ -328,14 +330,48 @@ mgb_register(device_t dev)
return (&mgb_sctx_init);
}
+static int
+mgb_mii_attach(struct mgb_softc *sc)
+{
+ struct mii_data *miid;
+ if_softc_ctx_t scctx;
+ int phyaddr;
+ int error;
+
+ scctx = iflib_get_softc_ctx(sc->ctx);
+
+ switch (pci_get_device(sc->dev)) {
+ case MGB_LAN7430_DEVICE_ID:
+ phyaddr = 1;
+ break;
+ case MGB_LAN7431_DEVICE_ID:
+ default:
+ phyaddr = MII_PHY_ANY;
+ break;
+ }
+
+ /* XXX: Would be nice(r) if locked methods were here */
+ error = mii_attach(sc->dev, &sc->miibus, iflib_get_ifp(sc->ctx),
+ mgb_media_change, mgb_media_status,
+ BMSR_DEFCAPMASK, phyaddr, MII_OFFSET_ANY, MIIF_DOPAUSE);
+ if (error != 0) {
+ device_printf(sc->dev, "Failed to attach MII interface\n");
+ return (error);
+ }
+
+ miid = device_get_softc(sc->miibus);
+ scctx->isc_media = &miid->mii_media;
+
+ return (0);
+}
+
static int
mgb_attach_pre(if_ctx_t ctx)
{
struct mgb_softc *sc;
if_softc_ctx_t scctx;
- int error, phyaddr, rid;
+ int error, rid;
struct ether_addr hwaddr;
- struct mii_data *miid;
sc = iflib_get_softc(ctx);
sc->ctx = ctx;
@@ -395,28 +431,12 @@ mgb_attach_pre(if_ctx_t ctx)
goto fail;
}
- switch (pci_get_device(sc->dev)) {
- case MGB_LAN7430_DEVICE_ID:
- phyaddr = 1;
- break;
- case MGB_LAN7431_DEVICE_ID:
- default:
- phyaddr = MII_PHY_ANY;
- break;
- }
-
- /* XXX: Would be nice(r) if locked methods were here */
- error = mii_attach(sc->dev, &sc->miibus, iflib_get_ifp(ctx),
- mgb_media_change, mgb_media_status,
- BMSR_DEFCAPMASK, phyaddr, MII_OFFSET_ANY, MIIF_DOPAUSE);
- if (error != 0) {
- device_printf(sc->dev, "Failed to attach MII interface\n");
- goto fail;
+ if (!sc->sgmii_en) {
+ error = mgb_mii_attach(sc);
+ if (error)
+ goto fail;
}
- miid = device_get_softc(sc->miibus);
- scctx->isc_media = &miid->mii_media;
-
scctx->isc_msix_bar = pci_msix_table_bar(sc->dev);
/** Setup PBA BAR **/
rid = pci_msix_pba_bar(sc->dev);
@@ -447,6 +467,11 @@ mgb_attach_pre(if_ctx_t ctx)
CSR_WRITE_REG(sc, MGB_INTR_VEC_TX_MAP, 0);
CSR_WRITE_REG(sc, MGB_INTR_VEC_OTHER_MAP, 0);
+ if (sc->sgmii_en) {
+ /* Unsure which speed to set, use 1Gbps as default. */
+ iflib_link_state_change(ctx, LINK_STATE_UP, IF_Mbps(1000));
+ }
+
return (0);
fail:
@@ -598,8 +623,6 @@ mgb_init(if_ctx_t ctx)
int error;
sc = iflib_get_softc(ctx);
- miid = device_get_softc(sc->miibus);
- device_printf(sc->dev, "running init ...\n");
error = mgb_dma_init(sc);
if (error != 0) {
@@ -615,6 +638,10 @@ mgb_init(if_ctx_t ctx)
MGB_RFE_ALLOW_MULTICAST |
MGB_RFE_ALLOW_UNICAST);
+ if (sc->sgmii_en)
+ return;
+
+ miid = device_get_softc(sc->miibus);
error = mii_mediachg(miid);
/* Not much we can do if this fails. */
if (error)
@@ -1190,10 +1217,11 @@ mgb_test_bar(struct mgb_softc *sc)
id_rev = CSR_READ_REG(sc, 0);
dev_id = id_rev >> 16;
if (dev_id == MGB_LAN7430_DEVICE_ID ||
- dev_id == MGB_LAN7431_DEVICE_ID) {
+ dev_id == MGB_LAN7431_DEVICE_ID ||
+ dev_id == MGB_PCI11414_DEVICE_ID) {
return (0);
} else {
- device_printf(sc->dev, "ID check failed.\n");
+ device_printf(sc->dev, "ID check failed: 0x%x\n", dev_id);
return (ENXIO);
}
}
@@ -1457,7 +1485,11 @@ mgb_hw_teardown(struct mgb_softc *sc)
static int
mgb_hw_init(struct mgb_softc *sc)
{
- int error = 0;
+ uint32_t sgmii_ctl;
+ uint32_t reg;
+ int error;
+
+ error = 0;
error = mgb_hw_reset(sc);
if (error != 0)
@@ -1469,6 +1501,30 @@ mgb_hw_init(struct mgb_softc *sc)
if (error != 0)
goto fail;
+ /* Enable SGMII if needed. */
+ reg = CSR_READ_REG(sc, STRAP_READ);
+ if (bootverbose)
+ device_printf(sc->dev, " Strap: %#b\n", reg,
+ "\020"
+ "\01ADV_PM_DISABLE"
+ "\02RGMII_RXC_DELAY_EN"
+ "\03RGMII_TXC_DELAY_EN"
+ "\04BASE_X"
+ "\05SGMII_2_5G"
+ "\06SGMII_REFCLK"
+ "\07SGMII_EN"
+ "\10RMII_EN"
+ "\27USE_SGMII_EN"
+ "\30USE_RMII_EN");
+ if ((reg & STRAP_READ_USE_SGMII_EN) != 0 &&
+ (reg & STRAP_READ_SGMII_EN) != 0) {
+ sgmii_ctl = CSR_READ_REG(sc, SGMII_CTL);
+ sgmii_ctl |= SGMII_CTL_SGMII_ENABLE;
+ sgmii_ctl &= ~SGMII_CTL_SGMII_POWER_DN;
+ CSR_WRITE_REG(sc, SGMII_CTL, sgmii_ctl);
+ sc->sgmii_en = true;
+ }
+
error = mgb_dmac_reset(sc);
if (error != 0)
goto fail;
diff --git a/sys/dev/mgb/if_mgb.h b/sys/dev/mgb/if_mgb.h
index ebae9bb29e55..c5289fd6e80a 100644
--- a/sys/dev/mgb/if_mgb.h
+++ b/sys/dev/mgb/if_mgb.h
@@ -33,6 +33,7 @@
#define MGB_MICROCHIP_VENDOR_ID 0x1055
#define MGB_LAN7430_DEVICE_ID 0x7430
#define MGB_LAN7431_DEVICE_ID 0x7431
+#define MGB_PCI11414_DEVICE_ID 0xA041
#define MGB_TIMEOUT (500)
@@ -85,6 +86,19 @@
#define MGB_PHY_RESET 0x10
#define MGB_PHY_READY 0x80
+/* Strap configuration */
+#define STRAP_READ 0x0C
+#define STRAP_READ_USE_RMII_EN (1 << 23)
+#define STRAP_READ_USE_SGMII_EN (1 << 22)
+#define STRAP_READ_RMII_EN (1 << 7)
+#define STRAP_READ_SGMII_EN (1 << 6)
+#define STRAP_READ_SGMII_REFCLK (1 << 5)
+#define STRAP_READ_SGMII_2_5G (1 << 4)
+#define STRAP_READ_BASE_X (1 << 3)
+#define STRAP_READ_RGMII_TXC_DELAY_EN (1 << 2)
+#define STRAP_READ_RGMII_RXC_DELAY_EN (1 << 1)
+#define STRAP_READ_ADV_PM_DISABLE (1 << 0)
+
/** FIFO Controller **/
#define MGB_FCT_TX_CTL 0xC4
#define MGB_FCT_RX_CTL 0xAC
@@ -129,7 +143,7 @@
*
**/
/* In linux driver these numbers are 50 and 65 for tx and rx .... */
-#define MGB_DMA_RING_SIZE 16 /* in programming guide, this number is 100 */
+#define MGB_DMA_RING_SIZE 1024 /* in programming guide, this number is 100 */
#define MGB_DMA_MAXSEGS 32
#define MGB_DMA_REG(reg, _channel) ((reg) | ((_channel) << 6))
#define MGB_DMA_RING_LIST_SIZE \
@@ -194,6 +208,22 @@
#define MGB_MII_WRITE 0x2
#define MGB_MII_BUSY 0x1
+#define SGMII_ACC 0x720
+#define SGMII_ACC_SGMII_BZY (1 << 31)
+#define SGMII_ACC_SGMII_WR (1 << 30)
+#define SGMII_ACC_SGMII_MMD_SHIFT 16
+#define SGMII_ACC_SGMII_MMD_MASK 0xf0000
+#define SGMII_ACC_SGMII_MMD_VSR (1 << 15)
+#define SGMII_ACC_SGMII_ADDR_SHIFT 0
+#define SGMII_ACC_SGMII_ADDR_MASK 0xffff
+#define SGMII_DATA 0x724
+#define SGMII_DATA_SHIFT 0
+#define SGMII_DATA_MASK 0xffff
+#define SGMII_CTL 0x728
+#define SGMII_CTL_SGMII_ENABLE (1 << 31)
+#define SGMII_CTL_LINK_STATUS_SOURCE (1 << 8)
+#define SGMII_CTL_SGMII_POWER_DN (1 << 1)
+
/** Interrupt registers **/
#define MGB_INTR_STS 0x780
#define MGB_INTR_SET 0x784 /* This triggers a particular interrupt */
@@ -325,6 +355,7 @@ struct mgb_softc {
struct mgb_ring_data rx_ring_data;
struct mgb_ring_data tx_ring_data;
+ bool sgmii_en;
};
#endif /* _IF_MGB_H_ */