summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-02-02 19:16:05 -0800
committerJakub Kicinski <kuba@kernel.org>2026-02-02 19:16:05 -0800
commit43af6628f3f69d7011d3fd6e0ef40246a7471d41 (patch)
treeb0eec73af5b6e7731621e5d5eaf31d8947f7a693
parentfbc73cbb777b58fce41d24bdac9a739a1eac079a (diff)
parent69a586e8866b0c49cfc5592da50d67b3cbfa45f4 (diff)
Merge branch 'net-stmmac-pcs-preparation'
Russell King says: ==================== net: stmmac: pcs preparation These three patches prepare for the PCS changes, which, subject to Qualcomm testing, should be coming in the next cycle. ==================== Link: https://patch.msgid.link/aXyRlFw7ZuhRPiKo@shell.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c18
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c31
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h24
4 files changed, 44 insertions, 31 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index ca81bb1cae39..49893b9fb88c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -46,8 +46,6 @@ static void dwxgmac2_update_caps(struct stmmac_priv *priv)
{
if (!priv->dma_cap.mbps_10_100)
priv->hw->link.caps &= ~(MAC_10 | MAC_100);
- else if (!priv->dma_cap.half_duplex)
- priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
}
static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7a451ae19f50..9500b332a152 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -906,6 +906,9 @@ static unsigned long stmmac_mac_get_caps(struct phylink_config *config,
/* Refresh the MAC-specific capabilities */
stmmac_mac_update_caps(priv);
+ if (priv->hw_cap_support && !priv->dma_cap.half_duplex)
+ priv->hw->link.caps &= ~(MAC_1000HD | MAC_100HD | MAC_10HD);
+
config->mac_capabilities = priv->hw->link.caps;
if (priv->plat->max_speed)
@@ -3156,8 +3159,6 @@ int stmmac_get_phy_intf_sel(phy_interface_t interface)
phy_intf_sel = PHY_INTF_SEL_GMII_MII;
else if (phy_interface_mode_is_rgmii(interface))
phy_intf_sel = PHY_INTF_SEL_RGMII;
- else if (interface == PHY_INTERFACE_MODE_SGMII)
- phy_intf_sel = PHY_INTF_SEL_SGMII;
else if (interface == PHY_INTERFACE_MODE_RMII)
phy_intf_sel = PHY_INTF_SEL_RMII;
else if (interface == PHY_INTERFACE_MODE_REVMII)
@@ -3171,13 +3172,24 @@ static int stmmac_prereset_configure(struct stmmac_priv *priv)
{
struct plat_stmmacenet_data *plat_dat = priv->plat;
phy_interface_t interface;
+ struct phylink_pcs *pcs;
int phy_intf_sel, ret;
if (!plat_dat->set_phy_intf_sel)
return 0;
interface = plat_dat->phy_interface;
- phy_intf_sel = stmmac_get_phy_intf_sel(interface);
+
+ /* Check whether this mode uses a PCS */
+ pcs = stmmac_mac_select_pcs(&priv->phylink_config, interface);
+ if (priv->integrated_pcs && pcs == &priv->integrated_pcs->pcs) {
+ /* Request the phy_intf_sel from the integrated PCS */
+ phy_intf_sel = stmmac_integrated_pcs_get_phy_intf_sel(pcs,
+ interface);
+ } else {
+ phy_intf_sel = stmmac_get_phy_intf_sel(interface);
+ }
+
if (phy_intf_sel < 0) {
netdev_err(priv->dev,
"failed to get phy_intf_sel for %s: %pe\n",
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
index 2f826fe7229b..88fa359ea716 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c
@@ -2,6 +2,20 @@
#include "stmmac.h"
#include "stmmac_pcs.h"
+/*
+ * GMAC_AN_STATUS is equivalent to MII_BMSR
+ * GMAC_ANE_ADV is equivalent to 802.3z MII_ADVERTISE
+ * GMAC_ANE_LPA is equivalent to 802.3z MII_LPA
+ * GMAC_ANE_EXP is equivalent to MII_EXPANSION
+ * GMAC_TBI is equivalent to MII_ESTATUS
+ *
+ * ADV, LPA and EXP are only available for the TBI and RTBI modes.
+ */
+#define GMAC_AN_STATUS 0x04 /* AN status */
+#define GMAC_ANE_ADV 0x08 /* ANE Advertisement */
+#define GMAC_ANE_LPA 0x0c /* ANE link partener ability */
+#define GMAC_TBI 0x14 /* TBI extend status */
+
static int dwmac_integrated_pcs_enable(struct phylink_pcs *pcs)
{
struct stmmac_pcs *spcs = phylink_pcs_to_stmmac_pcs(pcs);
@@ -49,11 +63,11 @@ void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status,
struct stmmac_extra_stats *x)
{
struct stmmac_pcs *spcs = priv->integrated_pcs;
- u32 val = readl(spcs->base + GMAC_AN_STATUS(0));
+ u32 val = readl(spcs->base + GMAC_AN_STATUS);
if (status & PCS_ANE_IRQ) {
x->irq_pcs_ane_n++;
- if (val & GMAC_AN_STATUS_ANC)
+ if (val & BMSR_ANEGCOMPLETE)
dev_info(priv->device,
"PCS ANE process completed\n");
}
@@ -61,12 +75,21 @@ void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status,
if (status & PCS_LINK_IRQ) {
x->irq_pcs_link_n++;
dev_info(priv->device, "PCS Link %s\n",
- val & GMAC_AN_STATUS_LS ? "Up" : "Down");
+ val & BMSR_LSTATUS ? "Up" : "Down");
- phylink_pcs_change(&spcs->pcs, val & GMAC_AN_STATUS_LS);
+ phylink_pcs_change(&spcs->pcs, val & BMSR_LSTATUS);
}
}
+int stmmac_integrated_pcs_get_phy_intf_sel(struct phylink_pcs *pcs,
+ phy_interface_t interface)
+{
+ if (interface == PHY_INTERFACE_MODE_SGMII)
+ return PHY_INTF_SEL_SGMII;
+
+ return -EINVAL;
+}
+
int stmmac_integrated_pcs_init(struct stmmac_priv *priv, unsigned int offset,
u32 int_mask)
{
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
index c4e6b242d390..23bbd4f10bf8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
@@ -16,13 +16,6 @@
/* PCS registers (AN/TBI/SGMII/RGMII) offsets */
#define GMAC_AN_CTRL(x) (x) /* AN control */
-#define GMAC_AN_STATUS(x) (x + 0x4) /* AN status */
-
-/* ADV, LPA and EXP are only available for the TBI and RTBI interfaces */
-#define GMAC_ANE_ADV(x) (x + 0x8) /* ANE Advertisement */
-#define GMAC_ANE_LPA(x) (x + 0xc) /* ANE link partener ability */
-#define GMAC_ANE_EXP(x) (x + 0x10) /* ANE expansion */
-#define GMAC_TBI(x) (x + 0x14) /* TBI extend status */
/* AN Configuration defines */
#define GMAC_AN_CTRL_RAN BIT_U32(9) /* Restart Auto-Negotiation */
@@ -32,21 +25,6 @@
#define GMAC_AN_CTRL_LR BIT_U32(17) /* Lock to Reference */
#define GMAC_AN_CTRL_SGMRAL BIT_U32(18) /* SGMII RAL Control */
-/* AN Status defines */
-#define GMAC_AN_STATUS_LS BIT_U32(2) /* Link Status 0:down 1:up */
-#define GMAC_AN_STATUS_ANA BIT_U32(3) /* Auto-Negotiation Ability */
-#define GMAC_AN_STATUS_ANC BIT_U32(5) /* Auto-Negotiation Complete */
-#define GMAC_AN_STATUS_ES BIT_U32(8) /* Extended Status */
-
-/* ADV and LPA defines */
-#define GMAC_ANE_FD BIT_U32(5)
-#define GMAC_ANE_HD BIT_U32(6)
-#define GMAC_ANE_PSE GENMASK_U32(8, 7)
-#define GMAC_ANE_PSE_SHIFT 7
-#define GMAC_ANE_RFE GENMASK_U32(13, 12)
-#define GMAC_ANE_RFE_SHIFT 12
-#define GMAC_ANE_ACK BIT_U32(14)
-
struct stmmac_priv;
struct stmmac_pcs {
@@ -64,6 +42,8 @@ phylink_pcs_to_stmmac_pcs(struct phylink_pcs *pcs)
void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status,
struct stmmac_extra_stats *x);
+int stmmac_integrated_pcs_get_phy_intf_sel(struct phylink_pcs *pcs,
+ phy_interface_t interface);
int stmmac_integrated_pcs_init(struct stmmac_priv *priv, unsigned int offset,
u32 int_mask);