diff options
Diffstat (limited to 'target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch')
-rw-r--r-- | target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch | 754 |
1 files changed, 0 insertions, 754 deletions
diff --git a/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch b/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch deleted file mode 100644 index b62dadd2f3..0000000000 --- a/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch +++ /dev/null @@ -1,754 +0,0 @@ -From: Russell King <rmk+kernel@arm.linux.org.uk> -Date: Wed, 16 Sep 2015 21:27:10 +0100 -Subject: [PATCH] net: mvneta: convert to phylink - -Convert mvneta to use phylink, which models the MAC to PHY link in -a generic, reusable form. - -Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> ---- - ---- a/drivers/net/ethernet/marvell/Kconfig -+++ b/drivers/net/ethernet/marvell/Kconfig -@@ -57,7 +57,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. ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -29,6 +29,7 @@ - #include <linux/of_net.h> - #include <linux/phy.h> - #include <linux/phy_fixed.h> -+#include <linux/phylink.h> - #include <linux/platform_device.h> - #include <linux/skbuff.h> - #include <net/hwbm.h> -@@ -189,6 +190,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) -@@ -204,13 +206,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) -@@ -400,14 +408,9 @@ struct mvneta_port { - u16 tx_ring_size; - u16 rx_ring_size; - -- struct mii_bus *mii_bus; -- 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; -- unsigned int use_inband_status:1; -+ struct phylink *phylink; - - struct mvneta_bm *bm_priv; - struct mvneta_bm_pool *pool_long; -@@ -1182,10 +1185,6 @@ static void mvneta_port_disable(struct m - val &= ~MVNETA_GMAC0_PORT_ENABLE; - mvreg_write(pp, MVNETA_GMAC_CTRL_0, val); - -- pp->link = 0; -- pp->duplex = -1; -- pp->speed = 0; -- - udelay(200); - } - -@@ -1245,44 +1244,6 @@ static void mvneta_set_other_mcast_table - mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val); - } - --static void mvneta_set_autoneg(struct mvneta_port *pp, int enable) --{ -- u32 val; -- -- if (enable) { -- 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); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val |= MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, 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); -- -- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); -- val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val); -- -- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); -- val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE; -- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- } --} -- - static void mvneta_percpu_unmask_interrupt(void *arg) - { - struct mvneta_port *pp = arg; -@@ -1430,7 +1391,6 @@ static void mvneta_defaults_set(struct m - val &= ~MVNETA_PHY_POLLING_ENABLE; - mvreg_write(pp, MVNETA_UNIT_CONTROL, val); - -- mvneta_set_autoneg(pp, pp->use_inband_status); - mvneta_set_ucast_table(pp, -1); - mvneta_set_special_mcast_table(pp, -1); - mvneta_set_other_mcast_table(pp, -1); -@@ -2635,26 +2595,11 @@ static irqreturn_t mvneta_isr(int irq, v - 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 -@@ -2670,7 +2615,6 @@ static int mvneta_poll(struct napi_struc - u32 cause_rx_tx; - int rx_queue; - struct mvneta_port *pp = netdev_priv(napi->dev); -- struct net_device *ndev = pp->dev; - struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports); - - if (!netif_running(pp->dev)) { -@@ -2684,12 +2628,11 @@ static int mvneta_poll(struct napi_struc - 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, ndev->phydev); -- } -+ -+ if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE | -+ MVNETA_CAUSE_LINK_CHANGE | -+ MVNETA_CAUSE_PSC_SYNC_CHANGE)) -+ mvneta_link_change(pp); - } - - /* Release Tx descriptors */ -@@ -2985,7 +2928,6 @@ static int mvneta_setup_txqs(struct mvne - static void mvneta_start_dev(struct mvneta_port *pp) - { - int cpu; -- struct net_device *ndev = pp->dev; - - mvneta_max_rx_size_set(pp, pp->pkt_size); - mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -@@ -3008,16 +2950,15 @@ static void mvneta_start_dev(struct mvne - MVNETA_CAUSE_LINK_CHANGE | - MVNETA_CAUSE_PSC_SYNC_CHANGE); - -- phy_start(ndev->phydev); -+ phylink_start(pp->phylink); - netif_tx_start_all_queues(pp->dev); - } - - static void mvneta_stop_dev(struct mvneta_port *pp) - { - unsigned int cpu; -- struct net_device *ndev = pp->dev; - -- phy_stop(ndev->phydev); -+ phylink_stop(pp->phylink); - - for_each_online_cpu(cpu) { - struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); -@@ -3187,99 +3128,210 @@ static int mvneta_set_mac_addr(struct ne - return 0; - } - --static void mvneta_adjust_link(struct net_device *ndev) -+static void mvneta_validate_support(struct net_device *ndev, unsigned int mode, -+ unsigned long *support) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ /* Allow all the expected bits */ -+ phylink_set(mask, Autoneg); -+ phylink_set(mask, TP); -+ phylink_set(mask, AUI); -+ phylink_set(mask, MII); -+ phylink_set(mask, FIBRE); -+ phylink_set(mask, BNC); -+ phylink_set(mask, Backplane); -+ -+ /* Half-duplex at speeds higher than 100Mbit is unsupported */ -+ phylink_set(mask, 1000baseT_Full); -+ phylink_set(mask, 1000baseX_Full); -+ -+ if (mode != MLO_AN_8023Z) { -+ /* 10M and 100M are only supported in non-802.3z mode */ -+ phylink_set(mask, 10baseT_Half); -+ phylink_set(mask, 10baseT_Full); -+ phylink_set(mask, 100baseT_Half); -+ phylink_set(mask, 100baseT_Full); -+ } else { -+ phylink_set(mask, Pause); -+ } -+ -+ bitmap_and(support, support, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -+} -+ -+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 = ndev->phydev; -- int status_change = 0; -+ u32 gmac_stat; - -- if (phydev->link) { -- if ((pp->speed != phydev->speed) || -- (pp->duplex != phydev->duplex)) { -- u32 val; -- -- 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 (phydev->duplex) -- val |= MVNETA_GMAC_CONFIG_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; -+ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS); - -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -+ 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; - -- pp->duplex = phydev->duplex; -- pp->speed = phydev->speed; -- } -+ state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE); -+ state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP); -+ state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX); -+ -+ return 1; -+} -+ -+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); -+ -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -+ gmac_an | MVNETA_GMAC_INBAND_RESTART_AN); -+ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, -+ gmac_an & ~MVNETA_GMAC_INBAND_RESTART_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); -+ -+ if (phylink_test(state->advertising, Pause)) -+ new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL; -+ -+ 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; - -- pp->link = phydev->link; -- status_change = 1; -+ 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 | -+ /* The MAC only supports FD mode */ -+ MVNETA_GMAC_CONFIG_FULL_DUPLEX; -+ -+ if (state->an_enabled) -+ new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN; -+ break; -+ -+ 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 void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) -+{ -+ struct mvneta_port *pp = netdev_priv(ndev); -+ u32 val; -+ -+ 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); - } - } - --static int mvneta_mdio_probe(struct mvneta_port *pp) -+static void mvneta_mac_link_up(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; -+ 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); - } - -- phy_dev->supported &= PHY_GBIT_FEATURES; -- phy_dev->advertising = phy_dev->supported; -+ mvneta_port_up(pp); -+} - -- pp->link = 0; -- pp->duplex = 0; -- pp->speed = 0; -+static const struct phylink_mac_ops mvneta_phylink_ops = { -+ .validate_support = mvneta_validate_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, -+}; - -- return 0; -+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) - { -- struct net_device *ndev = pp->dev; -- -- phy_disconnect(ndev->phydev); -+ phylink_disconnect_phy(pp->phylink); - } - - /* Electing a CPU must be done in an atomic way: it should be done -@@ -3537,10 +3589,9 @@ static int mvneta_stop(struct net_device - - static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - { -- if (!dev->phydev) -- return -ENOTSUPP; -+ struct mvneta_port *pp = netdev_priv(dev); - -- return phy_mii_ioctl(dev->phydev, ifr, cmd); -+ return phylink_mii_ioctl(pp->phylink, ifr, cmd); - } - - /* Ethtool methods */ -@@ -3551,44 +3602,18 @@ mvneta_ethtool_set_link_ksettings(struct - const struct ethtool_link_ksettings *cmd) - { - struct mvneta_port *pp = netdev_priv(ndev); -- struct phy_device *phydev = ndev->phydev; -- -- if (!phydev) -- return -ENODEV; - -- if ((cmd->base.autoneg == AUTONEG_ENABLE) != pp->use_inband_status) { -- u32 val; -- -- mvneta_set_autoneg(pp, cmd->base.autoneg == AUTONEG_ENABLE); -- -- if (cmd->base.autoneg == AUTONEG_DISABLE) { -- 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 (phydev->duplex) -- val |= MVNETA_GMAC_CONFIG_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; -- -- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- } -+ return phylink_ethtool_ksettings_set(pp->phylink, cmd); -+} - -- pp->use_inband_status = (cmd->base.autoneg == AUTONEG_ENABLE); -- netdev_info(pp->dev, "autoneg status set to %i\n", -- pp->use_inband_status); -- -- if (netif_running(ndev)) { -- mvneta_port_down(pp); -- mvneta_port_up(pp); -- } -- } -+/* Get link ksettings for ethtools */ -+static int -+mvneta_ethtool_get_link_ksettings(struct net_device *ndev, -+ struct ethtool_link_ksettings *cmd) -+{ -+ struct mvneta_port *pp = netdev_priv(ndev); - -- return phy_ethtool_ksettings_set(ndev->phydev, cmd); -+ return phylink_ethtool_ksettings_get(pp->phylink, cmd); - } - - /* Set interrupt coalescing for ethtools */ -@@ -3696,26 +3721,28 @@ static void mvneta_ethtool_update_stats( - { - const struct mvneta_statistic *s; - void __iomem *base = pp->base; -- u32 high, low, val; -- u64 val64; -+ u32 high, low; -+ u64 val; - int i; - - for (i = 0, s = mvneta_statistics; - s < mvneta_statistics + ARRAY_SIZE(mvneta_statistics); - s++, i++) { -+ val = 0; -+ - switch (s->type) { - case T_REG_32: - val = readl_relaxed(base + s->offset); -- pp->ethtool_stats[i] += val; - break; - case T_REG_64: - /* Docs say to read low 32-bit then high */ - low = readl_relaxed(base + s->offset); - high = readl_relaxed(base + s->offset + 4); -- val64 = (u64)high << 32 | low; -- pp->ethtool_stats[i] += val64; -+ val = (u64)high << 32 | low; - break; - } -+ -+ pp->ethtool_stats[i] += val; - } - } - -@@ -3875,7 +3902,7 @@ const struct ethtool_ops mvneta_eth_tool - .get_rxnfc = mvneta_ethtool_get_rxnfc, - .get_rxfh = mvneta_ethtool_get_rxfh, - .set_rxfh = mvneta_ethtool_set_rxfh, -- .get_link_ksettings = phy_ethtool_get_link_ksettings, -+ .get_link_ksettings = mvneta_ethtool_get_link_ksettings, - .set_link_ksettings = mvneta_ethtool_set_link_ksettings, - }; - -@@ -4002,14 +4029,13 @@ static int mvneta_probe(struct platform_ - 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 device_node *bm_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 tx_csum_limit; - int phy_mode; - int err; -@@ -4025,31 +4051,11 @@ static int mvneta_probe(struct platform_ - 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; -@@ -4060,12 +4066,7 @@ static int mvneta_probe(struct platform_ - - pp = netdev_priv(dev); - spin_lock_init(&pp->lock); -- 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->rxq_def = rxq_def; - -@@ -4076,7 +4077,7 @@ static int mvneta_probe(struct platform_ - 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); -@@ -4184,6 +4185,14 @@ static int mvneta_probe(struct platform_ - dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; - 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"); -@@ -4195,14 +4204,6 @@ static int mvneta_probe(struct platform_ - - 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->mdio.dev); -- } -- - return 0; - - err_netdev: -@@ -4213,16 +4214,14 @@ err_netdev: - 1 << pp->id); - } - 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_bus); - clk_disable_unprepare(pp->clk); --err_put_phy_node: -- of_node_put(phy_node); -- if (of_phy_is_fixed_link(dn)) -- of_phy_deregister_fixed_link(dn); - err_free_irq: - irq_dispose_mapping(dev->irq); - err_free_netdev: -@@ -4234,7 +4233,6 @@ err_free_netdev: - static int mvneta_remove(struct platform_device *pdev) - { - struct net_device *dev = platform_get_drvdata(pdev); -- struct device_node *dn = pdev->dev.of_node; - struct mvneta_port *pp = netdev_priv(dev); - - unregister_netdev(dev); -@@ -4242,10 +4240,8 @@ static int mvneta_remove(struct platform - clk_disable_unprepare(pp->clk); - free_percpu(pp->ports); - free_percpu(pp->stats); -- if (of_phy_is_fixed_link(dn)) -- of_phy_deregister_fixed_link(dn); - irq_dispose_mapping(dev->irq); -- of_node_put(pp->phy_node); -+ phylink_destroy(pp->phylink); - free_netdev(dev); - - if (pp->bm_priv) { |