Commit bf73478b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'lan743x-phylink'

Raju Lakkaraju says:

====================
Add support to PHYLINK for LAN743x/PCI11x1x chips

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:
============
V5 -> V6:
  - Remove the lan743x_find_max_speed( ) function. Not require
  - Add EEE enable check before calling lan743x_mac_eee_enable( ) function
V4 -> V5:
  - Remove the fixed_phy_unregister( ) function. Not require
  - Remove the "phydev->eee_enabled" check to update the MAC EEE
    enable/disable
  - Call lan743x_mac_eee_enable() with true after update tx_lpi_timer.
  - Add phy_support_eee() to initialize the EEE flags
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
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f3b6129b f95f28d7
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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.
+44 −79
Original line number Diff line number Diff line
@@ -1054,61 +1054,55 @@ 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);

	return phylink_ethtool_get_eee(adapter->phylink, eee);
}

	ret = phy_ethtool_get_eee(phydev, eee);
	if (ret < 0)
		return ret;
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;

	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;
	tx_lpi_timer = lan743x_csr_read(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT);
	if (tx_lpi_timer != eee->tx_lpi_timer) {
		u32 mac_cr = lan743x_csr_read(adapter, MAC_CR);

		/* Software should only change this field when Energy Efficient
		 * Ethernet Enable (EEEEN) is cleared.
		 * This function will trigger an autonegotiation restart and
		 * 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);

		if (mac_cr & MAC_CR_EEE_EN_)
			lan743x_mac_eee_enable(adapter, true);
	}

	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
@@ -1120,8 +1114,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,
@@ -1162,7 +1155,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;

@@ -1351,44 +1344,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 = {
@@ -1413,8 +1378,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,
+403 −243

File changed.

Preview size limit exceeded, changes collapsed.

+4 −0
Original line number Diff line number Diff line
@@ -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))
@@ -1203,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 */
+42 −0
Original line number Diff line number Diff line
@@ -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
Loading