* [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips
@ 2024-08-29 5:51 Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink Raju Lakkaraju
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
This is the follow-up patch series of
https://lkml.iu.edu/hypermail/linux/kernel/2310.2/02078.html
Divide the PHYLINK adaptation and SFP modifications into two separate patch
series.
The current patch series focuses on transitioning the LAN743x driver's PHY
support from phylib to phylink.
Tested on PCI11010 Rev-1 Evaluation board
Change List:
============
V3 -> V4:
- Add fixed-link patch along with this series.
Note: Note: This code was developed by Mr.Russell King
Ref:
https://lore.kernel.org/netdev/LV8PR11MB8700C786F5F1C274C73036CC9F8E2@LV8PR11MB8700.namprd11.prod.outlook.com/T/#me943adf54f1ea082edf294aba448fa003a116815
- Change phylink fixed-link function header's string from "Returns" to
"Returns:"
- Remove the EEE private variable from LAN743x adapter strcture and fix the
EEE's set/get functions
- set the individual caps (i.e. _RGMII, _RGMII_ID, _RGMII_RXID and
__RGMII_TXID) replace with phy_interface_set_rgmii( ) function
- Change lan743x_set_eee( ) to lan743x_mac_eee_enable( )
V2 -> V3:
- Remove the unwanted parens in each of these if() sub-blocks
- Replace "to_net_dev(config->dev)" with "netdev".
- Add GMII_ID/RGMII_TXID/RGMII_RXID in supported_interfaces
- Fix the lan743x_phy_handle_exists( ) return type
V1 -> V2:
- Fix the Russell King's comments i.e. remove the speed, duplex update in
lan743x_phylink_mac_config( )
- pre-March 2020 legacy support has been removed
V0 -> V1:
- Integrate with Synopsys DesignWare XPCS drivers
- Based on external review comments,
- Changes made to SGMII interface support only 1G/100M/10M bps speed
- Changes made to 2500Base-X interface support only 2.5Gbps speed
- Add check for not is_sgmii_en with is_sfp_support_en support
- Change the "pci11x1x_strap_get_status" function return type from void to
int
- Add ethtool phylink wol, eee, pause get/set functions
Raju Lakkaraju (5):
net: phylink: Add phylink_set_fixed_link() to configure fixed link
state in phylink
net: lan743x: Create separate PCS power reset function
net: lan743x: Create separate Link Speed Duplex state function
net: lan743x: Migrate phylib to phylink
net: lan743x: Add support to ethtool phylink get and set settings
drivers/net/ethernet/microchip/Kconfig | 5 +-
.../net/ethernet/microchip/lan743x_ethtool.c | 117 +--
drivers/net/ethernet/microchip/lan743x_main.c | 677 +++++++++++-------
drivers/net/ethernet/microchip/lan743x_main.h | 4 +
drivers/net/phy/phylink.c | 42 ++
include/linux/phylink.h | 2 +
6 files changed, 523 insertions(+), 324 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
@ 2024-08-29 5:51 ` Raju Lakkaraju
2024-08-30 20:37 ` Andrew Lunn
2024-08-29 5:51 ` [PATCH net-next V4 2/5] net: lan743x: Create separate PCS power reset function Raju Lakkaraju
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
From: Russell King <linux@armlinux.org.uk>
The function allows for the configuration of a fixed link state for a given
phylink instance. This addition is particularly useful for network devices that
operate with a fixed link configuration, where the link parameters do not change
dynamically. By using `phylink_set_fixed_link()`, drivers can easily set up
the fixed link state during initialization or configuration changes.
Signed-off-by: Russell King <linux@armlinux.org.uk>
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
---
Change List:
============
V0 -> V1:
- Change phylink fixed-link function header's string from "Returns" to
"Returns:"
- Add fixed-link patch along with this series.
Note: Note: This code was developed by Mr.Russell King
Ref:
https://lore.kernel.org/netdev/LV8PR11MB8700C786F5F1C274C73036CC9F8E2@LV8PR11MB8700.namprd11.prod.outlook.com/T/#me943adf54f1ea082edf294aba448fa003a116815
drivers/net/phy/phylink.c | 42 +++++++++++++++++++++++++++++++++++++++
include/linux/phylink.h | 2 ++
2 files changed, 44 insertions(+)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index ab4e9fc03017..4309317de3d1 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1635,6 +1635,48 @@ static int phylink_register_sfp(struct phylink *pl,
return ret;
}
+/**
+ * phylink_set_fixed_link() - set the fixed link
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @state: a pointer to a struct phylink_link_state.
+ *
+ * This function is used when the link parameters are known and do not change,
+ * making it suitable for certain types of network connections.
+ *
+ * Returns: zero on success or negative error code.
+ */
+int phylink_set_fixed_link(struct phylink *pl,
+ const struct phylink_link_state *state)
+{
+ const struct phy_setting *s;
+ unsigned long *adv;
+
+ if (pl->cfg_link_an_mode != MLO_AN_PHY || !state ||
+ !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
+ return -EINVAL;
+
+ s = phy_lookup_setting(state->speed, state->duplex,
+ pl->supported, true);
+ if (!s)
+ return -EINVAL;
+
+ adv = pl->link_config.advertising;
+ linkmode_zero(adv);
+ linkmode_set_bit(s->bit, adv);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv);
+
+ pl->link_config.speed = state->speed;
+ pl->link_config.duplex = state->duplex;
+ pl->link_config.link = 1;
+ pl->link_config.an_complete = 1;
+
+ pl->cfg_link_an_mode = MLO_AN_FIXED;
+ pl->cur_link_an_mode = pl->cfg_link_an_mode;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(phylink_set_fixed_link);
+
/**
* phylink_create() - create a phylink instance
* @config: a pointer to the target &struct phylink_config
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 2381e07429a2..5c01048860c4 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -598,6 +598,8 @@ int phylink_fwnode_phy_connect(struct phylink *pl,
const struct fwnode_handle *fwnode,
u32 flags);
void phylink_disconnect_phy(struct phylink *);
+int phylink_set_fixed_link(struct phylink *,
+ const struct phylink_link_state *);
void phylink_mac_change(struct phylink *, bool up);
void phylink_pcs_change(struct phylink_pcs *, bool up);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next V4 2/5] net: lan743x: Create separate PCS power reset function
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink Raju Lakkaraju
@ 2024-08-29 5:51 ` Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 3/5] net: lan743x: Create separate Link Speed Duplex state function Raju Lakkaraju
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
Create separate PCS power reset function from lan743x_sgmii_config () to use
as subroutine.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
---
Change List:
============
V3 -> V4:
- No change
V2 -> V3:
- No change
V1 -> V2:
- No change
drivers/net/ethernet/microchip/lan743x_main.c | 55 ++++++++++---------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index e418539565b1..ce1e104adc20 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -1147,12 +1147,39 @@ static int lan743x_pcs_seq_state(struct lan743x_adapter *adapter, u8 state)
return 0;
}
+static int lan743x_pcs_power_reset(struct lan743x_adapter *adapter)
+{
+ int mii_ctl;
+ int ret;
+
+ /* SGMII/1000/2500BASE-X PCS power down */
+ mii_ctl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2, MII_BMCR);
+ if (mii_ctl < 0)
+ return mii_ctl;
+
+ mii_ctl |= BMCR_PDOWN;
+ ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
+ if (ret < 0)
+ return ret;
+
+ ret = lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_DOWN);
+ if (ret < 0)
+ return ret;
+
+ /* SGMII/1000/2500BASE-X PCS power up */
+ mii_ctl &= ~BMCR_PDOWN;
+ ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
+ if (ret < 0)
+ return ret;
+
+ return lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_UP);
+}
+
static int lan743x_sgmii_config(struct lan743x_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct phy_device *phydev = netdev->phydev;
enum lan743x_sgmii_lsd lsd = POWER_DOWN;
- int mii_ctl;
bool status;
int ret;
@@ -1209,31 +1236,7 @@ static int lan743x_sgmii_config(struct lan743x_adapter *adapter)
netif_dbg(adapter, drv, adapter->netdev,
"SGMII 1G mode enable\n");
- /* SGMII/1000/2500BASE-X PCS power down */
- mii_ctl = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2, MII_BMCR);
- if (mii_ctl < 0)
- return mii_ctl;
-
- mii_ctl |= BMCR_PDOWN;
- ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
- if (ret < 0)
- return ret;
-
- ret = lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_DOWN);
- if (ret < 0)
- return ret;
-
- /* SGMII/1000/2500BASE-X PCS power up */
- mii_ctl &= ~BMCR_PDOWN;
- ret = lan743x_sgmii_write(adapter, MDIO_MMD_VEND2, MII_BMCR, mii_ctl);
- if (ret < 0)
- return ret;
-
- ret = lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_UP);
- if (ret < 0)
- return ret;
-
- return 0;
+ return lan743x_pcs_power_reset(adapter);
}
static void lan743x_mac_set_address(struct lan743x_adapter *adapter,
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next V4 3/5] net: lan743x: Create separate Link Speed Duplex state function
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 2/5] net: lan743x: Create separate PCS power reset function Raju Lakkaraju
@ 2024-08-29 5:51 ` Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings Raju Lakkaraju
4 siblings, 0 replies; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
Create separate Link Speed Duplex (LSD) update state function from
lan743x_sgmii_config () to use as subroutine.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
---
Change List:
============
V3 -> V4:
- No change
V2 -> V3:
- No change
V1 -> V2:
- No change
drivers/net/ethernet/microchip/lan743x_main.c | 75 +++++++++++--------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index ce1e104adc20..b4a4c2840a83 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -992,6 +992,42 @@ static int lan743x_sgmii_write(struct lan743x_adapter *adapter,
return ret;
}
+static int lan743x_get_lsd(int speed, int duplex, u8 mss)
+{
+ int lsd;
+
+ switch (speed) {
+ case SPEED_2500:
+ if (mss == MASTER_SLAVE_STATE_SLAVE)
+ lsd = LINK_2500_SLAVE;
+ else
+ lsd = LINK_2500_MASTER;
+ break;
+ case SPEED_1000:
+ if (mss == MASTER_SLAVE_STATE_SLAVE)
+ lsd = LINK_1000_SLAVE;
+ else
+ lsd = LINK_1000_MASTER;
+ break;
+ case SPEED_100:
+ if (duplex == DUPLEX_FULL)
+ lsd = LINK_100FD;
+ else
+ lsd = LINK_100HD;
+ break;
+ case SPEED_10:
+ if (duplex == DUPLEX_FULL)
+ lsd = LINK_10FD;
+ else
+ lsd = LINK_10HD;
+ break;
+ default:
+ lsd = -EINVAL;
+ }
+
+ return lsd;
+}
+
static int lan743x_sgmii_mpll_set(struct lan743x_adapter *adapter,
u16 baud)
{
@@ -1179,42 +1215,21 @@ static int lan743x_sgmii_config(struct lan743x_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct phy_device *phydev = netdev->phydev;
- enum lan743x_sgmii_lsd lsd = POWER_DOWN;
bool status;
int ret;
- switch (phydev->speed) {
- case SPEED_2500:
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_MASTER)
- lsd = LINK_2500_MASTER;
- else
- lsd = LINK_2500_SLAVE;
- break;
- case SPEED_1000:
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_MASTER)
- lsd = LINK_1000_MASTER;
- else
- lsd = LINK_1000_SLAVE;
- break;
- case SPEED_100:
- if (phydev->duplex)
- lsd = LINK_100FD;
- else
- lsd = LINK_100HD;
- break;
- case SPEED_10:
- if (phydev->duplex)
- lsd = LINK_10FD;
- else
- lsd = LINK_10HD;
- break;
- default:
+ ret = lan743x_get_lsd(phydev->speed, phydev->duplex,
+ phydev->master_slave_state);
+ if (ret < 0) {
netif_err(adapter, drv, adapter->netdev,
- "Invalid speed %d\n", phydev->speed);
- return -EINVAL;
+ "error %d link-speed-duplex(LSD) invalid\n", ret);
+ return ret;
}
- adapter->sgmii_lsd = lsd;
+ adapter->sgmii_lsd = ret;
+ netif_dbg(adapter, drv, adapter->netdev,
+ "Link Speed Duplex (lsd) : 0x%X\n", adapter->sgmii_lsd);
+
ret = lan743x_sgmii_aneg_update(adapter);
if (ret < 0) {
netif_err(adapter, drv, adapter->netdev,
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
` (2 preceding siblings ...)
2024-08-29 5:51 ` [PATCH net-next V4 3/5] net: lan743x: Create separate Link Speed Duplex state function Raju Lakkaraju
@ 2024-08-29 5:51 ` Raju Lakkaraju
2024-08-29 7:49 ` Maxime Chevallier
2024-08-29 5:51 ` [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings Raju Lakkaraju
4 siblings, 1 reply; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
Migrate phy support from phylib to phylink.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
---
Change List:
============
V3 -> V4:
- Add the Fixed-link by include the Russell King patch
- Change lan743x_phylink_create( ) argument from netdev to adapter
V2 -> V3:
- Remove the unwanted parens in each of these if() sub-blocks
- Replace "to_net_dev(config->dev)" with "netdev".
- Add GMII_ID/RGMII_TXID/RGMII_RXID in supported_interfaces
- Fix the lan743x_phy_handle_exists( ) return type
V1 -> V2:
- Split the PHYLINK and SFP changes in 2 different patch series
drivers/net/ethernet/microchip/Kconfig | 5 +-
drivers/net/ethernet/microchip/lan743x_main.c | 599 +++++++++++-------
drivers/net/ethernet/microchip/lan743x_main.h | 3 +
3 files changed, 382 insertions(+), 225 deletions(-)
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 43ba71e82260..4b7a0433b7e5 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -46,12 +46,13 @@ config LAN743X
tristate "LAN743x support"
depends on PCI
depends on PTP_1588_CLOCK_OPTIONAL
- select PHYLIB
select FIXED_PHY
select CRC16
select CRC32
+ select PHYLINK
help
- Support for the Microchip LAN743x PCI Express Gigabit Ethernet chip
+ Support for the Microchip LAN743x and PCI11x1x families of PCI
+ Express Ethernet devices
To compile this driver as a module, choose M here. The module will be
called lan743x.
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index b4a4c2840a83..91e74e231251 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -15,6 +15,7 @@
#include <linux/rtnetlink.h>
#include <linux/iopoll.h>
#include <linux/crc16.h>
+#include <linux/phylink.h>
#include "lan743x_main.h"
#include "lan743x_ethtool.h"
@@ -1077,26 +1078,7 @@ static int lan743x_sgmii_2_5G_mode_set(struct lan743x_adapter *adapter,
VR_MII_BAUD_RATE_1P25GBPS);
}
-static int lan743x_is_sgmii_2_5G_mode(struct lan743x_adapter *adapter,
- bool *status)
-{
- int ret;
-
- ret = lan743x_sgmii_read(adapter, MDIO_MMD_VEND2,
- VR_MII_GEN2_4_MPLL_CTRL1);
- if (ret < 0)
- return ret;
-
- if (ret == VR_MII_MPLL_MULTIPLIER_125 ||
- ret == VR_MII_MPLL_MULTIPLIER_50)
- *status = true;
- else
- *status = false;
-
- return 0;
-}
-
-static int lan743x_sgmii_aneg_update(struct lan743x_adapter *adapter)
+static int lan743x_serdes_clock_and_aneg_update(struct lan743x_adapter *adapter)
{
enum lan743x_sgmii_lsd lsd = adapter->sgmii_lsd;
int mii_ctrl;
@@ -1211,49 +1193,6 @@ static int lan743x_pcs_power_reset(struct lan743x_adapter *adapter)
return lan743x_pcs_seq_state(adapter, PCS_POWER_STATE_UP);
}
-static int lan743x_sgmii_config(struct lan743x_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct phy_device *phydev = netdev->phydev;
- bool status;
- int ret;
-
- ret = lan743x_get_lsd(phydev->speed, phydev->duplex,
- phydev->master_slave_state);
- if (ret < 0) {
- netif_err(adapter, drv, adapter->netdev,
- "error %d link-speed-duplex(LSD) invalid\n", ret);
- return ret;
- }
-
- adapter->sgmii_lsd = ret;
- netif_dbg(adapter, drv, adapter->netdev,
- "Link Speed Duplex (lsd) : 0x%X\n", adapter->sgmii_lsd);
-
- ret = lan743x_sgmii_aneg_update(adapter);
- if (ret < 0) {
- netif_err(adapter, drv, adapter->netdev,
- "error %d SGMII cfg failed\n", ret);
- return ret;
- }
-
- ret = lan743x_is_sgmii_2_5G_mode(adapter, &status);
- if (ret < 0) {
- netif_err(adapter, drv, adapter->netdev,
- "error %d SGMII get mode failed\n", ret);
- return ret;
- }
-
- if (status)
- netif_dbg(adapter, drv, adapter->netdev,
- "SGMII 2.5G mode enable\n");
- else
- netif_dbg(adapter, drv, adapter->netdev,
- "SGMII 1G mode enable\n");
-
- return lan743x_pcs_power_reset(adapter);
-}
-
static void lan743x_mac_set_address(struct lan743x_adapter *adapter,
u8 *addr)
{
@@ -1407,103 +1346,11 @@ static int lan743x_phy_reset(struct lan743x_adapter *adapter)
50000, 1000000);
}
-static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter,
- u16 local_adv, u16 remote_adv)
-{
- struct lan743x_phy *phy = &adapter->phy;
- u8 cap;
-
- if (phy->fc_autoneg)
- cap = mii_resolve_flowctrl_fdx(local_adv, remote_adv);
- else
- cap = phy->fc_request_control;
-
- lan743x_mac_flow_ctrl_set_enables(adapter,
- cap & FLOW_CTRL_TX,
- cap & FLOW_CTRL_RX);
-}
-
static int lan743x_phy_init(struct lan743x_adapter *adapter)
{
return lan743x_phy_reset(adapter);
}
-static void lan743x_phy_link_status_change(struct net_device *netdev)
-{
- struct lan743x_adapter *adapter = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
- u32 data;
-
- phy_print_status(phydev);
- if (phydev->state == PHY_RUNNING) {
- int remote_advertisement = 0;
- int local_advertisement = 0;
-
- data = lan743x_csr_read(adapter, MAC_CR);
-
- /* set duplex mode */
- if (phydev->duplex)
- data |= MAC_CR_DPX_;
- else
- data &= ~MAC_CR_DPX_;
-
- /* set bus speed */
- switch (phydev->speed) {
- case SPEED_10:
- data &= ~MAC_CR_CFG_H_;
- data &= ~MAC_CR_CFG_L_;
- break;
- case SPEED_100:
- data &= ~MAC_CR_CFG_H_;
- data |= MAC_CR_CFG_L_;
- break;
- case SPEED_1000:
- data |= MAC_CR_CFG_H_;
- data &= ~MAC_CR_CFG_L_;
- break;
- case SPEED_2500:
- data |= MAC_CR_CFG_H_;
- data |= MAC_CR_CFG_L_;
- break;
- }
- lan743x_csr_write(adapter, MAC_CR, data);
-
- local_advertisement =
- linkmode_adv_to_mii_adv_t(phydev->advertising);
- remote_advertisement =
- linkmode_adv_to_mii_adv_t(phydev->lp_advertising);
-
- lan743x_phy_update_flowcontrol(adapter, local_advertisement,
- remote_advertisement);
- lan743x_ptp_update_latency(adapter, phydev->speed);
- if (phydev->interface == PHY_INTERFACE_MODE_SGMII ||
- phydev->interface == PHY_INTERFACE_MODE_1000BASEX ||
- phydev->interface == PHY_INTERFACE_MODE_2500BASEX)
- lan743x_sgmii_config(adapter);
-
- data = lan743x_csr_read(adapter, MAC_CR);
- if (phydev->enable_tx_lpi)
- data |= MAC_CR_EEE_EN_;
- else
- data &= ~MAC_CR_EEE_EN_;
- lan743x_csr_write(adapter, MAC_CR, data);
- }
-}
-
-static void lan743x_phy_close(struct lan743x_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct phy_device *phydev = netdev->phydev;
-
- phy_stop(netdev->phydev);
- phy_disconnect(netdev->phydev);
-
- /* using phydev here as phy_disconnect NULLs netdev->phydev */
- if (phy_is_pseudo_fixed_link(phydev))
- fixed_phy_unregister(phydev);
-
-}
-
static void lan743x_phy_interface_select(struct lan743x_adapter *adapter)
{
u32 id_rev;
@@ -1520,65 +1367,9 @@ static void lan743x_phy_interface_select(struct lan743x_adapter *adapter)
adapter->phy_interface = PHY_INTERFACE_MODE_MII;
else
adapter->phy_interface = PHY_INTERFACE_MODE_RGMII;
-}
-
-static int lan743x_phy_open(struct lan743x_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct lan743x_phy *phy = &adapter->phy;
- struct fixed_phy_status fphy_status = {
- .link = 1,
- .speed = SPEED_1000,
- .duplex = DUPLEX_FULL,
- };
- struct phy_device *phydev;
- int ret = -EIO;
-
- /* try devicetree phy, or fixed link */
- phydev = of_phy_get_and_connect(netdev, adapter->pdev->dev.of_node,
- lan743x_phy_link_status_change);
-
- if (!phydev) {
- /* try internal phy */
- phydev = phy_find_first(adapter->mdiobus);
- if (!phydev) {
- if ((adapter->csr.id_rev & ID_REV_ID_MASK_) ==
- ID_REV_ID_LAN7431_) {
- phydev = fixed_phy_register(PHY_POLL,
- &fphy_status, NULL);
- if (IS_ERR(phydev)) {
- netdev_err(netdev, "No PHY/fixed_PHY found\n");
- return PTR_ERR(phydev);
- }
- } else {
- goto return_error;
- }
- }
- lan743x_phy_interface_select(adapter);
-
- ret = phy_connect_direct(netdev, phydev,
- lan743x_phy_link_status_change,
- adapter->phy_interface);
- if (ret)
- goto return_error;
- }
-
- /* MAC doesn't support 1000T Half */
- phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
-
- /* support both flow controls */
- phy_support_asym_pause(phydev);
- phy->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX);
- phy->fc_autoneg = phydev->autoneg;
-
- phy_start(phydev);
- phy_start_aneg(phydev);
- phy_attached_info(phydev);
- return 0;
-
-return_error:
- return ret;
+ netif_dbg(adapter, drv, adapter->netdev,
+ "selected phy interface: 0x%X\n", adapter->phy_interface);
}
static void lan743x_rfe_open(struct lan743x_adapter *adapter)
@@ -3079,6 +2870,350 @@ static int lan743x_rx_open(struct lan743x_rx *rx)
return ret;
}
+static int lan743x_phylink_sgmii_config(struct lan743x_adapter *adapter)
+{
+ u32 sgmii_ctl;
+ int ret;
+
+ ret = lan743x_get_lsd(SPEED_1000, DUPLEX_FULL,
+ MASTER_SLAVE_STATE_MASTER);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d link-speed-duplex(LSD) invalid\n", ret);
+ return ret;
+ }
+
+ adapter->sgmii_lsd = ret;
+ netif_dbg(adapter, drv, adapter->netdev,
+ "Link Speed Duplex (lsd) : 0x%X\n", adapter->sgmii_lsd);
+
+ /* LINK_STATUS_SOURCE from the External PHY via SGMII */
+ sgmii_ctl = lan743x_csr_read(adapter, SGMII_CTL);
+ sgmii_ctl &= ~SGMII_CTL_LINK_STATUS_SOURCE_;
+ lan743x_csr_write(adapter, SGMII_CTL, sgmii_ctl);
+
+ ret = lan743x_serdes_clock_and_aneg_update(adapter);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d sgmii aneg update failed\n", ret);
+ return ret;
+ }
+
+ return lan743x_pcs_power_reset(adapter);
+}
+
+static int lan743x_phylink_1000basex_config(struct lan743x_adapter *adapter)
+{
+ u32 sgmii_ctl;
+ int ret;
+
+ ret = lan743x_get_lsd(SPEED_1000, DUPLEX_FULL,
+ MASTER_SLAVE_STATE_MASTER);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d link-speed-duplex(LSD) invalid\n", ret);
+ return ret;
+ }
+
+ adapter->sgmii_lsd = ret;
+ netif_dbg(adapter, drv, adapter->netdev,
+ "Link Speed Duplex (lsd) : 0x%X\n", adapter->sgmii_lsd);
+
+ /* LINK_STATUS_SOURCE from 1000BASE-X PCS link status */
+ sgmii_ctl = lan743x_csr_read(adapter, SGMII_CTL);
+ sgmii_ctl |= SGMII_CTL_LINK_STATUS_SOURCE_;
+ lan743x_csr_write(adapter, SGMII_CTL, sgmii_ctl);
+
+ ret = lan743x_serdes_clock_and_aneg_update(adapter);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d 1000basex aneg update failed\n", ret);
+ return ret;
+ }
+
+ return lan743x_pcs_power_reset(adapter);
+}
+
+static int lan743x_phylink_2500basex_config(struct lan743x_adapter *adapter)
+{
+ u32 sgmii_ctl;
+ int ret;
+
+ ret = lan743x_get_lsd(SPEED_2500, DUPLEX_FULL,
+ MASTER_SLAVE_STATE_MASTER);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d link-speed-duplex(LSD) invalid\n", ret);
+ return ret;
+ }
+
+ adapter->sgmii_lsd = ret;
+ netif_dbg(adapter, drv, adapter->netdev,
+ "Link Speed Duplex (lsd) : 0x%X\n", adapter->sgmii_lsd);
+
+ /* LINK_STATUS_SOURCE from 2500BASE-X PCS link status */
+ sgmii_ctl = lan743x_csr_read(adapter, SGMII_CTL);
+ sgmii_ctl |= SGMII_CTL_LINK_STATUS_SOURCE_;
+ lan743x_csr_write(adapter, SGMII_CTL, sgmii_ctl);
+
+ ret = lan743x_serdes_clock_and_aneg_update(adapter);
+ if (ret < 0) {
+ netif_err(adapter, drv, adapter->netdev,
+ "error %d 2500basex aneg update failed\n", ret);
+ return ret;
+ }
+
+ return lan743x_pcs_power_reset(adapter);
+}
+
+static void lan743x_phylink_mac_config(struct phylink_config *config,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state)
+{
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+ int ret;
+
+ switch (state->interface) {
+ case PHY_INTERFACE_MODE_2500BASEX:
+ ret = lan743x_phylink_2500basex_config(adapter);
+ if (ret < 0)
+ netif_err(adapter, drv, adapter->netdev,
+ "2500BASEX config failed. Error %d\n", ret);
+ else
+ netif_dbg(adapter, drv, adapter->netdev,
+ "2500BASEX mode selected and configured\n");
+ break;
+ case PHY_INTERFACE_MODE_1000BASEX:
+ ret = lan743x_phylink_1000basex_config(adapter);
+ if (ret < 0)
+ netif_err(adapter, drv, adapter->netdev,
+ "1000BASEX config failed. Error %d\n", ret);
+ else
+ netif_dbg(adapter, drv, adapter->netdev,
+ "1000BASEX mode selected and configured\n");
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ ret = lan743x_phylink_sgmii_config(adapter);
+ if (ret < 0)
+ netif_err(adapter, drv, adapter->netdev,
+ "SGMII config failed. Error %d\n", ret);
+ else
+ netif_dbg(adapter, drv, adapter->netdev,
+ "SGMII mode selected and configured\n");
+ break;
+ default:
+ netif_dbg(adapter, drv, adapter->netdev,
+ "RGMII/GMII/MII(0x%X) mode enable\n", state->interface);
+ break;
+ }
+}
+
+static void lan743x_phylink_mac_link_down(struct phylink_config *config,
+ unsigned int link_an_mode,
+ phy_interface_t interface)
+{
+ netif_tx_stop_all_queues(to_net_dev(config->dev));
+}
+
+static void lan743x_phylink_mac_link_up(struct phylink_config *config,
+ struct phy_device *phydev,
+ unsigned int link_an_mode,
+ phy_interface_t interface,
+ int speed, int duplex,
+ bool tx_pause, bool rx_pause)
+{
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+ int mac_cr;
+ u8 cap;
+
+ mac_cr = lan743x_csr_read(adapter, MAC_CR);
+ /* Pre-initialize register bits.
+ * Resulting value corresponds to SPEED_10
+ */
+ mac_cr &= ~(MAC_CR_CFG_H_ | MAC_CR_CFG_L_);
+ if (speed == SPEED_2500)
+ mac_cr |= MAC_CR_CFG_H_ | MAC_CR_CFG_L_;
+ else if (speed == SPEED_1000)
+ mac_cr |= MAC_CR_CFG_H_;
+ else if (speed == SPEED_100)
+ mac_cr |= MAC_CR_CFG_L_;
+
+ lan743x_csr_write(adapter, MAC_CR, mac_cr);
+
+ lan743x_ptp_update_latency(adapter, speed);
+
+ /* Flow Control operation */
+ cap = 0;
+ if (tx_pause)
+ cap |= FLOW_CTRL_TX;
+ if (rx_pause)
+ cap |= FLOW_CTRL_RX;
+
+ lan743x_mac_flow_ctrl_set_enables(adapter,
+ cap & FLOW_CTRL_TX,
+ cap & FLOW_CTRL_RX);
+
+ netif_tx_wake_all_queues(netdev);
+}
+
+static const struct phylink_mac_ops lan743x_phylink_mac_ops = {
+ .mac_config = lan743x_phylink_mac_config,
+ .mac_link_down = lan743x_phylink_mac_link_down,
+ .mac_link_up = lan743x_phylink_mac_link_up,
+};
+
+static struct {
+ unsigned long mask;
+ int speed;
+ int duplex;
+} lan743x_mac_caps_params[] = {
+ { MAC_2500FD, SPEED_2500, DUPLEX_FULL },
+ { MAC_1000FD, SPEED_1000, DUPLEX_FULL },
+ { MAC_100FD, SPEED_100, DUPLEX_FULL },
+ { MAC_10FD, SPEED_10, DUPLEX_FULL },
+ { MAC_100HD, SPEED_100, DUPLEX_HALF },
+ { MAC_10HD, SPEED_10, DUPLEX_HALF },
+};
+
+static int lan743x_find_max_speed(unsigned long caps, int *speed, int *duplex)
+{
+ int i;
+
+ *speed = SPEED_UNKNOWN;
+ *duplex = DUPLEX_UNKNOWN;
+ for (i = 0; i < ARRAY_SIZE(lan743x_mac_caps_params); i++) {
+ if (caps & lan743x_mac_caps_params[i].mask) {
+ *speed = lan743x_mac_caps_params[i].speed;
+ *duplex = lan743x_mac_caps_params[i].duplex;
+ break;
+ }
+ }
+
+ return *speed == SPEED_UNKNOWN ? -EINVAL : 0;
+}
+
+static int lan743x_phylink_create(struct lan743x_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct phylink *pl;
+
+ adapter->phylink_config.dev = &netdev->dev;
+ adapter->phylink_config.type = PHYLINK_NETDEV;
+ adapter->phylink_config.mac_managed_pm = false;
+
+ adapter->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
+ MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD;
+
+ lan743x_phy_interface_select(adapter);
+
+ switch (adapter->phy_interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
+ adapter->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
+ adapter->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
+ adapter->phylink_config.supported_interfaces);
+ adapter->phylink_config.mac_capabilities |= MAC_2500FD;
+ break;
+ case PHY_INTERFACE_MODE_GMII:
+ __set_bit(PHY_INTERFACE_MODE_GMII,
+ adapter->phylink_config.supported_interfaces);
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ __set_bit(PHY_INTERFACE_MODE_MII,
+ adapter->phylink_config.supported_interfaces);
+ break;
+ default:
+ phy_interface_set_rgmii(adapter->phylink_config.supported_interfaces);
+ }
+
+ pl = phylink_create(&adapter->phylink_config, NULL,
+ adapter->phy_interface, &lan743x_phylink_mac_ops);
+
+ if (IS_ERR(pl)) {
+ netdev_err(netdev, "Could not create phylink (%pe)\n", pl);
+ return PTR_ERR(pl);
+ }
+
+ adapter->phylink = pl;
+ netdev_dbg(netdev, "lan743x phylink created");
+
+ return 0;
+}
+
+static bool lan743x_phy_handle_exists(struct device_node *dn)
+{
+ dn = of_parse_phandle(dn, "phy-handle", 0);
+ of_node_put(dn);
+ return dn != NULL;
+}
+
+static int lan743x_phylink_connect(struct lan743x_adapter *adapter)
+{
+ struct device_node *dn = adapter->pdev->dev.of_node;
+ struct net_device *dev = adapter->netdev;
+ struct phy_device *phydev;
+ int ret;
+
+ if (dn)
+ ret = phylink_of_phy_connect(adapter->phylink, dn, 0);
+
+ if (!dn || (ret && !lan743x_phy_handle_exists(dn))) {
+ phydev = phy_find_first(adapter->mdiobus);
+ if (phydev) {
+ /* attach the mac to the phy */
+ ret = phylink_connect_phy(adapter->phylink, phydev);
+ } else if (((adapter->csr.id_rev & ID_REV_ID_MASK_) ==
+ ID_REV_ID_LAN7431_) || adapter->is_pci11x1x) {
+ struct phylink_link_state state;
+ unsigned long caps;
+
+ caps = adapter->phylink_config.mac_capabilities;
+ ret = lan743x_find_max_speed(caps, &state.speed,
+ &state.duplex);
+ if (ret) {
+ netdev_err(dev, "find unknown speed (%d)\n",
+ ret);
+ return ret;
+ }
+
+ ret = phylink_set_fixed_link(adapter->phylink, &state);
+ if (ret) {
+ netdev_err(dev, "Could not set fixed link\n");
+ return ret;
+ }
+ } else {
+ netdev_err(dev, "no PHY found\n");
+ return -ENXIO;
+ }
+ }
+
+ if (ret) {
+ netdev_err(dev, "Could not attach PHY (%d)\n", ret);
+ return ret;
+ }
+
+ phylink_start(adapter->phylink);
+
+ return 0;
+}
+
+static void lan743x_phylink_disconnect(struct lan743x_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct phy_device *phydev = netdev->phydev;
+
+ phylink_stop(adapter->phylink);
+ phylink_disconnect_phy(adapter->phylink);
+
+ if (phydev)
+ if (phy_is_pseudo_fixed_link(phydev))
+ fixed_phy_unregister(phydev);
+}
+
static int lan743x_netdev_close(struct net_device *netdev)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
@@ -3092,7 +3227,7 @@ static int lan743x_netdev_close(struct net_device *netdev)
lan743x_ptp_close(adapter);
- lan743x_phy_close(adapter);
+ lan743x_phylink_disconnect(adapter);
lan743x_mac_close(adapter);
@@ -3115,13 +3250,13 @@ static int lan743x_netdev_open(struct net_device *netdev)
if (ret)
goto close_intr;
- ret = lan743x_phy_open(adapter);
+ ret = lan743x_phylink_connect(adapter);
if (ret)
goto close_mac;
ret = lan743x_ptp_open(adapter);
if (ret)
- goto close_phy;
+ goto close_mac;
lan743x_rfe_open(adapter);
@@ -3161,9 +3296,8 @@ static int lan743x_netdev_open(struct net_device *netdev)
lan743x_rx_close(&adapter->rx[index]);
}
lan743x_ptp_close(adapter);
-
-close_phy:
- lan743x_phy_close(adapter);
+ if (adapter->phylink)
+ lan743x_phylink_disconnect(adapter);
close_mac:
lan743x_mac_close(adapter);
@@ -3192,11 +3326,14 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
static int lan743x_netdev_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd)
{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
if (!netif_running(netdev))
return -EINVAL;
if (cmd == SIOCSHWTSTAMP)
return lan743x_ptp_ioctl(netdev, ifr, cmd);
- return phy_mii_ioctl(netdev->phydev, ifr, cmd);
+
+ return phylink_mii_ioctl(adapter->phylink, ifr, cmd);
}
static void lan743x_netdev_set_multicast(struct net_device *netdev)
@@ -3301,10 +3438,17 @@ static void lan743x_mdiobus_cleanup(struct lan743x_adapter *adapter)
mdiobus_unregister(adapter->mdiobus);
}
+static void lan743x_destroy_phylink(struct lan743x_adapter *adapter)
+{
+ phylink_destroy(adapter->phylink);
+ adapter->phylink = NULL;
+}
+
static void lan743x_full_cleanup(struct lan743x_adapter *adapter)
{
unregister_netdev(adapter->netdev);
+ lan743x_destroy_phylink(adapter);
lan743x_mdiobus_cleanup(adapter);
lan743x_hardware_cleanup(adapter);
lan743x_pci_cleanup(adapter);
@@ -3518,14 +3662,21 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
adapter->netdev->hw_features = adapter->netdev->features;
- /* carrier off reporting is important to ethtool even BEFORE open */
- netif_carrier_off(netdev);
+ ret = lan743x_phylink_create(adapter);
+ if (ret < 0) {
+ netif_err(adapter, probe, netdev,
+ "failed to setup phylink (%d)\n", ret);
+ goto cleanup_mdiobus;
+ }
ret = register_netdev(adapter->netdev);
if (ret < 0)
- goto cleanup_mdiobus;
+ goto cleanup_phylink;
return 0;
+cleanup_phylink:
+ lan743x_destroy_phylink(adapter);
+
cleanup_mdiobus:
lan743x_mdiobus_cleanup(adapter);
@@ -3781,6 +3932,7 @@ static int lan743x_pm_resume(struct device *dev)
MAC_WK_SRC_WK_FR_SAVED_;
lan743x_csr_write(adapter, MAC_WK_SRC, data);
+ rtnl_lock();
/* open netdev when netdev is at running state while resume.
* For instance, it is true when system wakesup after pm-suspend
* However, it is false when system wakes up after suspend GUI menu
@@ -3789,6 +3941,7 @@ static int lan743x_pm_resume(struct device *dev)
lan743x_netdev_open(netdev);
netif_device_attach(netdev);
+ rtnl_unlock();
return 0;
}
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 3b2585a384e2..7f73d66854be 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -5,6 +5,7 @@
#define _LAN743X_H
#include <linux/phy.h>
+#include <linux/phylink.h>
#include "lan743x_ptp.h"
#define DRIVER_AUTHOR "Bryan Whitehead <Bryan.Whitehead@microchip.com>"
@@ -1083,6 +1084,8 @@ struct lan743x_adapter {
u32 flags;
u32 hw_cfg;
phy_interface_t phy_interface;
+ struct phylink *phylink;
+ struct phylink_config phylink_config;
};
#define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel))
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
` (3 preceding siblings ...)
2024-08-29 5:51 ` [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink Raju Lakkaraju
@ 2024-08-29 5:51 ` Raju Lakkaraju
2024-08-30 20:55 ` Andrew Lunn
4 siblings, 1 reply; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-29 5:51 UTC (permalink / raw)
To: netdev
Cc: davem, linux, kuba, andrew, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
Add support to ethtool phylink functions:
- get/set settings like speed, duplex etc
- get/set the wake-on-lan (WOL)
- get/set the energy-efficient ethernet (EEE)
- get/set the pause
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
---
Change List:
============
V3 -> V4:
- Remove the EEE private variables from LAN743x adapter strcture and fix the
EEE's set/get functions
- Change lan743x_set_eee( ) to lan743x_mac_eee_enable( )
- Fix the EEE's tx lpi counter update
V2 -> V3:
- No change
V1 -> V2:
- Fix the phylink changes
.../net/ethernet/microchip/lan743x_ethtool.c | 117 ++++++------------
drivers/net/ethernet/microchip/lan743x_main.c | 20 +++
drivers/net/ethernet/microchip/lan743x_main.h | 1 +
3 files changed, 59 insertions(+), 79 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 3a63ec091413..b15b52d53e84 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -1058,61 +1058,49 @@ static int lan743x_ethtool_get_eee(struct net_device *netdev,
struct ethtool_keee *eee)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
- struct phy_device *phydev = netdev->phydev;
- u32 buf;
- int ret;
- if (!phydev)
- return -EIO;
- if (!phydev->drv) {
- netif_err(adapter, drv, adapter->netdev,
- "Missing PHY Driver\n");
- return -EIO;
- }
+ eee->tx_lpi_timer = lan743x_csr_read(adapter,
+ MAC_EEE_TX_LPI_REQ_DLY_CNT);
- ret = phy_ethtool_get_eee(phydev, eee);
- if (ret < 0)
- return ret;
+ return phylink_ethtool_get_eee(adapter->phylink, eee);
+}
- buf = lan743x_csr_read(adapter, MAC_CR);
- if (buf & MAC_CR_EEE_EN_) {
- /* EEE_TX_LPI_REQ_DLY & tx_lpi_timer are same uSec unit */
- buf = lan743x_csr_read(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT);
- eee->tx_lpi_timer = buf;
- } else {
- eee->tx_lpi_timer = 0;
+static int lan743x_ethtool_set_eee(struct net_device *netdev,
+ struct ethtool_keee *eee)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+ u32 tx_lpi_timer;
+
+ tx_lpi_timer = lan743x_csr_read(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT);
+ if (tx_lpi_timer != eee->tx_lpi_timer) {
+ /* Software should only change this field when Energy Efficient
+ * Ethernet Enable (EEEEN) is cleared.
+ * This function will trigger an autonegotiation restart and
+ * that eee will be reenabled during link up if eee was
+ * negotiated.
+ */
+ lan743x_mac_eee_enable(adapter, false);
+ lan743x_csr_write(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT,
+ eee->tx_lpi_timer);
}
- return 0;
+ return phylink_ethtool_set_eee(adapter->phylink, eee);
}
-static int lan743x_ethtool_set_eee(struct net_device *netdev,
- struct ethtool_keee *eee)
+static int lan743x_ethtool_set_link_ksettings(struct net_device *netdev,
+ const struct ethtool_link_ksettings *cmd)
{
- struct lan743x_adapter *adapter;
- struct phy_device *phydev;
- u32 buf = 0;
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
- if (!netdev)
- return -EINVAL;
- adapter = netdev_priv(netdev);
- if (!adapter)
- return -EINVAL;
- phydev = netdev->phydev;
- if (!phydev)
- return -EIO;
- if (!phydev->drv) {
- netif_err(adapter, drv, adapter->netdev,
- "Missing PHY Driver\n");
- return -EIO;
- }
+ return phylink_ethtool_ksettings_set(adapter->phylink, cmd);
+}
- if (eee->eee_enabled) {
- buf = (u32)eee->tx_lpi_timer;
- lan743x_csr_write(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT, buf);
- }
+static int lan743x_ethtool_get_link_ksettings(struct net_device *netdev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
- return phy_ethtool_set_eee(phydev, eee);
+ return phylink_ethtool_ksettings_get(adapter->phylink, cmd);
}
#ifdef CONFIG_PM
@@ -1124,8 +1112,7 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev,
wol->supported = 0;
wol->wolopts = 0;
- if (netdev->phydev)
- phy_ethtool_get_wol(netdev->phydev, wol);
+ phylink_ethtool_get_wol(adapter->phylink, wol);
if (wol->supported != adapter->phy_wol_supported)
netif_warn(adapter, drv, adapter->netdev,
@@ -1166,7 +1153,7 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
!(adapter->phy_wol_supported & WAKE_MAGICSECURE))
phy_wol.wolopts &= ~WAKE_MAGIC;
- ret = phy_ethtool_set_wol(netdev->phydev, &phy_wol);
+ ret = phylink_ethtool_set_wol(adapter->phylink, wol);
if (ret && (ret != -EOPNOTSUPP))
return ret;
@@ -1355,44 +1342,16 @@ static void lan743x_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *pause)
{
struct lan743x_adapter *adapter = netdev_priv(dev);
- struct lan743x_phy *phy = &adapter->phy;
- if (phy->fc_request_control & FLOW_CTRL_TX)
- pause->tx_pause = 1;
- if (phy->fc_request_control & FLOW_CTRL_RX)
- pause->rx_pause = 1;
- pause->autoneg = phy->fc_autoneg;
+ phylink_ethtool_get_pauseparam(adapter->phylink, pause);
}
static int lan743x_set_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *pause)
{
struct lan743x_adapter *adapter = netdev_priv(dev);
- struct phy_device *phydev = dev->phydev;
- struct lan743x_phy *phy = &adapter->phy;
- if (!phydev)
- return -ENODEV;
-
- if (!phy_validate_pause(phydev, pause))
- return -EINVAL;
-
- phy->fc_request_control = 0;
- if (pause->rx_pause)
- phy->fc_request_control |= FLOW_CTRL_RX;
-
- if (pause->tx_pause)
- phy->fc_request_control |= FLOW_CTRL_TX;
-
- phy->fc_autoneg = pause->autoneg;
-
- if (pause->autoneg == AUTONEG_DISABLE)
- lan743x_mac_flow_ctrl_set_enables(adapter, pause->tx_pause,
- pause->rx_pause);
- else
- phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause);
-
- return 0;
+ return phylink_ethtool_set_pauseparam(adapter->phylink, pause);
}
const struct ethtool_ops lan743x_ethtool_ops = {
@@ -1417,8 +1376,8 @@ const struct ethtool_ops lan743x_ethtool_ops = {
.get_ts_info = lan743x_ethtool_get_ts_info,
.get_eee = lan743x_ethtool_get_eee,
.set_eee = lan743x_ethtool_set_eee,
- .get_link_ksettings = phy_ethtool_get_link_ksettings,
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .get_link_ksettings = lan743x_ethtool_get_link_ksettings,
+ .set_link_ksettings = lan743x_ethtool_set_link_ksettings,
.get_regs_len = lan743x_get_regs_len,
.get_regs = lan743x_get_regs,
.get_pauseparam = lan743x_get_pauseparam,
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 91e74e231251..9c18e025a28d 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -2966,6 +2966,18 @@ static int lan743x_phylink_2500basex_config(struct lan743x_adapter *adapter)
return lan743x_pcs_power_reset(adapter);
}
+void lan743x_mac_eee_enable(struct lan743x_adapter *adapter, bool enable)
+{
+ u32 mac_cr;
+
+ mac_cr = lan743x_csr_read(adapter, MAC_CR);
+ if (enable)
+ mac_cr |= MAC_CR_EEE_EN_;
+ else
+ mac_cr &= ~MAC_CR_EEE_EN_;
+ lan743x_csr_write(adapter, MAC_CR, mac_cr);
+}
+
static void lan743x_phylink_mac_config(struct phylink_config *config,
unsigned int link_an_mode,
const struct phylink_link_state *state)
@@ -3013,7 +3025,11 @@ static void lan743x_phylink_mac_link_down(struct phylink_config *config,
unsigned int link_an_mode,
phy_interface_t interface)
{
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
netif_tx_stop_all_queues(to_net_dev(config->dev));
+ lan743x_mac_eee_enable(adapter, false);
}
static void lan743x_phylink_mac_link_up(struct phylink_config *config,
@@ -3055,6 +3071,10 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
cap & FLOW_CTRL_TX,
cap & FLOW_CTRL_RX);
+ if (phydev)
+ lan743x_mac_eee_enable(adapter, phydev->enable_tx_lpi &&
+ phydev->eee_enabled);
+
netif_tx_wake_all_queues(netdev);
}
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 7f73d66854be..8ef897c114d3 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -1206,5 +1206,6 @@ void lan743x_hs_syslock_release(struct lan743x_adapter *adapter);
void lan743x_mac_flow_ctrl_set_enables(struct lan743x_adapter *adapter,
bool tx_enable, bool rx_enable);
int lan743x_sgmii_read(struct lan743x_adapter *adapter, u8 mmd, u16 addr);
+void lan743x_mac_eee_enable(struct lan743x_adapter *adapter, bool enable);
#endif /* _LAN743X_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink
2024-08-29 5:51 ` [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink Raju Lakkaraju
@ 2024-08-29 7:49 ` Maxime Chevallier
2024-08-30 5:36 ` Raju Lakkaraju
0 siblings, 1 reply; 11+ messages in thread
From: Maxime Chevallier @ 2024-08-29 7:49 UTC (permalink / raw)
To: Raju Lakkaraju
Cc: netdev, davem, linux, kuba, andrew, hkallweit1, richardcochran,
rdunlap, Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
Hello Raju,
On Thu, 29 Aug 2024 11:21:31 +0530
Raju Lakkaraju <Raju.Lakkaraju@microchip.com> wrote:
> Migrate phy support from phylib to phylink.
>
> Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
[...]
> +static void lan743x_phylink_disconnect(struct lan743x_adapter *adapter)
> +{
> + struct net_device *netdev = adapter->netdev;
> + struct phy_device *phydev = netdev->phydev;
> +
> + phylink_stop(adapter->phylink);
> + phylink_disconnect_phy(adapter->phylink);
> +
> + if (phydev)
> + if (phy_is_pseudo_fixed_link(phydev))
> + fixed_phy_unregister(phydev);
You shouldn't manually deal with the fixed_phy when using phylink, it
handles fixed links already for you, without a PHY.
Thanks,
Maxime
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink
2024-08-29 7:49 ` Maxime Chevallier
@ 2024-08-30 5:36 ` Raju Lakkaraju
0 siblings, 0 replies; 11+ messages in thread
From: Raju Lakkaraju @ 2024-08-30 5:36 UTC (permalink / raw)
To: Maxime Chevallier
Cc: Raju Lakkaraju, netdev, davem, linux, kuba, andrew, hkallweit1,
richardcochran, rdunlap, Bryan.Whitehead, edumazet, pabeni,
linux-kernel, horms, UNGLinuxDriver
Hello Maxime,
Thank you for review the patches.
The 08/29/2024 09:49, Maxime Chevallier wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> Hello Raju,
>
> On Thu, 29 Aug 2024 11:21:31 +0530
> Raju Lakkaraju <Raju.Lakkaraju@microchip.com> wrote:
>
> > Migrate phy support from phylib to phylink.
> >
> > Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
>
> [...]
>
> > +static void lan743x_phylink_disconnect(struct lan743x_adapter *adapter)
> > +{
> > + struct net_device *netdev = adapter->netdev;
> > + struct phy_device *phydev = netdev->phydev;
> > +
> > + phylink_stop(adapter->phylink);
> > + phylink_disconnect_phy(adapter->phylink);
> > +
> > + if (phydev)
> > + if (phy_is_pseudo_fixed_link(phydev))
> > + fixed_phy_unregister(phydev);
>
> You shouldn't manually deal with the fixed_phy when using phylink, it
> handles fixed links already for you, without a PHY.
Sure.
I wll remove this fixed_phy unregister here.
>
> Thanks,
>
> Maxime
--
Thanks,
Raju
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink
2024-08-29 5:51 ` [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink Raju Lakkaraju
@ 2024-08-30 20:37 ` Andrew Lunn
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2024-08-30 20:37 UTC (permalink / raw)
To: Raju Lakkaraju
Cc: netdev, davem, linux, kuba, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
On Thu, Aug 29, 2024 at 11:21:28AM +0530, Raju Lakkaraju wrote:
> From: Russell King <linux@armlinux.org.uk>
>
> The function allows for the configuration of a fixed link state for a given
> phylink instance. This addition is particularly useful for network devices that
> operate with a fixed link configuration, where the link parameters do not change
> dynamically. By using `phylink_set_fixed_link()`, drivers can easily set up
> the fixed link state during initialization or configuration changes.
>
> Signed-off-by: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings
2024-08-29 5:51 ` [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings Raju Lakkaraju
@ 2024-08-30 20:55 ` Andrew Lunn
2024-09-04 8:23 ` Raju Lakkaraju
0 siblings, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2024-08-30 20:55 UTC (permalink / raw)
To: Raju Lakkaraju
Cc: netdev, davem, linux, kuba, hkallweit1, richardcochran, rdunlap,
Bryan.Whitehead, edumazet, pabeni, linux-kernel, horms,
UNGLinuxDriver
> @@ -3055,6 +3071,10 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
> cap & FLOW_CTRL_TX,
> cap & FLOW_CTRL_RX);
>
> + if (phydev)
> + lan743x_mac_eee_enable(adapter, phydev->enable_tx_lpi &&
> + phydev->eee_enabled);
This is wrong. The documentation says:
/**
* phy_support_eee - Set initial EEE policy configuration
* @phydev: Target phy_device struct
*
* This function configures the initial policy for Energy Efficient Ethernet
* (EEE) on the specified PHY device, influencing that EEE capabilities are
* advertised before the link is established. It should be called during PHY
* registration by the MAC driver and/or the PHY driver (for SmartEEE PHYs)
* if MAC supports LPI or PHY is capable to compensate missing LPI functionality
* of the MAC.
*
* The function sets default EEE policy parameters, including preparing the PHY
* to advertise EEE capabilities based on hardware support.
*
* It also sets the expected configuration for Low Power Idle (LPI) in the MAC
* driver. If the PHY framework determines that both local and remote
* advertisements support EEE, and the negotiated link mode is compatible with
* EEE, it will set enable_tx_lpi = true. The MAC driver is expected to act on
* this setting by enabling the LPI timer if enable_tx_lpi is set.
*/
So you should only be looking at enable_tx_lpi.
Also, do you actually call phy_support_eee() anywhere? I don't see it
in this patch, but maybe it was already there?
Adrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings
2024-08-30 20:55 ` Andrew Lunn
@ 2024-09-04 8:23 ` Raju Lakkaraju
0 siblings, 0 replies; 11+ messages in thread
From: Raju Lakkaraju @ 2024-09-04 8:23 UTC (permalink / raw)
To: Andrew Lunn
Cc: Raju Lakkaraju, netdev, davem, linux, kuba, hkallweit1,
richardcochran, rdunlap, Bryan.Whitehead, edumazet, pabeni,
linux-kernel, horms, UNGLinuxDriver
Hi Andrew,
Thank you for review the patches.
The 08/30/2024 22:55, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> > @@ -3055,6 +3071,10 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
> > cap & FLOW_CTRL_TX,
> > cap & FLOW_CTRL_RX);
> >
> > + if (phydev)
> > + lan743x_mac_eee_enable(adapter, phydev->enable_tx_lpi &&
> > + phydev->eee_enabled);
>
> This is wrong. The documentation says:
>
> /**
> * phy_support_eee - Set initial EEE policy configuration
> * @phydev: Target phy_device struct
> *
> * This function configures the initial policy for Energy Efficient Ethernet
> * (EEE) on the specified PHY device, influencing that EEE capabilities are
> * advertised before the link is established. It should be called during PHY
> * registration by the MAC driver and/or the PHY driver (for SmartEEE PHYs)
> * if MAC supports LPI or PHY is capable to compensate missing LPI functionality
> * of the MAC.
> *
> * The function sets default EEE policy parameters, including preparing the PHY
> * to advertise EEE capabilities based on hardware support.
> *
> * It also sets the expected configuration for Low Power Idle (LPI) in the MAC
> * driver. If the PHY framework determines that both local and remote
> * advertisements support EEE, and the negotiated link mode is compatible with
> * EEE, it will set enable_tx_lpi = true. The MAC driver is expected to act on
> * this setting by enabling the LPI timer if enable_tx_lpi is set.
> */
>
> So you should only be looking at enable_tx_lpi.
Ok. I will fix.
>
> Also, do you actually call phy_support_eee() anywhere? I don't see it
> in this patch, but maybe it was already there?
We never call phy_support_eee() anywhere.
I will fix
>
> Adrew
--
Thanks,
Raju
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-09-04 8:27 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-29 5:51 [PATCH net-next V4 0/5] Add support to PHYLINK for LAN743x/PCI11x1x chips Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 1/5] net: phylink: Add phylink_set_fixed_link() to configure fixed link state in phylink Raju Lakkaraju
2024-08-30 20:37 ` Andrew Lunn
2024-08-29 5:51 ` [PATCH net-next V4 2/5] net: lan743x: Create separate PCS power reset function Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 3/5] net: lan743x: Create separate Link Speed Duplex state function Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 4/5] net: lan743x: Migrate phylib to phylink Raju Lakkaraju
2024-08-29 7:49 ` Maxime Chevallier
2024-08-30 5:36 ` Raju Lakkaraju
2024-08-29 5:51 ` [PATCH net-next V4 5/5] net: lan743x: Add support to ethtool phylink get and set settings Raju Lakkaraju
2024-08-30 20:55 ` Andrew Lunn
2024-09-04 8:23 ` Raju Lakkaraju
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).