[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<176133848870.2245037.4413688703874426341.stgit@ahduyck-xeon-server.home.arpa>
Date: Fri, 24 Oct 2025 13:41:28 -0700
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 8/8] 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/fbnic/fbnic_irq.c | 2 -
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 7 +--
drivers/net/ethernet/meta/fbnic/fbnic_netdev.h | 1
drivers/net/ethernet/meta/fbnic/fbnic_phylink.c | 50 +++++++++++++++++++++--
4 files changed, 51 insertions(+), 9 deletions(-)
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 2d5ae89b4a15..1d732cf22ec5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -44,7 +44,7 @@ int __fbnic_open(struct fbnic_net *fbn)
if (err)
goto time_stop;
- err = fbnic_mac_request_irq(fbd);
+ err = fbnic_phylink_connect(fbn);
if (err)
goto time_stop;
@@ -52,8 +52,6 @@ int __fbnic_open(struct fbnic_net *fbn)
fbnic_bmc_rpc_init(fbd);
fbnic_rss_reinit(fbd, fbn);
- phylink_resume(fbn->phylink);
-
return 0;
time_stop:
fbnic_time_stop(fbn);
@@ -86,10 +84,11 @@ static int fbnic_stop(struct net_device *netdev)
{
struct fbnic_net *fbn = netdev_priv(netdev);
+ fbnic_mac_free_irq(fbn->fbd);
+ phylink_disconnect_phy(fbn->phylink);
phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
fbnic_down(fbn);
- fbnic_mac_free_irq(fbn->fbd);
fbnic_time_stop(fbn);
fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
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_phylink.c b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
index a9b2fc8108b7..b42cc5ad3055 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,49 @@ int fbnic_phylink_init(struct net_device *netdev)
return 0;
}
+/**
+ * fbnic_phylink_connect - Connect phylink structure to IRQ, PHY, and enable it
+ * @fbn: FBNIC Netdev private data struct phylink device attached to
+ *
+ * This function connects the phylink structure to the PHY and IRQ and then
+ * enables it to resuem 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 = phy_find_first(fbd->mii_bus);
+ 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;
+ }
+
+ err = fbnic_mac_request_irq(fbd);
+ if (err) {
+ phylink_disconnect_phy(fbn->phylink);
+ dev_err(fbd->dev, "Error requesting MAC IRQ, err: %d", err);
+ return err;
+ }
+
+ phylink_resume(fbn->phylink);
+
+ return 0;
+}
+
/**
* fbnic_phylink_pmd_training_complete_notify - PMD training complete notifier
* @fbn: FBNIC Netdev private data struct phylink device attached to
@@ -285,5 +327,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