From: Florian Fainelli <f.fainelli@gmail.com>
To: Russell King <rmk+kernel@arm.linux.org.uk>,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH RFC 15/26] net: mvneta: convert to phylink
Date: Thu, 07 Jan 2016 12:22:08 -0800 [thread overview]
Message-ID: <568EC8F0.2080305@gmail.com> (raw)
In-Reply-To: <E1a5zk4-00075z-9s@rmk-PC.arm.linux.org.uk>
On 07/12/15 09:38, Russell King wrote:
> Convert mvneta to use phylink, which models the MAC to PHY link in
> a generic, reusable form.
This looks much nicer after your changes, and this also makes it much
clearer what the PHY link changes bring in, and why in patch 11 I was
under the impression this duplicated a similar API from PHYLIB.
Since PHYLINK becomes a much better super set of PHYLIB now, we should
think about what to do with PHYLIB being using in drivers at some point
and see what could be deprecated/moved over to PHYLINK.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> drivers/net/ethernet/marvell/Kconfig | 2 +-
> drivers/net/ethernet/marvell/mvneta.c | 399 +++++++++++++++++++---------------
> 2 files changed, 224 insertions(+), 177 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
> index a1c862b4664d..d59fb29f28b3 100644
> --- a/drivers/net/ethernet/marvell/Kconfig
> +++ b/drivers/net/ethernet/marvell/Kconfig
> @@ -44,7 +44,7 @@ config MVNETA
> tristate "Marvell Armada 370/38x/XP network interface support"
> depends on PLAT_ORION
> select MVMDIO
> - select FIXED_PHY
> + select PHYLINK
> ---help---
> This driver supports the network interface units in the
> Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index e84c7f2634d3..f19d9a31dccd 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -31,6 +31,7 @@
> #include <linux/of_net.h>
> #include <linux/of_address.h>
> #include <linux/phy.h>
> +#include <linux/phylink.h>
> #include <linux/clk.h>
> #include <linux/cpu.h>
>
> @@ -169,6 +170,7 @@
> #define MVNETA_GMAC_CTRL_0 0x2c00
> #define MVNETA_GMAC_MAX_RX_SIZE_SHIFT 2
> #define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
> +#define MVNETA_GMAC0_PORT_1000BASE_X BIT(1)
> #define MVNETA_GMAC0_PORT_ENABLE BIT(0)
> #define MVNETA_GMAC_CTRL_2 0x2c08
> #define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0)
> @@ -184,13 +186,19 @@
> #define MVNETA_GMAC_TX_FLOW_CTRL_ENABLE BIT(5)
> #define MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE BIT(6)
> #define MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE BIT(7)
> +#define MVNETA_GMAC_AN_COMPLETE BIT(11)
> +#define MVNETA_GMAC_SYNC_OK BIT(14)
> #define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
> #define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
> #define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
> #define MVNETA_GMAC_INBAND_AN_ENABLE BIT(2)
> +#define MVNETA_GMAC_AN_BYPASS_ENABLE BIT(3)
> +#define MVNETA_GMAC_INBAND_RESTART_AN BIT(4)
> #define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
> #define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
> #define MVNETA_GMAC_AN_SPEED_EN BIT(7)
> +#define MVNETA_GMAC_CONFIG_FLOW_CTRL BIT(8)
> +#define MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL BIT(9)
> #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11)
> #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
> #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
> @@ -361,15 +369,9 @@ struct mvneta_port {
> u16 tx_ring_size;
> u16 rx_ring_size;
>
> - struct mii_bus *mii_bus;
> - struct phy_device *phy_dev;
> - phy_interface_t phy_interface;
> - struct device_node *phy_node;
> - unsigned int link;
> - unsigned int duplex;
> - unsigned int speed;
> + struct device_node *dn;
> unsigned int tx_csum_limit;
> - int use_inband_status:1;
> + struct phylink *phylink;
>
> u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
> };
> @@ -1056,26 +1058,6 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
> val &= ~MVNETA_PHY_POLLING_ENABLE;
> mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
>
> - if (pp->use_inband_status) {
> - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> - val &= ~(MVNETA_GMAC_FORCE_LINK_PASS |
> - MVNETA_GMAC_FORCE_LINK_DOWN |
> - MVNETA_GMAC_AN_FLOW_CTRL_EN);
> - val |= MVNETA_GMAC_INBAND_AN_ENABLE |
> - MVNETA_GMAC_AN_SPEED_EN |
> - MVNETA_GMAC_AN_DUPLEX_EN;
> - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> - val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
> - val |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
> - mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
> - } else {
> - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> - val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE |
> - MVNETA_GMAC_AN_SPEED_EN |
> - MVNETA_GMAC_AN_DUPLEX_EN);
> - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> - }
> -
> mvneta_set_ucast_table(pp, -1);
> mvneta_set_special_mcast_table(pp, -1);
> mvneta_set_other_mcast_table(pp, -1);
> @@ -2115,26 +2097,11 @@ static irqreturn_t mvneta_isr(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> -static int mvneta_fixed_link_update(struct mvneta_port *pp,
> - struct phy_device *phy)
> +static void mvneta_link_change(struct mvneta_port *pp)
> {
> - struct fixed_phy_status status;
> - struct fixed_phy_status changed = {};
> u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
>
> - status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
> - if (gmac_stat & MVNETA_GMAC_SPEED_1000)
> - status.speed = SPEED_1000;
> - else if (gmac_stat & MVNETA_GMAC_SPEED_100)
> - status.speed = SPEED_100;
> - else
> - status.speed = SPEED_10;
> - status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
> - changed.link = 1;
> - changed.speed = 1;
> - changed.duplex = 1;
> - fixed_phy_update_state(phy, &status, &changed);
> - return 0;
> + phylink_mac_change(pp->phylink, !!(gmac_stat & MVNETA_GMAC_LINK_UP));
> }
>
> /* NAPI handler
> @@ -2162,12 +2129,11 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
> u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE);
>
> mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
> - if (pp->use_inband_status && (cause_misc &
> - (MVNETA_CAUSE_PHY_STATUS_CHANGE |
> - MVNETA_CAUSE_LINK_CHANGE |
> - MVNETA_CAUSE_PSC_SYNC_CHANGE))) {
> - mvneta_fixed_link_update(pp, pp->phy_dev);
> - }
> +
> + if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE |
> + MVNETA_CAUSE_LINK_CHANGE |
> + MVNETA_CAUSE_PSC_SYNC_CHANGE))
> + mvneta_link_change(pp);
> }
>
> /* Release Tx descriptors */
> @@ -2456,7 +2422,7 @@ static void mvneta_start_dev(struct mvneta_port *pp)
> MVNETA_CAUSE_LINK_CHANGE |
> MVNETA_CAUSE_PSC_SYNC_CHANGE);
>
> - phy_start(pp->phy_dev);
> + phylink_start(pp->phylink);
> netif_tx_start_all_queues(pp->dev);
> }
>
> @@ -2464,7 +2430,7 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
> {
> unsigned int cpu;
>
> - phy_stop(pp->phy_dev);
> + phylink_stop(pp->phylink);
>
> for_each_present_cpu(cpu) {
> struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
> @@ -2615,99 +2581,218 @@ static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
> return 0;
> }
>
> -static void mvneta_adjust_link(struct net_device *ndev)
> +static int mvneta_mac_support(struct net_device *ndev, unsigned int mode,
> + struct phylink_link_state *state)
> +{
> + switch (mode) {
> + case MLO_AN_8023Z:
> + state->supported = SUPPORTED_1000baseT_Full |
> + SUPPORTED_Autoneg | SUPPORTED_Pause;
> + state->advertising = ADVERTISED_1000baseT_Full |
> + ADVERTISED_Autoneg | ADVERTISED_Pause;
> + state->an_enabled = 1;
> + break;
> +
> + case MLO_AN_FIXED:
> + break;
> +
> + default:
> + state->supported = PHY_10BT_FEATURES |
> + PHY_100BT_FEATURES |
> + SUPPORTED_1000baseT_Full |
> + SUPPORTED_Autoneg;
> + state->advertising = ADVERTISED_10baseT_Half |
> + ADVERTISED_10baseT_Full |
> + ADVERTISED_100baseT_Half |
> + ADVERTISED_100baseT_Full |
> + ADVERTISED_1000baseT_Full |
> + ADVERTISED_Autoneg;
> + state->an_enabled = 1;
> + break;
> + }
> + return 0;
> +}
> +
> +static int mvneta_mac_link_state(struct net_device *ndev,
> + struct phylink_link_state *state)
> {
> struct mvneta_port *pp = netdev_priv(ndev);
> - struct phy_device *phydev = pp->phy_dev;
> - int status_change = 0;
> + u32 gmac_stat;
>
> - if (phydev->link) {
> - if ((pp->speed != phydev->speed) ||
> - (pp->duplex != phydev->duplex)) {
> - u32 val;
> + gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
>
> - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> - val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
> - MVNETA_GMAC_CONFIG_GMII_SPEED |
> - MVNETA_GMAC_CONFIG_FULL_DUPLEX);
> + if (gmac_stat & MVNETA_GMAC_SPEED_1000)
> + state->speed = SPEED_1000;
> + else if (gmac_stat & MVNETA_GMAC_SPEED_100)
> + state->speed = SPEED_100;
> + else
> + state->speed = SPEED_10;
>
> - if (phydev->duplex)
> - val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
> + state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE);
> + state->sync = !!(gmac_stat & MVNETA_GMAC_SYNC_OK);
> + state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
> + state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
>
> - if (phydev->speed == SPEED_1000)
> - val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
> - else if (phydev->speed == SPEED_100)
> - val |= MVNETA_GMAC_CONFIG_MII_SPEED;
> + state->pause = 0;
> + if (gmac_stat & MVNETA_GMAC_RX_FLOW_CTRL_ENABLE)
> + state->pause |= MLO_PAUSE_RX;
> + if (gmac_stat & MVNETA_GMAC_TX_FLOW_CTRL_ENABLE)
> + state->pause |= MLO_PAUSE_TX;
>
> - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> + return 1;
> +}
>
> - pp->duplex = phydev->duplex;
> - pp->speed = phydev->speed;
> - }
> +static void mvneta_mac_an_restart(struct net_device *ndev, unsigned int mode)
> +{
> + struct mvneta_port *pp = netdev_priv(ndev);
> +
> + if (mode == MLO_AN_8023Z) {
> + u32 gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> +
> + gmac_an |= MVNETA_GMAC_INBAND_RESTART_AN;
> + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, gmac_an);
> }
> +}
>
> - if (phydev->link != pp->link) {
> - if (!phydev->link) {
> - pp->duplex = -1;
> - pp->speed = 0;
> - }
> +static void mvneta_mac_config(struct net_device *ndev, unsigned int mode,
> + const struct phylink_link_state *state)
> +{
> + struct mvneta_port *pp = netdev_priv(ndev);
> + u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
> + u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
> + u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
> + u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> +
> + new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X;
> + new_ctrl2 = gmac_ctrl2 & ~MVNETA_GMAC2_INBAND_AN_ENABLE;
> + new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
> + new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE |
> + MVNETA_GMAC_INBAND_RESTART_AN |
> + MVNETA_GMAC_CONFIG_MII_SPEED |
> + MVNETA_GMAC_CONFIG_GMII_SPEED |
> + MVNETA_GMAC_AN_SPEED_EN |
> + MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL |
> + MVNETA_GMAC_CONFIG_FLOW_CTRL |
> + MVNETA_GMAC_AN_FLOW_CTRL_EN |
> + MVNETA_GMAC_CONFIG_FULL_DUPLEX |
> + MVNETA_GMAC_AN_DUPLEX_EN);
> +
> + switch (mode) {
> + case MLO_AN_SGMII:
> + /* SGMII mode receives the state from the PHY */
> + new_ctrl2 |= MVNETA_GMAC2_INBAND_AN_ENABLE;
> + new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
> + new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
> + MVNETA_GMAC_FORCE_LINK_PASS)) |
> + MVNETA_GMAC_INBAND_AN_ENABLE |
> + MVNETA_GMAC_AN_SPEED_EN |
> + MVNETA_GMAC_AN_DUPLEX_EN;
> + break;
> +
> + case MLO_AN_8023Z:
> + /* 802.3z negotiation - only 1000base-X */
> + new_ctrl0 |= MVNETA_GMAC0_PORT_1000BASE_X;
> + new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
> + new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
> + MVNETA_GMAC_FORCE_LINK_PASS)) |
> + MVNETA_GMAC_INBAND_AN_ENABLE |
> + MVNETA_GMAC_CONFIG_GMII_SPEED;
> +
> + if (state->advertising & ADVERTISED_Pause)
> + new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL;
> +
> + if (state->an_enabled)
> + new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN |
> + MVNETA_GMAC_AN_DUPLEX_EN;
> + else if (state->duplex)
> + new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
> + break;
>
> - pp->link = phydev->link;
> - status_change = 1;
> + default:
> + /* Phy or fixed speed */
> + if (state->duplex)
> + new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
> +
> + if (state->speed == SPEED_1000)
> + new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED;
> + else if (state->speed == SPEED_100)
> + new_an |= MVNETA_GMAC_CONFIG_MII_SPEED;
> + break;
> }
>
> - if (status_change) {
> - if (phydev->link) {
> - if (!pp->use_inband_status) {
> - u32 val = mvreg_read(pp,
> - MVNETA_GMAC_AUTONEG_CONFIG);
> - val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
> - val |= MVNETA_GMAC_FORCE_LINK_PASS;
> - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
> - val);
> - }
> - mvneta_port_up(pp);
> - } else {
> - if (!pp->use_inband_status) {
> - u32 val = mvreg_read(pp,
> - MVNETA_GMAC_AUTONEG_CONFIG);
> - val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
> - val |= MVNETA_GMAC_FORCE_LINK_DOWN;
> - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
> - val);
> - }
> - mvneta_port_down(pp);
> - }
> - phy_print_status(phydev);
> + /* Armada 370 documentation says we can only change the port mode
> + * and in-band enable when the link is down, so force it down
> + * while making these changes. We also do this for GMAC_CTRL2 */
> + if ((new_ctrl0 ^ gmac_ctrl0) & MVNETA_GMAC0_PORT_1000BASE_X ||
> + (new_ctrl2 ^ gmac_ctrl2) & MVNETA_GMAC2_INBAND_AN_ENABLE ||
> + (new_an ^ gmac_an) & MVNETA_GMAC_INBAND_AN_ENABLE) {
> + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
> + (gmac_an & ~MVNETA_GMAC_FORCE_LINK_PASS) |
> + MVNETA_GMAC_FORCE_LINK_DOWN);
> }
> +
> + if (new_ctrl0 != gmac_ctrl0)
> + mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
> + if (new_ctrl2 != gmac_ctrl2)
> + mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2);
> + if (new_clk != gmac_clk)
> + mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk);
> + if (new_an != gmac_an)
> + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an);
> }
>
> -static int mvneta_mdio_probe(struct mvneta_port *pp)
> +static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode)
> {
> - struct phy_device *phy_dev;
> + struct mvneta_port *pp = netdev_priv(ndev);
> + u32 val;
>
> - phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
> - pp->phy_interface);
> - if (!phy_dev) {
> - netdev_err(pp->dev, "could not find the PHY\n");
> - return -ENODEV;
> + mvneta_port_down(pp);
> +
> + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
> + val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> + val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
> + val |= MVNETA_GMAC_FORCE_LINK_DOWN;
> + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> }
> +}
>
> - phy_dev->supported &= PHY_GBIT_FEATURES;
> - phy_dev->advertising = phy_dev->supported;
> +static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode,
> + struct phy_device *phy)
> +{
> + struct mvneta_port *pp = netdev_priv(ndev);
> + u32 val;
>
> - pp->phy_dev = phy_dev;
> - pp->link = 0;
> - pp->duplex = 0;
> - pp->speed = 0;
> + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
> + val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> + val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
> + val |= MVNETA_GMAC_FORCE_LINK_PASS;
> + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> + }
>
> - return 0;
> + mvneta_port_up(pp);
> +}
> +
> +static const struct phylink_mac_ops mvneta_phylink_ops = {
> + .mac_get_support = mvneta_mac_support,
> + .mac_link_state = mvneta_mac_link_state,
> + .mac_an_restart = mvneta_mac_an_restart,
> + .mac_config = mvneta_mac_config,
> + .mac_link_down = mvneta_mac_link_down,
> + .mac_link_up = mvneta_mac_link_up,
> +};
> +
> +static int mvneta_mdio_probe(struct mvneta_port *pp)
> +{
> + int err = phylink_of_phy_connect(pp->phylink, pp->dn);
> + if (err)
> + netdev_err(pp->dev, "could not attach PHY\n");
> +
> + return err;
> }
>
> static void mvneta_mdio_remove(struct mvneta_port *pp)
> {
> - phy_disconnect(pp->phy_dev);
> - pp->phy_dev = NULL;
> + phylink_disconnect_phy(pp->phylink);
> }
>
> static void mvneta_percpu_enable(void *arg)
> @@ -2914,10 +2999,7 @@ static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
> {
> struct mvneta_port *pp = netdev_priv(dev);
>
> - if (!pp->phy_dev)
> - return -ENOTSUPP;
> -
> - return phy_mii_ioctl(pp->phy_dev, ifr, cmd);
> + return phylink_mii_ioctl(pp->phylink, ifr, cmd);
> }
>
> /* Ethtool methods */
> @@ -2927,10 +3009,7 @@ int mvneta_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
> {
> struct mvneta_port *pp = netdev_priv(dev);
>
> - if (!pp->phy_dev)
> - return -ENODEV;
> -
> - return phy_ethtool_gset(pp->phy_dev, cmd);
> + return phylink_ethtool_get_settings(pp->phylink, cmd);
> }
>
> /* Set settings (phy address, speed) for ethtools */
> @@ -2938,10 +3017,7 @@ int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
> {
> struct mvneta_port *pp = netdev_priv(dev);
>
> - if (!pp->phy_dev)
> - return -ENODEV;
> -
> - return phy_ethtool_sset(pp->phy_dev, cmd);
> + return phylink_ethtool_set_settings(pp->phylink, cmd);
> }
>
> /* Set interrupt coalescing for ethtools */
> @@ -3223,9 +3299,6 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
> return -EINVAL;
> }
>
> - if (pp->use_inband_status)
> - ctrl |= MVNETA_GMAC2_INBAND_AN_ENABLE;
> -
> /* Cancel Port Reset */
> ctrl &= ~MVNETA_GMAC2_PORT_RESET;
> mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl);
> @@ -3243,13 +3316,12 @@ static int mvneta_probe(struct platform_device *pdev)
> const struct mbus_dram_target_info *dram_target_info;
> struct resource *res;
> struct device_node *dn = pdev->dev.of_node;
> - struct device_node *phy_node;
> struct mvneta_port *pp;
> struct net_device *dev;
> + struct phylink *phylink;
> const char *dt_mac_addr;
> char hw_mac_addr[ETH_ALEN];
> const char *mac_from;
> - const char *managed;
> int phy_mode;
> int err;
> int cpu;
> @@ -3264,31 +3336,11 @@ static int mvneta_probe(struct platform_device *pdev)
> goto err_free_netdev;
> }
>
> - phy_node = of_parse_phandle(dn, "phy", 0);
> - if (!phy_node) {
> - if (!of_phy_is_fixed_link(dn)) {
> - dev_err(&pdev->dev, "no PHY specified\n");
> - err = -ENODEV;
> - goto err_free_irq;
> - }
> -
> - err = of_phy_register_fixed_link(dn);
> - if (err < 0) {
> - dev_err(&pdev->dev, "cannot register fixed PHY\n");
> - goto err_free_irq;
> - }
> -
> - /* In the case of a fixed PHY, the DT node associated
> - * to the PHY is the Ethernet MAC DT node.
> - */
> - phy_node = of_node_get(dn);
> - }
> -
> phy_mode = of_get_phy_mode(dn);
> if (phy_mode < 0) {
> dev_err(&pdev->dev, "incorrect phy-mode\n");
> err = -EINVAL;
> - goto err_put_phy_node;
> + goto err_free_irq;
> }
>
> dev->tx_queue_len = MVNETA_MAX_TXD;
> @@ -3298,18 +3350,13 @@ static int mvneta_probe(struct platform_device *pdev)
> dev->ethtool_ops = &mvneta_eth_tool_ops;
>
> pp = netdev_priv(dev);
> - pp->phy_node = phy_node;
> - pp->phy_interface = phy_mode;
> -
> - err = of_property_read_string(dn, "managed", &managed);
> - pp->use_inband_status = (err == 0 &&
> - strcmp(managed, "in-band-status") == 0);
> + pp->dn = dn;
> pp->cpu_notifier.notifier_call = mvneta_percpu_notifier;
>
> pp->clk = devm_clk_get(&pdev->dev, NULL);
> if (IS_ERR(pp->clk)) {
> err = PTR_ERR(pp->clk);
> - goto err_put_phy_node;
> + goto err_free_irq;
> }
>
> clk_prepare_enable(pp->clk);
> @@ -3386,6 +3433,14 @@ static int mvneta_probe(struct platform_device *pdev)
> dev->priv_flags |= IFF_UNICAST_FLT;
> dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
>
> + phylink = phylink_create(dev, dn, phy_mode, &mvneta_phylink_ops);
> + if (IS_ERR(phylink)) {
> + err = PTR_ERR(phylink);
> + goto err_free_stats;
> + }
> +
> + pp->phylink = phylink;
> +
> err = register_netdev(dev);
> if (err < 0) {
> dev_err(&pdev->dev, "failed to register\n");
> @@ -3397,24 +3452,16 @@ static int mvneta_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, pp->dev);
>
> - if (pp->use_inband_status) {
> - struct phy_device *phy = of_phy_find_device(dn);
> -
> - mvneta_fixed_link_update(pp, phy);
> -
> - put_device(&phy->dev);
> - }
> -
> return 0;
>
> err_free_stats:
> + if (pp->phylink)
> + phylink_destroy(pp->phylink);
> free_percpu(pp->stats);
> err_free_ports:
> free_percpu(pp->ports);
> err_clk:
> clk_disable_unprepare(pp->clk);
> -err_put_phy_node:
> - of_node_put(phy_node);
> err_free_irq:
> irq_dispose_mapping(dev->irq);
> err_free_netdev:
> @@ -3433,7 +3480,7 @@ static int mvneta_remove(struct platform_device *pdev)
> free_percpu(pp->ports);
> free_percpu(pp->stats);
> irq_dispose_mapping(dev->irq);
> - of_node_put(pp->phy_node);
> + phylink_destroy(pp->phylink);
> free_netdev(dev);
>
> return 0;
>
--
Florian
next prev parent reply other threads:[~2016-01-07 20:22 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-07 17:35 [PATCH RFC 00/26] Phylink & SFP support Russell King - ARM Linux
2015-12-07 17:37 ` [PATCH RFC 01/26] phy: move fixed_phy MII register generation to a library Russell King
2016-01-07 19:47 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 02/26] phy: convert swphy register generation to tabular form Russell King
2016-01-07 19:47 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 03/26] phy: separate swphy state validation from register generation Russell King
2016-01-07 19:48 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 04/26] phy: generate swphy registers on the fly Russell King
2016-01-07 19:49 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 05/26] phy: improve safety of fixed-phy MII register reading Russell King
2016-01-07 19:50 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 06/26] phy: provide a hook for link up/link down events Russell King
2016-01-07 19:53 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 07/26] phy: marvell: 88E1512: add flow control support Russell King
2016-01-07 19:53 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 08/26] phy: export phy_start_machine() for phylink Russell King
2016-01-07 19:53 ` Florian Fainelli
2015-12-07 17:37 ` [PATCH RFC 09/26] phy: export phy_speed_to_str() " Russell King
2016-01-07 19:54 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 10/26] phy: add I2C mdio bus Russell King
2015-12-08 18:15 ` Florian Fainelli
2015-12-11 10:25 ` Russell King - ARM Linux
2015-12-07 17:38 ` [PATCH RFC 11/26] phylink: add phylink infrastructure Russell King
2016-01-07 20:09 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 12/26] phylink: add hooks for SFP support Russell King
2016-01-07 20:05 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 13/26] sfp: add phylink based SFP module support Russell King
2016-01-07 20:23 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 14/26] sfp: display SFP module information Russell King
2016-01-07 20:23 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 15/26] net: mvneta: convert to phylink Russell King
2016-01-07 20:22 ` Florian Fainelli [this message]
2015-12-07 17:38 ` [PATCH RFC 16/26] phy: fixed-phy: remove fixed_phy_update_state() Russell King
2016-01-07 20:15 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 17/26] phylink: add ethtool nway_reset support Russell King
2016-01-07 20:24 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 18/26] net: mvneta: add " Russell King
2016-01-07 20:19 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 19/26] phylink: add flow control support Russell King
2016-01-07 20:25 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 20/26] net: mvneta: add flow control support via phylink Russell King
2016-01-07 20:26 ` Florian Fainelli
2015-12-07 17:38 ` [PATCH RFC 21/26] net: mvneta: enable flow control for PHY connections Russell King
2016-01-07 20:31 ` Florian Fainelli
2015-12-07 17:39 ` [PATCH RFC 22/26] phylink: add EEE support Russell King
2016-01-07 20:34 ` Florian Fainelli
2015-12-07 17:39 ` [PATCH RFC 23/26] net: mvneta: " Russell King
2016-01-07 20:35 ` Florian Fainelli
2015-12-07 17:39 ` [PATCH RFC 24/26] phylink: add module EEPROM support Russell King
2016-01-07 20:36 ` Florian Fainelli
2015-12-07 17:39 ` [PATCH RFC 25/26] net: mvneta: add module EEPROM reading support Russell King
2016-01-07 20:36 ` Florian Fainelli
2015-12-07 17:39 ` [PATCH RFC 26/26] sfp/phylink: hook up eeprom functions Russell King
2015-12-15 7:26 ` [PATCH RFC 00/26] Phylink & SFP support Dustin Byford
2015-12-28 2:08 ` Florian Fainelli
2015-12-28 23:39 ` Dustin Byford
2016-01-07 20:42 ` Florian Fainelli
2015-12-28 1:56 ` Florian Fainelli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=568EC8F0.2080305@gmail.com \
--to=f.fainelli@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=rmk+kernel@arm.linux.org.uk \
--cc=thomas.petazzoni@free-electrons.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.