Commit 53036aa8 authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller
Browse files

net: freescale: ucc_geth: phylink conversion



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: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02d4a649
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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.
+186 −259

File changed.

Preview size limit exceeded, changes collapsed.

+7 −6
Original line number Diff line number Diff line
@@ -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;
};

+15 −58
Original line number Diff line number Diff line
@@ -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,11 +321,9 @@ 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);
	ret = phylink_ethtool_set_wol(ugeth->phylink, wol);
	if (ret == -EOPNOTSUPP) {
		ugeth->phy_wol_en = 0;
	} else if (ret) {
@@ -374,7 +332,6 @@ static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
		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