[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<176218926788.2759873.2345667871349722199.stgit@ahduyck-xeon-server.home.arpa>
Date: Mon, 03 Nov 2025 09:01:07 -0800
From: Alexander Duyck <alexander.duyck@...il.com>
To: netdev@...r.kernel.org
Cc: kuba@...nel.org, kernel-team@...a.com, andrew+netdev@...n.ch,
hkallweit1@...il.com, linux@...linux.org.uk, pabeni@...hat.com,
davem@...emloft.net
Subject: [net-next PATCH v2 10/11] fbnic: Add phydev representing PMD to
phylink setup
From: Alexander Duyck <alexanderduyck@...com>
With this patch we add support for a phydev which represents the PMD state
to the phylink interface. As we now have this path we can separate the link
state from the PCS and instead report it through the phydev which allows us
to more easily transition to using the XPCS when the time comes.
Signed-off-by: Alexander Duyck <alexanderduyck@...com>
---
drivers/net/ethernet/meta/Kconfig | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 2 +
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 16 +++++++++
drivers/net/ethernet/meta/fbnic/fbnic_netdev.h | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_phylink.c | 40 +++++++++++++++++++++--
6 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/meta/Kconfig b/drivers/net/ethernet/meta/Kconfig
index dff51f23d295..23676b530a83 100644
--- a/drivers/net/ethernet/meta/Kconfig
+++ b/drivers/net/ethernet/meta/Kconfig
@@ -24,6 +24,7 @@ config FBNIC
depends on MAX_SKB_FRAGS < 22
depends on PCI_MSI
depends on PTP_1588_CLOCK_OPTIONAL
+ select FBNIC_PHY
select NET_DEVLINK
select PAGE_POOL
select PHYLINK
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
index 45af6c1331fb..432b053b5ed6 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
@@ -140,7 +140,7 @@ static irqreturn_t fbnic_mac_msix_intr(int __always_unused irq, void *data)
/* Record link down events */
if (!fbd->mac->get_link(fbd, fbn->aui, fbn->fec)) {
fbn->link_down_events = link_down_events;
- phylink_mac_change(fbn->phylink, false);
+ phy_mac_interrupt(fbd->netdev->phydev);
}
return IRQ_HANDLED;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index 65318a5b466e..51cf88b62927 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -101,6 +101,20 @@ static int fbnic_stop(struct net_device *netdev)
return 0;
}
+static int fbnic_init(struct net_device *netdev)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
+ return fbnic_phylink_connect(fbn);
+}
+
+static void fbnic_uninit(struct net_device *netdev)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
+ phylink_disconnect_phy(fbn->phylink);
+}
+
static int fbnic_uc_sync(struct net_device *netdev, const unsigned char *addr)
{
struct fbnic_net *fbn = netdev_priv(netdev);
@@ -529,6 +543,8 @@ static int fbnic_bpf(struct net_device *netdev, struct netdev_bpf *bpf)
static const struct net_device_ops fbnic_netdev_ops = {
.ndo_open = fbnic_open,
.ndo_stop = fbnic_stop,
+ .ndo_init = fbnic_init,
+ .ndo_uninit = fbnic_uninit,
.ndo_validate_addr = eth_validate_addr,
.ndo_start_xmit = fbnic_xmit_frame,
.ndo_features_check = fbnic_features_check,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
index 7b773c06e245..f8807f6e443d 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
@@ -107,6 +107,7 @@ int fbnic_phylink_ethtool_ksettings_get(struct net_device *netdev,
int fbnic_phylink_get_fecparam(struct net_device *netdev,
struct ethtool_fecparam *fecparam);
int fbnic_phylink_init(struct net_device *netdev);
+int fbnic_phylink_connect(struct fbnic_net *fbn);
void fbnic_phylink_pmd_training_complete_notify(struct fbnic_net *fbn);
bool fbnic_check_split_frames(struct bpf_prog *prog,
unsigned int mtu, u32 hds_threshold);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index b3f05bdb4f52..befcb1e7747a 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -16,6 +16,7 @@
char fbnic_driver_name[] = DRV_NAME;
MODULE_DESCRIPTION(DRV_SUMMARY);
+MODULE_SOFTDEP("pre: fbnic_phy");
MODULE_LICENSE("GPL");
static const struct fbnic_info fbnic_asic_info = {
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
index e10fc08f22f2..59ee2fb32f91 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
@@ -132,9 +132,8 @@ fbnic_phylink_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
state->duplex = DUPLEX_FULL;
- state->link = (fbd->pmd_state == FBNIC_PMD_SEND_DATA) &&
- (rd32(fbd, FBNIC_PCS(MDIO_STAT1, 0)) &
- MDIO_STAT1_LSTATUS);
+ state->link = !!(rd32(fbd, FBNIC_PCS(MDIO_STAT1, 0)) &
+ MDIO_STAT1_LSTATUS);
}
static int
@@ -264,6 +263,39 @@ int fbnic_phylink_init(struct net_device *netdev)
return 0;
}
+/**
+ * fbnic_phylink_connect - Connect phylink structure to IRQ and enable it
+ * @fbn: FBNIC Netdev private data struct phylink device attached to
+ *
+ * Return: zero on success, negative on failure
+ *
+ * This function connects the phylink structure to the IRQ and then enables it
+ * to resume operations. With this function completed the PHY will be able to
+ * obtain link and notify the netdev of its current state.
+ **/
+int fbnic_phylink_connect(struct fbnic_net *fbn)
+{
+ struct fbnic_dev *fbd = fbn->fbd;
+ struct phy_device *phydev;
+ int err;
+
+ phydev = mdiobus_get_phy(fbd->mdio_bus, 0);
+ if (!phydev) {
+ dev_err(fbd->dev, "No PHY found\n");
+ return -ENODEV;
+ }
+
+ /* We don't need to poll, the MAC will notify us of events */
+ phydev->irq = PHY_MAC_INTERRUPT;
+ phy_attached_info(phydev);
+
+ err = phylink_connect_phy(fbn->phylink, phydev);
+ if (err)
+ dev_err(fbd->dev, "Error connecting phy, err: %d\n", err);
+
+ return err;
+}
+
/**
* fbnic_phylink_pmd_training_complete_notify - PMD training complete notifier
* @fbn: FBNIC Netdev private data struct phylink device attached to
@@ -285,5 +317,5 @@ void fbnic_phylink_pmd_training_complete_notify(struct fbnic_net *fbn)
return;
fbd->pmd_state = FBNIC_PMD_SEND_DATA;
- phylink_mac_change(fbn->phylink, true);
+ phy_mac_interrupt(fbd->netdev->phydev);
}
Powered by blists - more mailing lists