* [PATCH net-next v3 01/10] net: freescale: ucc_geth: Drop support for the "interface" DT property
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 02/10] net: freescale: ucc_geth: split adjust_link for phylink conversion Maxime Chevallier
` (9 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
In april 2007, ucc_geth was converted to phylib with :
commit 728de4c927a3 ("ucc_geth: migrate ucc_geth to phylib").
In that commit, the device-tree property "interface", that could be used to
retrieve the PHY interface mode was deprecated.
DTS files that still used that property were converted along the way, in
the following commit, also dating from april 2007 :
commit 0fd8c47cccb1 ("[POWERPC] Replace undocumented interface properties in dts files")
17 years later, there's no users of that property left and I hope it's
safe to say we can remove support from that in the ucc_geth driver,
making the probe() function a bit simpler.
Should there be any users that have a DT that was generated when 2.6.21 was
cutting-edge, print an error message with hints on how to convert the
devicetree if the 'interface' property is found.
With that property gone, we can greatly simplify the parsing of the
phy-interface-mode from the devicetree by using of_get_phy_mode(),
allowing the removal of the open-coded parsing in the driver.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3 : Return an error code on failure. I kept Andrew's R'd-by though,
let me know if I should drop it.
drivers/net/ethernet/freescale/ucc_geth.c | 63 +++++------------------
1 file changed, 12 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 6663c1768089..b023a1a1dc5c 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3469,32 +3469,6 @@ static int ucc_geth_resume(struct platform_device *ofdev)
#define ucc_geth_resume NULL
#endif
-static phy_interface_t to_phy_interface(const char *phy_connection_type)
-{
- if (strcasecmp(phy_connection_type, "mii") == 0)
- return PHY_INTERFACE_MODE_MII;
- if (strcasecmp(phy_connection_type, "gmii") == 0)
- return PHY_INTERFACE_MODE_GMII;
- if (strcasecmp(phy_connection_type, "tbi") == 0)
- return PHY_INTERFACE_MODE_TBI;
- if (strcasecmp(phy_connection_type, "rmii") == 0)
- return PHY_INTERFACE_MODE_RMII;
- if (strcasecmp(phy_connection_type, "rgmii") == 0)
- return PHY_INTERFACE_MODE_RGMII;
- if (strcasecmp(phy_connection_type, "rgmii-id") == 0)
- return PHY_INTERFACE_MODE_RGMII_ID;
- if (strcasecmp(phy_connection_type, "rgmii-txid") == 0)
- return PHY_INTERFACE_MODE_RGMII_TXID;
- if (strcasecmp(phy_connection_type, "rgmii-rxid") == 0)
- return PHY_INTERFACE_MODE_RGMII_RXID;
- if (strcasecmp(phy_connection_type, "rtbi") == 0)
- return PHY_INTERFACE_MODE_RTBI;
- if (strcasecmp(phy_connection_type, "sgmii") == 0)
- return PHY_INTERFACE_MODE_SGMII;
-
- return PHY_INTERFACE_MODE_MII;
-}
-
static int ucc_geth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
@@ -3564,19 +3538,6 @@ static int ucc_geth_probe(struct platform_device* ofdev)
int err, ucc_num, max_speed = 0;
const unsigned int *prop;
phy_interface_t phy_interface;
- static const int enet_to_speed[] = {
- SPEED_10, SPEED_10, SPEED_10,
- SPEED_100, SPEED_100, SPEED_100,
- SPEED_1000, SPEED_1000, SPEED_1000, SPEED_1000,
- };
- static const phy_interface_t enet_to_phy_interface[] = {
- PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_RMII,
- PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_MII,
- PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
- PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
- PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
- PHY_INTERFACE_MODE_SGMII,
- };
ugeth_vdbg("%s: IN", __func__);
@@ -3627,18 +3588,18 @@ static int ucc_geth_probe(struct platform_device* ofdev)
/* Find the TBI PHY node. If it's not there, we don't support SGMII */
ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
- /* get the phy interface type, or default to MII */
- prop = of_get_property(np, "phy-connection-type", NULL);
- if (!prop) {
- /* handle interface property present in old trees */
- prop = of_get_property(ug_info->phy_node, "interface", NULL);
- if (prop != NULL) {
- phy_interface = enet_to_phy_interface[*prop];
- max_speed = enet_to_speed[*prop];
- } else
- phy_interface = PHY_INTERFACE_MODE_MII;
- } else {
- phy_interface = to_phy_interface((const char *)prop);
+ prop = of_get_property(ug_info->phy_node, "interface", NULL);
+ if (prop) {
+ dev_err(&ofdev->dev,
+ "Device-tree property 'interface' is no longer supported. Please use 'phy-connection-type' instead.");
+ err = -EINVAL;
+ goto err_deregister_fixed_link;
+ }
+
+ err = of_get_phy_mode(np, &phy_interface);
+ if (err) {
+ dev_err(&ofdev->dev, "Invalid phy-connection-type");
+ goto err_deregister_fixed_link;
}
/* get speed, or derive from PHY interface */
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v3 02/10] net: freescale: ucc_geth: split adjust_link for phylink conversion
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 01/10] net: freescale: ucc_geth: Drop support for the "interface" DT property Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 03/10] net: freescale: ucc_geth: Use netdev->phydev to access the PHY Maxime Chevallier
` (8 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
Preparing the phylink conversion, split the adjust_link callbaclk, by
clearly separating the mac configuration, link_up and link_down phases.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 180 +++++++++++-----------
1 file changed, 93 insertions(+), 87 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index b023a1a1dc5c..bf9f5901b405 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1548,105 +1548,111 @@ static void ugeth_activate(struct ucc_geth_private *ugeth)
__netdev_watchdog_up(ugeth->ndev);
}
-/* Called every time the controller might need to be made
- * aware of new link state. The PHY code conveys this
- * information through variables in the ugeth structure, and this
- * function converts those variables into the appropriate
- * register values, and can bring down the device if needed.
- */
-
-static void adjust_link(struct net_device *dev)
+static void ugeth_link_up(struct ucc_geth_private *ugeth,
+ struct phy_device *phy,
+ phy_interface_t interface, int speed, int duplex)
{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
- struct ucc_geth __iomem *ug_regs;
- struct ucc_fast __iomem *uf_regs;
- struct phy_device *phydev = ugeth->phydev;
+ struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
+ struct ucc_fast __iomem *uf_regs = ugeth->uccf->uf_regs;
+ u32 tempval = in_be32(&ug_regs->maccfg2);
+ u32 upsmr = in_be32(&uf_regs->upsmr);
int new_state = 0;
- ug_regs = ugeth->ug_regs;
- uf_regs = ugeth->uccf->uf_regs;
-
- if (phydev->link) {
- u32 tempval = in_be32(&ug_regs->maccfg2);
- u32 upsmr = in_be32(&uf_regs->upsmr);
- /* Now we make sure that we can be in full duplex mode.
- * If not, we operate in half-duplex mode. */
- if (phydev->duplex != ugeth->oldduplex) {
- new_state = 1;
- if (!(phydev->duplex))
- tempval &= ~(MACCFG2_FDX);
- else
- tempval |= MACCFG2_FDX;
- ugeth->oldduplex = phydev->duplex;
- }
+ /* Now we make sure that we can be in full duplex mode.
+ * If not, we operate in half-duplex mode.
+ */
+ if (duplex != ugeth->oldduplex) {
+ new_state = 1;
+ if (duplex == DUPLEX_HALF)
+ tempval &= ~(MACCFG2_FDX);
+ else
+ tempval |= MACCFG2_FDX;
+ ugeth->oldduplex = duplex;
+ }
- if (phydev->speed != ugeth->oldspeed) {
- new_state = 1;
- switch (phydev->speed) {
- case SPEED_1000:
- tempval = ((tempval &
- ~(MACCFG2_INTERFACE_MODE_MASK)) |
- MACCFG2_INTERFACE_MODE_BYTE);
- break;
- case SPEED_100:
- case SPEED_10:
- tempval = ((tempval &
- ~(MACCFG2_INTERFACE_MODE_MASK)) |
- MACCFG2_INTERFACE_MODE_NIBBLE);
- /* if reduced mode, re-set UPSMR.R10M */
- if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- if (phydev->speed == SPEED_10)
- upsmr |= UCC_GETH_UPSMR_R10M;
- else
- upsmr &= ~UCC_GETH_UPSMR_R10M;
- }
- break;
- default:
- if (netif_msg_link(ugeth))
- pr_warn(
- "%s: Ack! Speed (%d) is not 10/100/1000!",
- dev->name, phydev->speed);
- break;
+ if (speed != ugeth->oldspeed) {
+ new_state = 1;
+ switch (speed) {
+ case SPEED_1000:
+ tempval = ((tempval &
+ ~(MACCFG2_INTERFACE_MODE_MASK)) |
+ MACCFG2_INTERFACE_MODE_BYTE);
+ break;
+ case SPEED_100:
+ case SPEED_10:
+ tempval = ((tempval &
+ ~(MACCFG2_INTERFACE_MODE_MASK)) |
+ MACCFG2_INTERFACE_MODE_NIBBLE);
+ /* if reduced mode, re-set UPSMR.R10M */
+ if (interface == PHY_INTERFACE_MODE_RMII ||
+ phy_interface_mode_is_rgmii(interface) ||
+ interface == PHY_INTERFACE_MODE_RTBI) {
+ if (speed == SPEED_10)
+ upsmr |= UCC_GETH_UPSMR_R10M;
+ else
+ upsmr &= ~UCC_GETH_UPSMR_R10M;
}
- ugeth->oldspeed = phydev->speed;
+ break;
+ default:
+ if (netif_msg_link(ugeth))
+ pr_warn("%s: Speed (%d) is not 10/100/1000!",
+ netdev_name(ugeth->ndev), speed);
+ break;
}
+ ugeth->oldspeed = speed;
+ }
- if (!ugeth->oldlink) {
- new_state = 1;
- ugeth->oldlink = 1;
- }
+ if (!ugeth->oldlink) {
+ new_state = 1;
+ ugeth->oldlink = 1;
+ }
- if (new_state) {
- /*
- * To change the MAC configuration we need to disable
- * the controller. To do so, we have to either grab
- * ugeth->lock, which is a bad idea since 'graceful
- * stop' commands might take quite a while, or we can
- * quiesce driver's activity.
- */
- ugeth_quiesce(ugeth);
- ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+ if (new_state) {
+ /*
+ * To change the MAC configuration we need to disable
+ * the controller. To do so, we have to either grab
+ * ugeth->lock, which is a bad idea since 'graceful
+ * stop' commands might take quite a while, or we can
+ * quiesce driver's activity.
+ */
+ ugeth_quiesce(ugeth);
+ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
- out_be32(&ug_regs->maccfg2, tempval);
- out_be32(&uf_regs->upsmr, upsmr);
+ out_be32(&ug_regs->maccfg2, tempval);
+ out_be32(&uf_regs->upsmr, upsmr);
- ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
- ugeth_activate(ugeth);
- }
- } else if (ugeth->oldlink) {
- new_state = 1;
- ugeth->oldlink = 0;
- ugeth->oldspeed = 0;
- ugeth->oldduplex = -1;
+ ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+ ugeth_activate(ugeth);
}
- if (new_state && netif_msg_link(ugeth))
- phy_print_status(phydev);
+ if (netif_msg_link(ugeth))
+ phy_print_status(phy);
+}
+
+static void ugeth_link_down(struct ucc_geth_private *ugeth)
+{
+ ugeth->oldlink = 0;
+ ugeth->oldspeed = 0;
+ ugeth->oldduplex = -1;
+}
+
+/* Called every time the controller might need to be made
+ * aware of new link state. The PHY code conveys this
+ * information through variables in the ugeth structure, and this
+ * function converts those variables into the appropriate
+ * register values, and can bring down the device if needed.
+ */
+
+static void adjust_link(struct net_device *dev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+ struct phy_device *phydev = ugeth->phydev;
+
+ if (phydev->link)
+ ugeth_link_up(ugeth, phydev, phydev->interface,
+ phydev->speed, phydev->duplex);
+ else
+ ugeth_link_down(ugeth);
}
/* Initialize TBI PHY interface for communicating with the
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v3 03/10] net: freescale: ucc_geth: Use netdev->phydev to access the PHY
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 01/10] net: freescale: ucc_geth: Drop support for the "interface" DT property Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 02/10] net: freescale: ucc_geth: split adjust_link for phylink conversion Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 04/10] net: freescale: ucc_geth: Fix WOL configuration Maxime Chevallier
` (7 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
As this driver pre-dates phylib, it uses a private pointer to get a
reference to the attached phy_device. Drop that pointer and use the
netdev's pointer instead.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 27 ++++++++-----------
drivers/net/ethernet/freescale/ucc_geth.h | 1 -
.../net/ethernet/freescale/ucc_geth_ethtool.c | 17 ++++++------
3 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index bf9f5901b405..cc5f9ca42a78 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1646,7 +1646,7 @@ static void ugeth_link_down(struct ucc_geth_private *ugeth)
static void adjust_link(struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = dev->phydev;
if (phydev->link)
ugeth_link_up(ugeth, phydev, phydev->interface,
@@ -1727,8 +1727,6 @@ static int init_phy(struct net_device *dev)
phy_set_max_speed(phydev, priv->max_speed);
- priv->phydev = phydev;
-
return 0;
}
@@ -2001,7 +1999,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
static void ucc_geth_stop(struct ucc_geth_private *ugeth)
{
struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = ugeth->ndev->phydev;
ugeth_vdbg("%s: IN", __func__);
@@ -3316,13 +3314,13 @@ static int ucc_geth_open(struct net_device *dev)
goto err;
}
- phy_start(ugeth->phydev);
+ phy_start(dev->phydev);
napi_enable(&ugeth->napi);
netdev_reset_queue(dev);
netif_start_queue(dev);
device_set_wakeup_capable(&dev->dev,
- qe_alive_during_sleep() || ugeth->phydev->irq);
+ qe_alive_during_sleep() || dev->phydev->irq);
device_set_wakeup_enable(&dev->dev, ugeth->wol_en);
return err;
@@ -3343,8 +3341,7 @@ static int ucc_geth_close(struct net_device *dev)
cancel_work_sync(&ugeth->timeout_work);
ucc_geth_stop(ugeth);
- phy_disconnect(ugeth->phydev);
- ugeth->phydev = NULL;
+ phy_disconnect(dev->phydev);
free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
@@ -3378,7 +3375,7 @@ static void ucc_geth_timeout_work(struct work_struct *work)
ucc_geth_stop(ugeth);
ucc_geth_init_mac(ugeth);
/* Must start PHY here */
- phy_start(ugeth->phydev);
+ phy_start(dev->phydev);
netif_tx_start_all_queues(dev);
}
@@ -3421,7 +3418,7 @@ static int ucc_geth_suspend(struct platform_device *ofdev, pm_message_t state)
setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX);
} else if (!(ugeth->wol_en & WAKE_PHY)) {
- phy_stop(ugeth->phydev);
+ phy_stop(ndev->phydev);
}
return 0;
@@ -3461,8 +3458,8 @@ static int ucc_geth_resume(struct platform_device *ofdev)
ugeth->oldspeed = 0;
ugeth->oldduplex = -1;
- phy_stop(ugeth->phydev);
- phy_start(ugeth->phydev);
+ phy_stop(ndev->phydev);
+ phy_start(ndev->phydev);
napi_enable(&ugeth->napi);
netif_device_attach(ndev);
@@ -3477,15 +3474,13 @@ static int ucc_geth_resume(struct platform_device *ofdev)
static int ucc_geth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
-
if (!netif_running(dev))
return -EINVAL;
- if (!ugeth->phydev)
+ if (!dev->phydev)
return -ENODEV;
- return phy_mii_ioctl(ugeth->phydev, rq, cmd);
+ return phy_mii_ioctl(dev->phydev, rq, cmd);
}
static const struct net_device_ops ucc_geth_netdev_ops = {
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index 4294ed096ebb..c08a56b7c9fe 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1210,7 +1210,6 @@ struct ucc_geth_private {
u16 skb_dirtytx[NUM_TX_QUEUES];
struct ugeth_mii_info *mii_info;
- struct phy_device *phydev;
phy_interface_t phy_interface;
int max_speed;
uint32_t msg_enable;
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index 699f346faf5c..fb5254d7d1ba 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -103,8 +103,7 @@ static const char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
static int
uec_get_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd)
{
- struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = netdev->phydev;
if (!phydev)
return -ENODEV;
@@ -118,8 +117,7 @@ static int
uec_set_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
- struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = netdev->phydev;
if (!phydev)
return -ENODEV;
@@ -132,8 +130,10 @@ uec_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = netdev->phydev;
- pause->autoneg = ugeth->phydev->autoneg;
+ if (phydev)
+ pause->autoneg = phydev->autoneg;
if (ugeth->ug_info->receiveFlowControl)
pause->rx_pause = 1;
@@ -146,12 +146,13 @@ uec_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = netdev->phydev;
int ret = 0;
ugeth->ug_info->receiveFlowControl = pause->rx_pause;
ugeth->ug_info->transmitFlowControl = pause->tx_pause;
- if (ugeth->phydev->autoneg) {
+ if (phydev && phydev->autoneg) {
if (netif_running(netdev)) {
/* FIXME: automatically restart */
netdev_info(netdev, "Please re-open the interface\n");
@@ -343,7 +344,7 @@ uec_get_drvinfo(struct net_device *netdev,
static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = netdev->phydev;
if (phydev && phydev->irq)
wol->supported |= WAKE_PHY;
@@ -356,7 +357,7 @@ static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = ugeth->phydev;
+ struct phy_device *phydev = netdev->phydev;
if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
return -EINVAL;
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v3 04/10] net: freescale: ucc_geth: Fix WOL configuration
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (2 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 03/10] net: freescale: ucc_geth: Use netdev->phydev to access the PHY Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-04 1:58 ` Andrew Lunn
2024-12-03 12:43 ` [PATCH net-next v3 05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts Maxime Chevallier
` (6 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
The get/set_wol ethtool ops rely on querying the PHY for its WoL
capabilities, checking for the presence of a PHY and a PHY interrupts
isn't enough. Address that by cleaning up the WoL configuration
sequence.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 4 +--
drivers/net/ethernet/freescale/ucc_geth.h | 1 +
.../net/ethernet/freescale/ucc_geth_ethtool.c | 36 +++++++++++++++----
3 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index cc5f9ca42a78..587bcbc079da 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -3413,11 +3413,11 @@ static int ucc_geth_suspend(struct platform_device *ofdev, pm_message_t state)
*/
ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
- if (ugeth->wol_en & WAKE_MAGIC) {
+ if (ugeth->wol_en & WAKE_MAGIC && !ugeth->phy_wol_en) {
setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX);
- } else if (!(ugeth->wol_en & WAKE_PHY)) {
+ } else if (!ugeth->phy_wol_en) {
phy_stop(ndev->phydev);
}
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index c08a56b7c9fe..e08cfc8d8904 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1217,6 +1217,7 @@ struct ucc_geth_private {
int oldduplex;
int oldlink;
int wol_en;
+ u32 phy_wol_en;
struct device_node *node;
};
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index fb5254d7d1ba..89b323ef8145 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -346,26 +346,48 @@ static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct ucc_geth_private *ugeth = netdev_priv(netdev);
struct phy_device *phydev = netdev->phydev;
- if (phydev && phydev->irq)
- wol->supported |= WAKE_PHY;
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ if (phydev)
+ phy_ethtool_get_wol(phydev, wol);
+
if (qe_alive_during_sleep())
wol->supported |= WAKE_MAGIC;
- wol->wolopts = ugeth->wol_en;
+ wol->wolopts |= ugeth->wol_en;
}
static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
struct phy_device *phydev = netdev->phydev;
+ int ret = 0;
- if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
- return -EINVAL;
- else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
+ if (phydev) {
+ ret = phy_ethtool_set_wol(phydev, wol);
+ if (ret == -EOPNOTSUPP) {
+ ugeth->phy_wol_en = 0;
+ } else if (ret) {
+ return ret;
+ } else {
+ ugeth->phy_wol_en = wol->wolopts;
+ goto out;
+ }
+ }
+
+ /* If the PHY isn't handling the WoL and the MAC is asked to more than
+ * WAKE_MAGIC, error-out
+ */
+ if (!ugeth->phy_wol_en &&
+ wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
- else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
+
+ if (wol->wolopts & WAKE_MAGIC &&
+ !qe_alive_during_sleep())
return -EINVAL;
+out:
ugeth->wol_en = wol->wolopts;
device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 04/10] net: freescale: ucc_geth: Fix WOL configuration
2024-12-03 12:43 ` [PATCH net-next v3 04/10] net: freescale: ucc_geth: Fix WOL configuration Maxime Chevallier
@ 2024-12-04 1:58 ` Andrew Lunn
0 siblings, 0 replies; 19+ messages in thread
From: Andrew Lunn @ 2024-12-04 1:58 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
On Tue, Dec 03, 2024 at 01:43:15PM +0100, Maxime Chevallier wrote:
> The get/set_wol ethtool ops rely on querying the PHY for its WoL
> capabilities, checking for the presence of a PHY and a PHY interrupts
> isn't enough. Address that by cleaning up the WoL configuration
> sequence.
>
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
This at least looks sensible.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
I don't think we are going to get a perfect implementation until we
move most of the logic into phylink. We need the MAC to declare a
bitmap of what WoL options it supports. And we need the PHY to declare
the same. And the core can then figure out which of the enabled WoL
options the PHY should do, which the MAC should do, if the MAC can be
powered off, etc.
But i doubt that will get implemented any time soon.
Andrew
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v3 05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (3 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 04/10] net: freescale: ucc_geth: Fix WOL configuration Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-04 1:59 ` Andrew Lunn
2024-12-03 12:43 ` [PATCH net-next v3 06/10] net: freescale: ucc_geth: Simplify frame length check Maxime Chevallier
` (5 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
The WoL opts are represented through a bitmask stored in a u32. As this
mask is copied as-is in the driver, make sure we use the exact same type
to store them internally.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index e08cfc8d8904..60fd804a616a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1216,7 +1216,7 @@ struct ucc_geth_private {
int oldspeed;
int oldduplex;
int oldlink;
- int wol_en;
+ u32 wol_en;
u32 phy_wol_en;
struct device_node *node;
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts
2024-12-03 12:43 ` [PATCH net-next v3 05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts Maxime Chevallier
@ 2024-12-04 1:59 ` Andrew Lunn
0 siblings, 0 replies; 19+ messages in thread
From: Andrew Lunn @ 2024-12-04 1:59 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
On Tue, Dec 03, 2024 at 01:43:16PM +0100, Maxime Chevallier wrote:
> The WoL opts are represented through a bitmask stored in a u32. As this
> mask is copied as-is in the driver, make sure we use the exact same type
> to store them internally.
>
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v3 06/10] net: freescale: ucc_geth: Simplify frame length check
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (4 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 07/10] net: freescale: ucc_geth: Hardcode the preamble length to 7 bytes Maxime Chevallier
` (4 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
The frame length check is configured when the phy interface is setup.
However, it's configured according to an internal flag that is always
false. So, just make so that we disable the relevant bit in the MACCFG2
register upon accessing it for other MAC configuration operations.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 21 +++------------------
drivers/net/ethernet/freescale/ucc_geth.h | 1 -
2 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 587bcbc079da..566f53e24d28 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1205,22 +1205,6 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
return 0;
}
-static int init_check_frame_length_mode(int length_check,
- u32 __iomem *maccfg2_register)
-{
- u32 value = 0;
-
- value = in_be32(maccfg2_register);
-
- if (length_check)
- value |= MACCFG2_LC;
- else
- value &= ~MACCFG2_LC;
-
- out_be32(maccfg2_register, value);
- return 0;
-}
-
static int init_preamble_length(u8 preamble_length,
u32 __iomem *maccfg2_register)
{
@@ -1304,6 +1288,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
/* Set MACCFG2 */
maccfg2 = in_be32(&ug_regs->maccfg2);
+
+ /* Disable frame length check */
+ maccfg2 &= ~MACCFG2_LC;
maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
if ((ugeth->max_speed == SPEED_10) ||
(ugeth->max_speed == SPEED_100))
@@ -1365,8 +1352,6 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
put_device(&tbiphy->mdio.dev);
}
- init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
-
ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
if (ret_val != 0) {
if (netif_msg_probe(ugeth))
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index 60fd804a616a..2365b61c743a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1088,7 +1088,6 @@ struct ucc_geth_info {
u8 miminumInterFrameGapEnforcement;
u8 backToBackInterFrameGap;
int ipAddressAlignment;
- int lengthCheckRx;
u32 mblinterval;
u16 nortsrbytetime;
u8 fracsiz;
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v3 07/10] net: freescale: ucc_geth: Hardcode the preamble length to 7 bytes
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (5 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 06/10] net: freescale: ucc_geth: Simplify frame length check Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-03 12:43 ` [PATCH net-next v3 08/10] net: freescale: ucc_geth: Move the serdes configuration around Maxime Chevallier
` (3 subsequent siblings)
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
The preamble length can be configured in ucc_geth, however it just
ends-up always being configured to 7 bytes, as nothing ever changes the
default value of 7.
Make that value the default value when the MACCFG2 register gets
initialized, and remove the code to configure that value altogether.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 21 ---------------------
drivers/net/ethernet/freescale/ucc_geth.h | 4 ++--
2 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 566f53e24d28..81aefe291d80 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -132,7 +132,6 @@ static const struct ucc_geth_info ugeth_primary_info = {
.transmitFlowControl = 1,
.maxGroupAddrInHash = 4,
.maxIndAddrInHash = 4,
- .prel = 7,
.maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */
.minFrameLength = 64,
.maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */
@@ -1205,18 +1204,6 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
return 0;
}
-static int init_preamble_length(u8 preamble_length,
- u32 __iomem *maccfg2_register)
-{
- if ((preamble_length < 3) || (preamble_length > 7))
- return -EINVAL;
-
- clrsetbits_be32(maccfg2_register, MACCFG2_PREL_MASK,
- preamble_length << MACCFG2_PREL_SHIFT);
-
- return 0;
-}
-
static int init_rx_parameters(int reject_broadcast,
int receive_short_frames,
int promiscuous, u32 __iomem *upsmr_register)
@@ -1276,7 +1263,6 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
struct ucc_geth_info *ug_info;
struct ucc_geth __iomem *ug_regs;
struct ucc_fast __iomem *uf_regs;
- int ret_val;
u32 upsmr, maccfg2;
u16 value;
@@ -1352,13 +1338,6 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
put_device(&tbiphy->mdio.dev);
}
- ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
- if (ret_val != 0) {
- if (netif_msg_probe(ugeth))
- pr_err("Preamble length must be between 3 and 7 inclusive\n");
- return ret_val;
- }
-
return 0;
}
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index 2365b61c743a..dfb727327093 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -921,7 +921,8 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_UPSMR_INIT UCC_GETH_UPSMR_RES1
#define UCC_GETH_MACCFG1_INIT 0
-#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1)
+#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1 | \
+ (7 << MACCFG2_PREL_SHIFT))
/* Ethernet Address Type. */
enum enet_addr_type {
@@ -1113,7 +1114,6 @@ struct ucc_geth_info {
int transmitFlowControl;
u8 maxGroupAddrInHash;
u8 maxIndAddrInHash;
- u8 prel;
u16 maxFrameLength;
u16 minFrameLength;
u16 maxD1Length;
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v3 08/10] net: freescale: ucc_geth: Move the serdes configuration around
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (6 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 07/10] net: freescale: ucc_geth: Hardcode the preamble length to 7 bytes Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-04 2:12 ` Andrew Lunn
2024-12-03 12:43 ` [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes Maxime Chevallier
` (2 subsequent siblings)
10 siblings, 1 reply; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
The uec_configure_serdes() function deals with serialized linkmodes
settings. It's used during the link bringup sequence. It is planned to
be used during the phylink conversion for mac configuration, but it
needs to me moved around in the process. To make the phylink port
clearer, this commit moves the function without any feature change.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 93 +++++++++++------------
1 file changed, 46 insertions(+), 47 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 81aefe291d80..f6dd36dc03fe 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1512,6 +1512,52 @@ static void ugeth_activate(struct ucc_geth_private *ugeth)
__netdev_watchdog_up(ugeth->ndev);
}
+/* Initialize TBI PHY interface for communicating with the
+ * SERDES lynx PHY on the chip. We communicate with this PHY
+ * through the MDIO bus on each controller, treating it as a
+ * "normal" PHY at the address found in the UTBIPA register. We assume
+ * that the UTBIPA register is valid. Either the MDIO bus code will set
+ * it to a value that doesn't conflict with other PHYs on the bus, or the
+ * value doesn't matter, as there are no other PHYs on the bus.
+ */
+static void uec_configure_serdes(struct net_device *dev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+ struct phy_device *tbiphy;
+
+ if (!ug_info->tbi_node) {
+ dev_warn(&dev->dev, "SGMII mode requires that the device tree specify a tbi-handle\n");
+ return;
+ }
+
+ tbiphy = of_phy_find_device(ug_info->tbi_node);
+ if (!tbiphy) {
+ dev_err(&dev->dev, "error: Could not get TBI device\n");
+ return;
+ }
+
+ /*
+ * If the link is already up, we must already be ok, and don't need to
+ * configure and reset the TBI<->SerDes link. Maybe U-Boot configured
+ * everything for us? Resetting it takes the link down and requires
+ * several seconds for it to come back.
+ */
+ if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) {
+ put_device(&tbiphy->mdio.dev);
+ return;
+ }
+
+ /* Single clk mode, mii mode off(for serdes communication) */
+ phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
+
+ phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
+
+ phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
+
+ put_device(&tbiphy->mdio.dev);
+}
+
static void ugeth_link_up(struct ucc_geth_private *ugeth,
struct phy_device *phy,
phy_interface_t interface, int speed, int duplex)
@@ -1619,53 +1665,6 @@ static void adjust_link(struct net_device *dev)
ugeth_link_down(ugeth);
}
-/* Initialize TBI PHY interface for communicating with the
- * SERDES lynx PHY on the chip. We communicate with this PHY
- * through the MDIO bus on each controller, treating it as a
- * "normal" PHY at the address found in the UTBIPA register. We assume
- * that the UTBIPA register is valid. Either the MDIO bus code will set
- * it to a value that doesn't conflict with other PHYs on the bus, or the
- * value doesn't matter, as there are no other PHYs on the bus.
- */
-static void uec_configure_serdes(struct net_device *dev)
-{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
- struct ucc_geth_info *ug_info = ugeth->ug_info;
- struct phy_device *tbiphy;
-
- if (!ug_info->tbi_node) {
- dev_warn(&dev->dev, "SGMII mode requires that the device "
- "tree specify a tbi-handle\n");
- return;
- }
-
- tbiphy = of_phy_find_device(ug_info->tbi_node);
- if (!tbiphy) {
- dev_err(&dev->dev, "error: Could not get TBI device\n");
- return;
- }
-
- /*
- * If the link is already up, we must already be ok, and don't need to
- * configure and reset the TBI<->SerDes link. Maybe U-Boot configured
- * everything for us? Resetting it takes the link down and requires
- * several seconds for it to come back.
- */
- if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) {
- put_device(&tbiphy->mdio.dev);
- return;
- }
-
- /* Single clk mode, mii mode off(for serdes communication) */
- phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
-
- phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
-
- phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
-
- put_device(&tbiphy->mdio.dev);
-}
-
/* Configure the PHY for dev.
* returns 0 if success. -1 if failure
*/
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 08/10] net: freescale: ucc_geth: Move the serdes configuration around
2024-12-03 12:43 ` [PATCH net-next v3 08/10] net: freescale: ucc_geth: Move the serdes configuration around Maxime Chevallier
@ 2024-12-04 2:12 ` Andrew Lunn
0 siblings, 0 replies; 19+ messages in thread
From: Andrew Lunn @ 2024-12-04 2:12 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
On Tue, Dec 03, 2024 at 01:43:19PM +0100, Maxime Chevallier wrote:
> The uec_configure_serdes() function deals with serialized linkmodes
> settings. It's used during the link bringup sequence. It is planned to
> be used during the phylink conversion for mac configuration, but it
> needs to me moved around in the process. To make the phylink port
> clearer, this commit moves the function without any feature change.
>
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (7 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 08/10] net: freescale: ucc_geth: Move the serdes configuration around Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-04 2:15 ` Andrew Lunn
2024-12-03 12:43 ` [PATCH net-next v3 10/10] net: freescale: ucc_geth: phylink conversion Maxime Chevallier
2024-12-06 13:50 ` [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion patchwork-bot+netdevbpf
10 siblings, 1 reply; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
A number of parallel MII interfaces also exist in a "Reduced" mode,
usually with higher clock rates and fewer data lines, to ease the
hardware design. This is what the 'R' stands for in RGMII, RMII, RTBI,
RXAUI, etc.
The UCC Geth controller has a special configuration bit that needs to be
set when the MII mode is one of the supported reduced modes.
Add a local helper for that.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: No changes
drivers/net/ethernet/freescale/ucc_geth.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index f6dd36dc03fe..57debcba124c 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -1258,6 +1258,13 @@ static int init_min_frame_len(u16 min_frame_length,
return 0;
}
+static bool phy_interface_mode_is_reduced(phy_interface_t interface)
+{
+ return phy_interface_mode_is_rgmii(interface) ||
+ interface == PHY_INTERFACE_MODE_RMII ||
+ interface == PHY_INTERFACE_MODE_RTBI;
+}
+
static int adjust_enet_interface(struct ucc_geth_private *ugeth)
{
struct ucc_geth_info *ug_info;
@@ -1290,12 +1297,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
upsmr = in_be32(&uf_regs->upsmr);
upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M |
UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM);
- if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
+ if (phy_interface_mode_is_reduced(ugeth->phy_interface)) {
if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
upsmr |= UCC_GETH_UPSMR_RPM;
switch (ugeth->max_speed) {
@@ -1594,9 +1596,7 @@ static void ugeth_link_up(struct ucc_geth_private *ugeth,
~(MACCFG2_INTERFACE_MODE_MASK)) |
MACCFG2_INTERFACE_MODE_NIBBLE);
/* if reduced mode, re-set UPSMR.R10M */
- if (interface == PHY_INTERFACE_MODE_RMII ||
- phy_interface_mode_is_rgmii(interface) ||
- interface == PHY_INTERFACE_MODE_RTBI) {
+ if (phy_interface_mode_is_reduced(interface)) {
if (speed == SPEED_10)
upsmr |= UCC_GETH_UPSMR_R10M;
else
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
2024-12-03 12:43 ` [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes Maxime Chevallier
@ 2024-12-04 2:15 ` Andrew Lunn
2024-12-04 8:22 ` Maxime Chevallier
0 siblings, 1 reply; 19+ messages in thread
From: Andrew Lunn @ 2024-12-04 2:15 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
> +static bool phy_interface_mode_is_reduced(phy_interface_t interface)
> +{
> + return phy_interface_mode_is_rgmii(interface) ||
> + interface == PHY_INTERFACE_MODE_RMII ||
> + interface == PHY_INTERFACE_MODE_RTBI;
> +}
I wounder if this is useful anywhere else? Did you take a look around
other MAC drivers? Maybe this should be in phy.h?
Andrew
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
2024-12-04 2:15 ` Andrew Lunn
@ 2024-12-04 8:22 ` Maxime Chevallier
2024-12-04 15:41 ` Andrew Lunn
0 siblings, 1 reply; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-04 8:22 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
Hello Andrew,
On Wed, 4 Dec 2024 03:15:52 +0100
Andrew Lunn <andrew@lunn.ch> wrote:
> > +static bool phy_interface_mode_is_reduced(phy_interface_t interface)
> > +{
> > + return phy_interface_mode_is_rgmii(interface) ||
> > + interface == PHY_INTERFACE_MODE_RMII ||
> > + interface == PHY_INTERFACE_MODE_RTBI;
> > +}
>
> I wounder if this is useful anywhere else? Did you take a look around
> other MAC drivers? Maybe this should be in phy.h?
Yes I did consider it but it looks like ucc_geth is the only driver
that has a configuration that applies to all R(MII/GMII/TBI) interfaces
:/ I didn't even know about RTBI mode before looking at that driver and
it does look like it's not supported by that many devices... I'd be
happy to put that in phy.h but I think ucc_geth is going to be the sole
user :)
Thanks,
Maxime
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
2024-12-04 8:22 ` Maxime Chevallier
@ 2024-12-04 15:41 ` Andrew Lunn
2024-12-05 7:32 ` Maxime Chevallier
0 siblings, 1 reply; 19+ messages in thread
From: Andrew Lunn @ 2024-12-04 15:41 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
On Wed, Dec 04, 2024 at 09:22:32AM +0100, Maxime Chevallier wrote:
> Hello Andrew,
>
> On Wed, 4 Dec 2024 03:15:52 +0100
> Andrew Lunn <andrew@lunn.ch> wrote:
>
> > > +static bool phy_interface_mode_is_reduced(phy_interface_t interface)
> > > +{
> > > + return phy_interface_mode_is_rgmii(interface) ||
> > > + interface == PHY_INTERFACE_MODE_RMII ||
> > > + interface == PHY_INTERFACE_MODE_RTBI;
> > > +}
> >
> > I wounder if this is useful anywhere else? Did you take a look around
> > other MAC drivers? Maybe this should be in phy.h?
>
> Yes I did consider it but it looks like ucc_geth is the only driver
> that has a configuration that applies to all R(MII/GMII/TBI) interfaces
O.K. What is important is you considered it. Thanks. Too many
developers are focus on just their driver and don't think about other
drivers and code reuse.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
2024-12-04 15:41 ` Andrew Lunn
@ 2024-12-05 7:32 ` Maxime Chevallier
0 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-05 7:32 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Christophe Leroy, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Simon Horman, Herve Codina,
Uwe Kleine-König, linuxppc-dev
On Wed, 4 Dec 2024 16:41:33 +0100
Andrew Lunn <andrew@lunn.ch> wrote:
> On Wed, Dec 04, 2024 at 09:22:32AM +0100, Maxime Chevallier wrote:
> > Hello Andrew,
> >
> > On Wed, 4 Dec 2024 03:15:52 +0100
> > Andrew Lunn <andrew@lunn.ch> wrote:
> >
> > > > +static bool phy_interface_mode_is_reduced(phy_interface_t interface)
> > > > +{
> > > > + return phy_interface_mode_is_rgmii(interface) ||
> > > > + interface == PHY_INTERFACE_MODE_RMII ||
> > > > + interface == PHY_INTERFACE_MODE_RTBI;
> > > > +}
> > >
> > > I wounder if this is useful anywhere else? Did you take a look around
> > > other MAC drivers? Maybe this should be in phy.h?
> >
> > Yes I did consider it but it looks like ucc_geth is the only driver
> > that has a configuration that applies to all R(MII/GMII/TBI) interfaces
>
> O.K. What is important is you considered it. Thanks. Too many
> developers are focus on just their driver and don't think about other
> drivers and code reuse.
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Thanks Andrew. I should have indicated that in the commit log or in the
cover in the first place though, I'll make sure to do it next time.
Maxime
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v3 10/10] net: freescale: ucc_geth: phylink conversion
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (8 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes Maxime Chevallier
@ 2024-12-03 12:43 ` Maxime Chevallier
2024-12-06 13:50 ` [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion patchwork-bot+netdevbpf
10 siblings, 0 replies; 19+ messages in thread
From: Maxime Chevallier @ 2024-12-03 12:43 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Christophe Leroy, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Simon Horman, Herve Codina, Uwe Kleine-König, linuxppc-dev
ucc_geth is quite capable in terms of supported interfaces, and even
includes an externally controlled PCS (well, TBI). Port that driver to
phylink.
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V3: After adjusting patch 1, I also had to adjust the jump label in this
patch for the probe error handling.
drivers/net/ethernet/freescale/Kconfig | 3 +-
drivers/net/ethernet/freescale/ucc_geth.c | 445 ++++++++----------
drivers/net/ethernet/freescale/ucc_geth.h | 13 +-
.../net/ethernet/freescale/ucc_geth_ethtool.c | 73 +--
4 files changed, 209 insertions(+), 325 deletions(-)
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 75401d2a5fb4..a2d7300925a8 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -81,8 +81,7 @@ config UCC_GETH
tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE && PPC32
select FSL_PQ_MDIO
- select PHYLIB
- select FIXED_PHY
+ select PHYLINK
help
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
which is available on some Freescale SOCs.
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 57debcba124c..f47f8177a93b 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -26,7 +26,7 @@
#include <linux/dma-mapping.h>
#include <linux/mii.h>
#include <linux/phy.h>
-#include <linux/phy_fixed.h>
+#include <linux/phylink.h>
#include <linux/workqueue.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -34,6 +34,7 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/platform_device.h>
+#include <linux/rtnetlink.h>
#include <linux/uaccess.h>
#include <asm/irq.h>
@@ -1265,84 +1266,6 @@ static bool phy_interface_mode_is_reduced(phy_interface_t interface)
interface == PHY_INTERFACE_MODE_RTBI;
}
-static int adjust_enet_interface(struct ucc_geth_private *ugeth)
-{
- struct ucc_geth_info *ug_info;
- struct ucc_geth __iomem *ug_regs;
- struct ucc_fast __iomem *uf_regs;
- u32 upsmr, maccfg2;
- u16 value;
-
- ugeth_vdbg("%s: IN", __func__);
-
- ug_info = ugeth->ug_info;
- ug_regs = ugeth->ug_regs;
- uf_regs = ugeth->uccf->uf_regs;
-
- /* Set MACCFG2 */
- maccfg2 = in_be32(&ug_regs->maccfg2);
-
- /* Disable frame length check */
- maccfg2 &= ~MACCFG2_LC;
- maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
- if ((ugeth->max_speed == SPEED_10) ||
- (ugeth->max_speed == SPEED_100))
- maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
- else if (ugeth->max_speed == SPEED_1000)
- maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
- maccfg2 |= ug_info->padAndCrc;
- out_be32(&ug_regs->maccfg2, maccfg2);
-
- /* Set UPSMR */
- upsmr = in_be32(&uf_regs->upsmr);
- upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M |
- UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM);
- if (phy_interface_mode_is_reduced(ugeth->phy_interface)) {
- if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
- upsmr |= UCC_GETH_UPSMR_RPM;
- switch (ugeth->max_speed) {
- case SPEED_10:
- upsmr |= UCC_GETH_UPSMR_R10M;
- fallthrough;
- case SPEED_100:
- if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI)
- upsmr |= UCC_GETH_UPSMR_RMM;
- }
- }
- if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- upsmr |= UCC_GETH_UPSMR_TBIM;
- }
- if (ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII)
- upsmr |= UCC_GETH_UPSMR_SGMM;
-
- out_be32(&uf_regs->upsmr, upsmr);
-
- /* Disable autonegotiation in tbi mode, because by default it
- comes up in autonegotiation mode. */
- /* Note that this depends on proper setting in utbipar register. */
- if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
- (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- struct ucc_geth_info *ug_info = ugeth->ug_info;
- struct phy_device *tbiphy;
-
- if (!ug_info->tbi_node)
- pr_warn("TBI mode requires that the device tree specify a tbi-handle\n");
-
- tbiphy = of_phy_find_device(ug_info->tbi_node);
- if (!tbiphy)
- pr_warn("Could not get TBI device\n");
-
- value = phy_read(tbiphy, ENET_TBI_MII_CR);
- value &= ~0x1000; /* Turn off autonegotiation */
- phy_write(tbiphy, ENET_TBI_MII_CR, value);
-
- put_device(&tbiphy->mdio.dev);
- }
-
- return 0;
-}
-
static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
{
struct ucc_fast_private *uccf;
@@ -1560,64 +1483,62 @@ static void uec_configure_serdes(struct net_device *dev)
put_device(&tbiphy->mdio.dev);
}
-static void ugeth_link_up(struct ucc_geth_private *ugeth,
- struct phy_device *phy,
- phy_interface_t interface, int speed, int duplex)
+static void ugeth_mac_link_up(struct phylink_config *config, struct phy_device *phy,
+ unsigned int mode, phy_interface_t interface,
+ int speed, int duplex, bool tx_pause, bool rx_pause)
{
+ struct net_device *ndev = to_net_dev(config->dev);
+ struct ucc_geth_private *ugeth = netdev_priv(ndev);
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
struct ucc_fast __iomem *uf_regs = ugeth->uccf->uf_regs;
- u32 tempval = in_be32(&ug_regs->maccfg2);
- u32 upsmr = in_be32(&uf_regs->upsmr);
- int new_state = 0;
+ u32 old_maccfg2, maccfg2 = in_be32(&ug_regs->maccfg2);
+ u32 old_upsmr, upsmr = in_be32(&uf_regs->upsmr);
- /* Now we make sure that we can be in full duplex mode.
- * If not, we operate in half-duplex mode.
- */
- if (duplex != ugeth->oldduplex) {
- new_state = 1;
- if (duplex == DUPLEX_HALF)
- tempval &= ~(MACCFG2_FDX);
- else
- tempval |= MACCFG2_FDX;
- ugeth->oldduplex = duplex;
- }
+ old_maccfg2 = maccfg2;
+ old_upsmr = upsmr;
+
+ /* No length check */
+ maccfg2 &= ~MACCFG2_LC;
+ maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
+ upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M |
+ UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM);
+
+ if (speed == SPEED_10 || speed == SPEED_100)
+ maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
+ else if (speed == SPEED_1000)
+ maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
+
+ maccfg2 |= ug_info->padAndCrc;
+
+ if (phy_interface_mode_is_reduced(interface)) {
+
+ if (interface != PHY_INTERFACE_MODE_RMII)
+ upsmr |= UCC_GETH_UPSMR_RPM;
- if (speed != ugeth->oldspeed) {
- new_state = 1;
switch (speed) {
- case SPEED_1000:
- tempval = ((tempval &
- ~(MACCFG2_INTERFACE_MODE_MASK)) |
- MACCFG2_INTERFACE_MODE_BYTE);
- break;
- case SPEED_100:
case SPEED_10:
- tempval = ((tempval &
- ~(MACCFG2_INTERFACE_MODE_MASK)) |
- MACCFG2_INTERFACE_MODE_NIBBLE);
- /* if reduced mode, re-set UPSMR.R10M */
- if (phy_interface_mode_is_reduced(interface)) {
- if (speed == SPEED_10)
- upsmr |= UCC_GETH_UPSMR_R10M;
- else
- upsmr &= ~UCC_GETH_UPSMR_R10M;
- }
- break;
- default:
- if (netif_msg_link(ugeth))
- pr_warn("%s: Speed (%d) is not 10/100/1000!",
- netdev_name(ugeth->ndev), speed);
- break;
+ upsmr |= UCC_GETH_UPSMR_R10M;
+ fallthrough;
+ case SPEED_100:
+ if (interface != PHY_INTERFACE_MODE_RTBI)
+ upsmr |= UCC_GETH_UPSMR_RMM;
}
- ugeth->oldspeed = speed;
}
- if (!ugeth->oldlink) {
- new_state = 1;
- ugeth->oldlink = 1;
- }
+ if (interface == PHY_INTERFACE_MODE_TBI ||
+ interface == PHY_INTERFACE_MODE_RTBI)
+ upsmr |= UCC_GETH_UPSMR_TBIM;
+
+ if (interface == PHY_INTERFACE_MODE_SGMII)
+ upsmr |= UCC_GETH_UPSMR_SGMM;
- if (new_state) {
+ if (duplex == DUPLEX_HALF)
+ maccfg2 &= ~(MACCFG2_FDX);
+ else
+ maccfg2 |= MACCFG2_FDX;
+
+ if (maccfg2 != old_maccfg2 || upsmr != old_upsmr) {
/*
* To change the MAC configuration we need to disable
* the controller. To do so, we have to either grab
@@ -1628,69 +1549,79 @@ static void ugeth_link_up(struct ucc_geth_private *ugeth,
ugeth_quiesce(ugeth);
ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
- out_be32(&ug_regs->maccfg2, tempval);
+ out_be32(&ug_regs->maccfg2, maccfg2);
out_be32(&uf_regs->upsmr, upsmr);
ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
ugeth_activate(ugeth);
}
- if (netif_msg_link(ugeth))
- phy_print_status(phy);
-}
+ if (interface == PHY_INTERFACE_MODE_SGMII)
+ uec_configure_serdes(ndev);
-static void ugeth_link_down(struct ucc_geth_private *ugeth)
-{
- ugeth->oldlink = 0;
- ugeth->oldspeed = 0;
- ugeth->oldduplex = -1;
-}
+ if (!phylink_autoneg_inband(mode)) {
+ ug_info->aufc = 0;
+ ug_info->receiveFlowControl = rx_pause;
+ ug_info->transmitFlowControl = tx_pause;
-/* Called every time the controller might need to be made
- * aware of new link state. The PHY code conveys this
- * information through variables in the ugeth structure, and this
- * function converts those variables into the appropriate
- * register values, and can bring down the device if needed.
- */
+ init_flow_control_params(ug_info->aufc,
+ ug_info->receiveFlowControl,
+ ug_info->transmitFlowControl,
+ ug_info->pausePeriod,
+ ug_info->extensionField,
+ &ugeth->uccf->uf_regs->upsmr,
+ &ugeth->ug_regs->uempr,
+ &ugeth->ug_regs->maccfg1);
+ }
-static void adjust_link(struct net_device *dev)
+ ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+}
+
+static void ugeth_mac_link_down(struct phylink_config *config,
+ unsigned int mode, phy_interface_t interface)
{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
- struct phy_device *phydev = dev->phydev;
+ struct net_device *ndev = to_net_dev(config->dev);
+ struct ucc_geth_private *ugeth = netdev_priv(ndev);
- if (phydev->link)
- ugeth_link_up(ugeth, phydev, phydev->interface,
- phydev->speed, phydev->duplex);
- else
- ugeth_link_down(ugeth);
+ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
}
-/* Configure the PHY for dev.
- * returns 0 if success. -1 if failure
- */
-static int init_phy(struct net_device *dev)
+static void ugeth_mac_config(struct phylink_config *config, unsigned int mode,
+ const struct phylink_link_state *state)
{
- struct ucc_geth_private *priv = netdev_priv(dev);
- struct ucc_geth_info *ug_info = priv->ug_info;
- struct phy_device *phydev;
+ struct net_device *ndev = to_net_dev(config->dev);
+ struct ucc_geth_private *ugeth = netdev_priv(ndev);
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+ u16 value;
- priv->oldlink = 0;
- priv->oldspeed = 0;
- priv->oldduplex = -1;
+ if (state->interface == PHY_INTERFACE_MODE_TBI ||
+ state->interface == PHY_INTERFACE_MODE_RTBI) {
+ struct phy_device *tbiphy;
- phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
- priv->phy_interface);
- if (!phydev) {
- dev_err(&dev->dev, "Could not attach to PHY\n");
- return -ENODEV;
- }
+ if (!ug_info->tbi_node)
+ pr_warn("TBI mode requires that the device tree specify a tbi-handle\n");
+
+ tbiphy = of_phy_find_device(ug_info->tbi_node);
+ if (!tbiphy)
+ pr_warn("Could not get TBI device\n");
+
+ value = phy_read(tbiphy, ENET_TBI_MII_CR);
+ value &= ~0x1000; /* Turn off autonegotiation */
+ phy_write(tbiphy, ENET_TBI_MII_CR, value);
- if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
- uec_configure_serdes(dev);
+ put_device(&tbiphy->mdio.dev);
+ }
- phy_set_max_speed(phydev, priv->max_speed);
+ if (phylink_autoneg_inband(mode)) {
+ ug_info->aufc = 1;
- return 0;
+ init_flow_control_params(ug_info->aufc, 1, 1,
+ ug_info->pausePeriod,
+ ug_info->extensionField,
+ &ugeth->uccf->uf_regs->upsmr,
+ &ugeth->ug_regs->uempr,
+ &ugeth->ug_regs->maccfg1);
+ }
}
static void ugeth_dump_regs(struct ucc_geth_private *ugeth)
@@ -1962,7 +1893,6 @@ static void ucc_geth_set_multi(struct net_device *dev)
static void ucc_geth_stop(struct ucc_geth_private *ugeth)
{
struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
- struct phy_device *phydev = ugeth->ndev->phydev;
ugeth_vdbg("%s: IN", __func__);
@@ -1971,7 +1901,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
* Must be done before disabling the controller
* or deadlock may happen.
*/
- phy_stop(phydev);
+ phylink_stop(ugeth->phylink);
/* Disable the controller */
ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
@@ -3213,12 +3143,6 @@ static int ucc_geth_init_mac(struct ucc_geth_private *ugeth)
goto err;
}
- err = adjust_enet_interface(ugeth);
- if (err) {
- netif_err(ugeth, ifup, dev, "Cannot configure net device, aborting\n");
- goto err;
- }
-
/* Set MACSTNADDR1, MACSTNADDR2 */
/* For more details see the hardware spec. */
init_mac_station_addr_regs(dev->dev_addr[0],
@@ -3230,12 +3154,6 @@ static int ucc_geth_init_mac(struct ucc_geth_private *ugeth)
&ugeth->ug_regs->macstnaddr1,
&ugeth->ug_regs->macstnaddr2);
- err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
- if (err) {
- netif_err(ugeth, ifup, dev, "Cannot enable net device, aborting\n");
- goto err;
- }
-
return 0;
err:
ucc_geth_stop(ugeth);
@@ -3258,10 +3176,10 @@ static int ucc_geth_open(struct net_device *dev)
return -EINVAL;
}
- err = init_phy(dev);
+ err = phylink_of_phy_connect(ugeth->phylink, ugeth->dev->of_node, 0);
if (err) {
- netif_err(ugeth, ifup, dev, "Cannot initialize PHY, aborting\n");
- return err;
+ dev_err(&dev->dev, "Could not attach to PHY\n");
+ return -ENODEV;
}
err = ucc_geth_init_mac(ugeth);
@@ -3277,7 +3195,7 @@ static int ucc_geth_open(struct net_device *dev)
goto err;
}
- phy_start(dev->phydev);
+ phylink_start(ugeth->phylink);
napi_enable(&ugeth->napi);
netdev_reset_queue(dev);
netif_start_queue(dev);
@@ -3304,7 +3222,7 @@ static int ucc_geth_close(struct net_device *dev)
cancel_work_sync(&ugeth->timeout_work);
ucc_geth_stop(ugeth);
- phy_disconnect(dev->phydev);
+ phylink_disconnect_phy(ugeth->phylink);
free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
@@ -3338,7 +3256,7 @@ static void ucc_geth_timeout_work(struct work_struct *work)
ucc_geth_stop(ugeth);
ucc_geth_init_mac(ugeth);
/* Must start PHY here */
- phy_start(dev->phydev);
+ phylink_start(ugeth->phylink);
netif_tx_start_all_queues(dev);
}
@@ -3363,6 +3281,7 @@ static int ucc_geth_suspend(struct platform_device *ofdev, pm_message_t state)
{
struct net_device *ndev = platform_get_drvdata(ofdev);
struct ucc_geth_private *ugeth = netdev_priv(ndev);
+ bool mac_wol = false;
if (!netif_running(ndev))
return 0;
@@ -3380,10 +3299,13 @@ static int ucc_geth_suspend(struct platform_device *ofdev, pm_message_t state)
setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX);
- } else if (!ugeth->phy_wol_en) {
- phy_stop(ndev->phydev);
+ mac_wol = true;
}
+ rtnl_lock();
+ phylink_suspend(ugeth->phylink, mac_wol);
+ rtnl_unlock();
+
return 0;
}
@@ -3417,12 +3339,9 @@ static int ucc_geth_resume(struct platform_device *ofdev)
}
}
- ugeth->oldlink = 0;
- ugeth->oldspeed = 0;
- ugeth->oldduplex = -1;
-
- phy_stop(ndev->phydev);
- phy_start(ndev->phydev);
+ rtnl_lock();
+ phylink_resume(ugeth->phylink);
+ rtnl_unlock();
napi_enable(&ugeth->napi);
netif_device_attach(ndev);
@@ -3437,13 +3356,12 @@ static int ucc_geth_resume(struct platform_device *ofdev)
static int ucc_geth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+
if (!netif_running(dev))
return -EINVAL;
- if (!dev->phydev)
- return -ENODEV;
-
- return phy_mii_ioctl(dev->phydev, rq, cmd);
+ return phylink_mii_ioctl(ugeth->phylink, rq, cmd);
}
static const struct net_device_ops ucc_geth_netdev_ops = {
@@ -3451,7 +3369,6 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
.ndo_stop = ucc_geth_close,
.ndo_start_xmit = ucc_geth_start_xmit,
.ndo_validate_addr = eth_validate_addr,
- .ndo_change_carrier = fixed_phy_change_carrier,
.ndo_set_mac_address = ucc_geth_set_mac_addr,
.ndo_set_rx_mode = ucc_geth_set_multi,
.ndo_tx_timeout = ucc_geth_timeout,
@@ -3491,6 +3408,12 @@ static int ucc_geth_parse_clock(struct device_node *np, const char *which,
return 0;
}
+struct phylink_mac_ops ugeth_mac_ops = {
+ .mac_link_up = ugeth_mac_link_up,
+ .mac_link_down = ugeth_mac_link_down,
+ .mac_config = ugeth_mac_config,
+};
+
static int ucc_geth_probe(struct platform_device* ofdev)
{
struct device *device = &ofdev->dev;
@@ -3498,8 +3421,10 @@ static int ucc_geth_probe(struct platform_device* ofdev)
struct net_device *dev = NULL;
struct ucc_geth_private *ugeth = NULL;
struct ucc_geth_info *ug_info;
+ struct device_node *phy_node;
+ struct phylink *phylink;
struct resource res;
- int err, ucc_num, max_speed = 0;
+ int err, ucc_num;
const unsigned int *prop;
phy_interface_t phy_interface;
@@ -3537,57 +3462,35 @@ static int ucc_geth_probe(struct platform_device* ofdev)
ug_info->uf_info.regs = res.start;
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
- ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0);
- if (!ug_info->phy_node && of_phy_is_fixed_link(np)) {
- /*
- * In the case of a fixed PHY, the DT node associated
- * to the PHY is the Ethernet MAC DT node.
- */
- err = of_phy_register_fixed_link(np);
- if (err)
- return err;
- ug_info->phy_node = of_node_get(np);
- }
-
/* Find the TBI PHY node. If it's not there, we don't support SGMII */
ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
- prop = of_get_property(ug_info->phy_node, "interface", NULL);
- if (prop) {
- dev_err(&ofdev->dev,
- "Device-tree property 'interface' is no longer supported. Please use 'phy-connection-type' instead.");
- err = -EINVAL;
- goto err_deregister_fixed_link;
+ phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (phy_node) {
+ prop = of_get_property(phy_node, "interface", NULL);
+ if (prop) {
+ dev_err(&ofdev->dev,
+ "Device-tree property 'interface' is no longer supported. Please use 'phy-connection-type' instead.");
+ of_node_put(phy_node);
+ err = -EINVAL;
+ goto err_put_tbi;
+ }
+ of_node_put(phy_node);
}
err = of_get_phy_mode(np, &phy_interface);
if (err) {
dev_err(&ofdev->dev, "Invalid phy-connection-type");
- goto err_deregister_fixed_link;
- }
-
- /* get speed, or derive from PHY interface */
- if (max_speed == 0)
- switch (phy_interface) {
- case PHY_INTERFACE_MODE_GMII:
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- case PHY_INTERFACE_MODE_TBI:
- case PHY_INTERFACE_MODE_RTBI:
- case PHY_INTERFACE_MODE_SGMII:
- max_speed = SPEED_1000;
- break;
- default:
- max_speed = SPEED_100;
- break;
- }
+ goto err_put_tbi;
+ }
- if (max_speed == SPEED_1000) {
+ if (phy_interface == PHY_INTERFACE_MODE_GMII ||
+ phy_interface_mode_is_rgmii(phy_interface) ||
+ phy_interface == PHY_INTERFACE_MODE_TBI ||
+ phy_interface == PHY_INTERFACE_MODE_RTBI ||
+ phy_interface == PHY_INTERFACE_MODE_SGMII) {
unsigned int snums = qe_get_num_of_snums();
- /* configure muram FIFOs for gigabit operation */
ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
@@ -3616,7 +3519,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
dev = devm_alloc_etherdev(&ofdev->dev, sizeof(*ugeth));
if (!dev) {
err = -ENOMEM;
- goto err_deregister_fixed_link;
+ goto err_put_tbi;
}
ugeth = netdev_priv(dev);
@@ -3643,23 +3546,50 @@ static int ucc_geth_probe(struct platform_device* ofdev)
dev->max_mtu = 1518;
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
- ugeth->phy_interface = phy_interface;
- ugeth->max_speed = max_speed;
- /* Carrier starts down, phylib will bring it up */
- netif_carrier_off(dev);
+ ugeth->phylink_config.dev = &dev->dev;
+ ugeth->phylink_config.type = PHYLINK_NETDEV;
+
+ ugeth->phylink_config.mac_capabilities =
+ MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD;
+
+ __set_bit(PHY_INTERFACE_MODE_MII,
+ ugeth->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_RMII,
+ ugeth->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_GMII,
+ ugeth->phylink_config.supported_interfaces);
+ phy_interface_set_rgmii(ugeth->phylink_config.supported_interfaces);
+
+ if (ug_info->tbi_node) {
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
+ ugeth->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_TBI,
+ ugeth->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_RTBI,
+ ugeth->phylink_config.supported_interfaces);
+ }
+
+ phylink = phylink_create(&ugeth->phylink_config, dev_fwnode(&dev->dev),
+ phy_interface, &ugeth_mac_ops);
+ if (IS_ERR(phylink)) {
+ err = PTR_ERR(phylink);
+ goto err_put_tbi;
+ }
+
+ ugeth->phylink = phylink;
err = devm_register_netdev(&ofdev->dev, dev);
if (err) {
if (netif_msg_probe(ugeth))
pr_err("%s: Cannot register net device, aborting\n",
dev->name);
- goto err_deregister_fixed_link;
+ goto err_destroy_phylink;
}
err = of_get_ethdev_address(np, dev);
if (err == -EPROBE_DEFER)
- goto err_deregister_fixed_link;
+ goto err_destroy_phylink;
ugeth->ug_info = ug_info;
ugeth->dev = device;
@@ -3668,11 +3598,11 @@ static int ucc_geth_probe(struct platform_device* ofdev)
return 0;
-err_deregister_fixed_link:
- if (of_phy_is_fixed_link(np))
- of_phy_deregister_fixed_link(np);
+err_destroy_phylink:
+ phylink_destroy(phylink);
+err_put_tbi:
of_node_put(ug_info->tbi_node);
- of_node_put(ug_info->phy_node);
+
return err;
}
@@ -3680,13 +3610,10 @@ static void ucc_geth_remove(struct platform_device* ofdev)
{
struct net_device *dev = platform_get_drvdata(ofdev);
struct ucc_geth_private *ugeth = netdev_priv(dev);
- struct device_node *np = ofdev->dev.of_node;
ucc_geth_memclean(ugeth);
- if (of_phy_is_fixed_link(np))
- of_phy_deregister_fixed_link(np);
+ phylink_destroy(ugeth->phylink);
of_node_put(ugeth->ug_info->tbi_node);
- of_node_put(ugeth->ug_info->phy_node);
}
static const struct of_device_id ucc_geth_match[] = {
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index dfb727327093..38789faae706 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/phylink.h>
#include <linux/if_ether.h>
#include <soc/fsl/qe/immap_qe.h>
@@ -1074,6 +1075,9 @@ struct ucc_geth_tad_params {
u16 vid;
};
+struct phylink;
+struct phylink_config;
+
/* GETH protocol initialization structure */
struct ucc_geth_info {
struct ucc_fast_info uf_info;
@@ -1124,7 +1128,6 @@ struct ucc_geth_info {
u32 eventRegMask;
u16 pausePeriod;
u16 extensionField;
- struct device_node *phy_node;
struct device_node *tbi_node;
u8 weightfactor[NUM_TX_QUEUES];
u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
@@ -1209,15 +1212,13 @@ struct ucc_geth_private {
u16 skb_dirtytx[NUM_TX_QUEUES];
struct ugeth_mii_info *mii_info;
- phy_interface_t phy_interface;
- int max_speed;
uint32_t msg_enable;
- int oldspeed;
- int oldduplex;
- int oldlink;
u32 wol_en;
u32 phy_wol_en;
+ struct phylink *phylink;
+ struct phylink_config phylink_config;
+
struct device_node *node;
};
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index 89b323ef8145..1fb49e5a414a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -103,26 +103,18 @@ static const char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
static int
uec_get_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd)
{
- struct phy_device *phydev = netdev->phydev;
-
- if (!phydev)
- return -ENODEV;
-
- phy_ethtool_ksettings_get(phydev, cmd);
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
- return 0;
+ return phylink_ethtool_ksettings_get(ugeth->phylink, cmd);
}
static int
uec_set_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
- struct phy_device *phydev = netdev->phydev;
-
- if (!phydev)
- return -ENODEV;
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
- return phy_ethtool_ksettings_set(phydev, cmd);
+ return phylink_ethtool_ksettings_set(ugeth->phylink, cmd);
}
static void
@@ -130,15 +122,8 @@ uec_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
-
- if (phydev)
- pause->autoneg = phydev->autoneg;
- if (ugeth->ug_info->receiveFlowControl)
- pause->rx_pause = 1;
- if (ugeth->ug_info->transmitFlowControl)
- pause->tx_pause = 1;
+ return phylink_ethtool_get_pauseparam(ugeth->phylink, pause);
}
static int
@@ -146,31 +131,11 @@ uec_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
- int ret = 0;
ugeth->ug_info->receiveFlowControl = pause->rx_pause;
ugeth->ug_info->transmitFlowControl = pause->tx_pause;
- if (phydev && phydev->autoneg) {
- if (netif_running(netdev)) {
- /* FIXME: automatically restart */
- netdev_info(netdev, "Please re-open the interface\n");
- }
- } else {
- struct ucc_geth_info *ug_info = ugeth->ug_info;
-
- ret = init_flow_control_params(ug_info->aufc,
- ug_info->receiveFlowControl,
- ug_info->transmitFlowControl,
- ug_info->pausePeriod,
- ug_info->extensionField,
- &ugeth->uccf->uf_regs->upsmr,
- &ugeth->ug_regs->uempr,
- &ugeth->ug_regs->maccfg1);
- }
-
- return ret;
+ return phylink_ethtool_set_pauseparam(ugeth->phylink, pause);
}
static uint32_t
@@ -344,13 +309,8 @@ uec_get_drvinfo(struct net_device *netdev,
static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
-
- wol->supported = 0;
- wol->wolopts = 0;
- if (phydev)
- phy_ethtool_get_wol(phydev, wol);
+ phylink_ethtool_get_wol(ugeth->phylink, wol);
if (qe_alive_during_sleep())
wol->supported |= WAKE_MAGIC;
@@ -361,19 +321,16 @@ static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct ucc_geth_private *ugeth = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
int ret = 0;
- if (phydev) {
- ret = phy_ethtool_set_wol(phydev, wol);
- if (ret == -EOPNOTSUPP) {
- ugeth->phy_wol_en = 0;
- } else if (ret) {
- return ret;
- } else {
- ugeth->phy_wol_en = wol->wolopts;
- goto out;
- }
+ ret = phylink_ethtool_set_wol(ugeth->phylink, wol);
+ if (ret == -EOPNOTSUPP) {
+ ugeth->phy_wol_en = 0;
+ } else if (ret) {
+ return ret;
+ } else {
+ ugeth->phy_wol_en = wol->wolopts;
+ goto out;
}
/* If the PHY isn't handling the WoL and the MAC is asked to more than
--
2.47.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion
2024-12-03 12:43 [PATCH net-next v3 00/10] net: freescale: ucc_geth: Phylink conversion Maxime Chevallier
` (9 preceding siblings ...)
2024-12-03 12:43 ` [PATCH net-next v3 10/10] net: freescale: ucc_geth: phylink conversion Maxime Chevallier
@ 2024-12-06 13:50 ` patchwork-bot+netdevbpf
10 siblings, 0 replies; 19+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-12-06 13:50 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, andrew, kuba, edumazet, pabeni, linux, christophe.leroy,
hkallweit1, netdev, linux-kernel, thomas.petazzoni, horms,
herve.codina, u.kleine-koenig, linuxppc-dev
Hello:
This series was applied to netdev/net-next.git (main)
by David S. Miller <davem@davemloft.net>:
On Tue, 3 Dec 2024 13:43:11 +0100 you wrote:
> Hello everyone,
>
> This is V3 of the phylink conversion for ucc_geth.
>
> The main changes in this V3 are related to error handling in the patches
> 1 and 10 to report an error when the deprecated "interface" property is
> found in DT. Doing so, I found and addressed some issues with the jump
> labels in the error paths, impacting patches 1 and 10.
>
> [...]
Here is the summary with links:
- [net-next,v3,01/10] net: freescale: ucc_geth: Drop support for the "interface" DT property
https://git.kernel.org/netdev/net-next/c/3e42bb998c6d
- [net-next,v3,02/10] net: freescale: ucc_geth: split adjust_link for phylink conversion
https://git.kernel.org/netdev/net-next/c/1e59fd163100
- [net-next,v3,03/10] net: freescale: ucc_geth: Use netdev->phydev to access the PHY
https://git.kernel.org/netdev/net-next/c/43068024cc2a
- [net-next,v3,04/10] net: freescale: ucc_geth: Fix WOL configuration
https://git.kernel.org/netdev/net-next/c/d2adc441a19a
- [net-next,v3,05/10] net: freescale: ucc_geth: Use the correct type to store WoL opts
https://git.kernel.org/netdev/net-next/c/420d56e4de52
- [net-next,v3,06/10] net: freescale: ucc_geth: Simplify frame length check
https://git.kernel.org/netdev/net-next/c/270ec339126a
- [net-next,v3,07/10] net: freescale: ucc_geth: Hardcode the preamble length to 7 bytes
https://git.kernel.org/netdev/net-next/c/dba25f75383f
- [net-next,v3,08/10] net: freescale: ucc_geth: Move the serdes configuration around
https://git.kernel.org/netdev/net-next/c/efc52055b756
- [net-next,v3,09/10] net: freescale: ucc_geth: Introduce a helper to check Reduced modes
https://git.kernel.org/netdev/net-next/c/02d4a6498b30
- [net-next,v3,10/10] net: freescale: ucc_geth: phylink conversion
https://git.kernel.org/netdev/net-next/c/53036aa8d031
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 19+ messages in thread