aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch
diff options
context:
space:
mode:
authorScott Roberts <ttocsr@gmail.com>2019-09-27 14:19:01 -0600
committerHauke Mehrtens <hauke@hauke-m.de>2019-10-12 23:43:08 +0200
commitd2a1075973728b55231688809b68a0f0b93c9da4 (patch)
treeaa026543b3be26f0e5b71c4596f9e7a4b440e486 /target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch
parente11fc8439c9f7230441408c4d257efc46f372312 (diff)
downloadupstream-d2a1075973728b55231688809b68a0f0b93c9da4.tar.gz
upstream-d2a1075973728b55231688809b68a0f0b93c9da4.tar.bz2
upstream-d2a1075973728b55231688809b68a0f0b93c9da4.zip
mvebu: backport mvneta and comphy from linux 5.x
These patches backport support for the ARMADA 3700 COMPHY driver. Also backported is the mvneta driver. This will allow switching the SGMII speed using SMC calls. To support this you must update the firmware using Marvells 18.12 version (this has now been upstreamed). The mvneta driver allows 2500basex and 2500baset. Signed-off-by: Scott Roberts <ttocsr@gmail.com>
Diffstat (limited to 'target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch')
-rw-r--r--target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch159
1 files changed, 159 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch b/target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch
new file mode 100644
index 0000000000..257cfdec4a
--- /dev/null
+++ b/target/linux/mvebu/patches-4.19/535-net-marvell-neta-add-comphy-support.patch
@@ -0,0 +1,159 @@
+From a10c1c8191e04c21769656c2ca8e1c69a6218954 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Thu, 7 Feb 2019 16:19:26 +0000
+Subject: [PATCH] net: marvell: neta: add comphy support
+
+Add support for the common phy binding, so that we can reconfigure the
+comphy according to the desired ethernet speed. This will allow us to
+support 1000base-X and 2500base-X SFPs dynamically on SolidRun Clearfog.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 45 +++++++++++++++++++++++++++++++----
+ 1 file changed, 41 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -27,6 +27,7 @@
+ #include <linux/of_irq.h>
+ #include <linux/of_mdio.h>
+ #include <linux/of_net.h>
++#include <linux/phy/phy.h>
+ #include <linux/phy.h>
+ #include <linux/phylink.h>
+ #include <linux/platform_device.h>
+@@ -436,6 +437,7 @@ struct mvneta_port {
+ struct device_node *dn;
+ unsigned int tx_csum_limit;
+ struct phylink *phylink;
++ struct phy *comphy;
+
+ struct mvneta_bm *bm_priv;
+ struct mvneta_bm_pool *pool_long;
+@@ -3153,6 +3155,8 @@ static void mvneta_start_dev(struct mvne
+ {
+ int cpu;
+
++ WARN_ON(phy_power_on(pp->comphy));
++
+ mvneta_max_rx_size_set(pp, pp->pkt_size);
+ mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
+
+@@ -3215,6 +3219,8 @@ static void mvneta_stop_dev(struct mvnet
+
+ mvneta_tx_reset(pp);
+ mvneta_rx_reset(pp);
++
++ WARN_ON(phy_power_off(pp->comphy));
+ }
+
+ static void mvneta_percpu_enable(void *arg)
+@@ -3340,6 +3346,7 @@ static int mvneta_set_mac_addr(struct ne
+ static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
+ struct phylink_link_state *state)
+ {
++ struct mvneta_port *pp = netdev_priv(ndev);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ /* We only support QSGMII, SGMII, 802.3z and RGMII modes */
+@@ -3360,8 +3367,13 @@ static void mvneta_validate(struct net_d
+ phylink_set(mask, Pause);
+
+ /* Half-duplex at speeds higher than 100Mbit is unsupported */
+- phylink_set(mask, 1000baseT_Full);
+- phylink_set(mask, 1000baseX_Full);
++ if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) {
++ phylink_set(mask, 1000baseT_Full);
++ phylink_set(mask, 1000baseX_Full);
++ }
++ if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) {
++ phylink_set(mask, 2500baseX_Full);
++ }
+
+ if (!phy_interface_mode_is_8023z(state->interface)) {
+ /* 10M and 100M are only supported in non-802.3z mode */
+@@ -3375,6 +3387,11 @@ static void mvneta_validate(struct net_d
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_and(state->advertising, state->advertising, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
++
++ /* We can only operate at 2500BaseX or 1000BaseX. If requested
++ * to advertise both, only report advertising at 2500BaseX.
++ */
++ phylink_helper_basex_speed(state);
+ }
+
+ static int mvneta_mac_link_state(struct net_device *ndev,
+@@ -3386,7 +3403,9 @@ static int mvneta_mac_link_state(struct
+ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
+
+ if (gmac_stat & MVNETA_GMAC_SPEED_1000)
+- state->speed = SPEED_1000;
++ state->speed =
++ state->interface == PHY_INTERFACE_MODE_2500BASEX ?
++ SPEED_2500 : SPEED_1000;
+ else if (gmac_stat & MVNETA_GMAC_SPEED_100)
+ state->speed = SPEED_100;
+ else
+@@ -3501,12 +3520,20 @@ static void mvneta_mac_config(struct net
+ MVNETA_GMAC_FORCE_LINK_DOWN);
+ }
+
++
+ /* When at 2.5G, the link partner can send frames with shortened
+ * preambles.
+ */
+ if (state->speed == SPEED_2500)
+ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE;
+
++ if (pp->comphy &&
++ (state->interface == PHY_INTERFACE_MODE_SGMII ||
++ state->interface == PHY_INTERFACE_MODE_1000BASEX ||
++ state->interface == PHY_INTERFACE_MODE_2500BASEX))
++ WARN_ON(phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET,
++ state->interface));
++
+ if (new_ctrl0 != gmac_ctrl0)
+ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
+ if (new_ctrl2 != gmac_ctrl2)
+@@ -4419,7 +4446,7 @@ static int mvneta_port_power_up(struct m
+ if (phy_mode == PHY_INTERFACE_MODE_QSGMII)
+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
+ else if (phy_mode == PHY_INTERFACE_MODE_SGMII ||
+- phy_mode == PHY_INTERFACE_MODE_1000BASEX)
++ phy_interface_mode_is_8023z(phy_mode))
+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
+ else if (!phy_interface_mode_is_rgmii(phy_mode))
+ return -EINVAL;
+@@ -4436,6 +4463,7 @@ static int mvneta_probe(struct platform_
+ struct mvneta_port *pp;
+ struct net_device *dev;
+ struct phylink *phylink;
++ struct phy *comphy;
+ const char *dt_mac_addr;
+ char hw_mac_addr[ETH_ALEN];
+ const char *mac_from;
+@@ -4461,6 +4489,14 @@ static int mvneta_probe(struct platform_
+ goto err_free_irq;
+ }
+
++ comphy = devm_of_phy_get(&pdev->dev, dn, NULL);
++ if (comphy == ERR_PTR(-EPROBE_DEFER)) {
++ err = -EPROBE_DEFER;
++ goto err_free_irq;
++ } else if (IS_ERR(comphy)) {
++ comphy = NULL;
++ }
++
+ phylink = phylink_create(dev, pdev->dev.fwnode, phy_mode,
+ &mvneta_phylink_ops);
+ if (IS_ERR(phylink)) {
+@@ -4477,6 +4513,7 @@ static int mvneta_probe(struct platform_
+ pp = netdev_priv(dev);
+ spin_lock_init(&pp->lock);
+ pp->phylink = phylink;
++ pp->comphy = comphy;
+ pp->phy_interface = phy_mode;
+ pp->dn = dn;
+