netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: mvpp2: Implement RXAUI Support
@ 2019-08-01 20:45 Matt Pelland
  2019-08-01 20:45 ` [PATCH 1/2] net: mvpp2: implement RXAUI support Matt Pelland
  2019-08-01 20:45 ` [PATCH 2/2] net: mvpp2: support multiple comphy lanes Matt Pelland
  0 siblings, 2 replies; 5+ messages in thread
From: Matt Pelland @ 2019-08-01 20:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, maxime.chevallier, antoine.tenart

This patch set implements support for configuring Marvell's mvpp2 hardware for
RXAUI operation. There are two other patches necessary for this to work
correctly that concern Marvell's cp110 comphy that were emailed to the general
linux-kernel mailing list earlier on. I can post them here if need be. This
patch set was successfully tested on a Marvell Armada 7040 based platform.

Cheers,
Matt



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] net: mvpp2: implement RXAUI support
  2019-08-01 20:45 [PATCH] net: mvpp2: Implement RXAUI Support Matt Pelland
@ 2019-08-01 20:45 ` Matt Pelland
  2019-08-05 18:20   ` David Miller
  2019-08-01 20:45 ` [PATCH 2/2] net: mvpp2: support multiple comphy lanes Matt Pelland
  1 sibling, 1 reply; 5+ messages in thread
From: Matt Pelland @ 2019-08-01 20:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, maxime.chevallier, antoine.tenart, Matt Pelland

Marvell's mvpp2 packet processor supports RXAUI on port zero in a
similar manner to the existing 10G protocols that have already been
implemented. This patch implements the miscellaneous extra configuration
steps required for RXAUI operation.

Signed-off-by: Matt Pelland <mpelland@starry.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |  1 +
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 30 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index 4d9564ba68f6..256e7c796631 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -481,6 +481,7 @@
 #define MVPP22_XLG_CTRL4_REG			0x184
 #define     MVPP22_XLG_CTRL4_FWD_FC		BIT(5)
 #define     MVPP22_XLG_CTRL4_FWD_PFC		BIT(6)
+#define     MVPP22_XLG_CTRL4_USE_XPCS		BIT(8)
 #define     MVPP22_XLG_CTRL4_MACMODSELECT_GMAC	BIT(12)
 #define     MVPP22_XLG_CTRL4_EN_IDLE_CHECK	BIT(14)
 
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index e9d8ffe897e9..8b633af4a684 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -968,6 +968,7 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
 static bool mvpp2_is_xlg(phy_interface_t interface)
 {
 	return interface == PHY_INTERFACE_MODE_10GKR ||
+	       interface == PHY_INTERFACE_MODE_RXAUI ||
 	       interface == PHY_INTERFACE_MODE_XAUI;
 }
 
@@ -1008,6 +1009,27 @@ static void mvpp22_gop_init_sgmii(struct mvpp2_port *port)
 	}
 }
 
+static void mvpp22_gop_init_rxaui(struct mvpp2_port *port)
+{
+	struct mvpp2 *priv = port->priv;
+	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
+	u32 val;
+
+	val = readl(xpcs + MVPP22_XPCS_CFG0);
+	val &= ~MVPP22_XPCS_CFG0_RESET_DIS;
+	writel(val, xpcs + MVPP22_XPCS_CFG0);
+
+	val = readl(xpcs + MVPP22_XPCS_CFG0);
+	val &= ~(MVPP22_XPCS_CFG0_PCS_MODE(0x3) |
+		 MVPP22_XPCS_CFG0_ACTIVE_LANE(0x3));
+	val |= MVPP22_XPCS_CFG0_ACTIVE_LANE(2);
+	writel(val, xpcs + MVPP22_XPCS_CFG0);
+
+	val = readl(xpcs + MVPP22_XPCS_CFG0);
+	val |= MVPP22_XPCS_CFG0_RESET_DIS;
+	writel(val, xpcs + MVPP22_XPCS_CFG0);
+}
+
 static void mvpp22_gop_init_10gkr(struct mvpp2_port *port)
 {
 	struct mvpp2 *priv = port->priv;
@@ -1053,6 +1075,9 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
 	case PHY_INTERFACE_MODE_2500BASEX:
 		mvpp22_gop_init_sgmii(port);
 		break;
+	case PHY_INTERFACE_MODE_RXAUI:
+		mvpp22_gop_init_rxaui(port);
+		break;
 	case PHY_INTERFACE_MODE_10GKR:
 		if (port->gop_id != 0)
 			goto invalid_conf;
@@ -4570,6 +4595,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
 	switch (state->interface) {
 	case PHY_INTERFACE_MODE_10GKR:
 	case PHY_INTERFACE_MODE_XAUI:
+	case PHY_INTERFACE_MODE_RXAUI:
 		if (port->gop_id != 0)
 			goto empty_set;
 		break;
@@ -4592,6 +4618,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
 	switch (state->interface) {
 	case PHY_INTERFACE_MODE_10GKR:
 	case PHY_INTERFACE_MODE_XAUI:
+	case PHY_INTERFACE_MODE_RXAUI:
 	case PHY_INTERFACE_MODE_NA:
 		if (port->gop_id == 0) {
 			phylink_set(mask, 10000baseT_Full);
@@ -4744,6 +4771,9 @@ static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
 	ctrl4 |= MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC |
 		 MVPP22_XLG_CTRL4_EN_IDLE_CHECK;
 
+	if (state->interface == PHY_INTERFACE_MODE_RXAUI)
+		ctrl4 |= MVPP22_XLG_CTRL4_USE_XPCS;
+
 	if (old_ctrl0 != ctrl0)
 		writel(ctrl0, port->base + MVPP22_XLG_CTRL0_REG);
 	if (old_ctrl4 != ctrl4)
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] net: mvpp2: support multiple comphy lanes
  2019-08-01 20:45 [PATCH] net: mvpp2: Implement RXAUI Support Matt Pelland
  2019-08-01 20:45 ` [PATCH 1/2] net: mvpp2: implement RXAUI support Matt Pelland
@ 2019-08-01 20:45 ` Matt Pelland
  2019-08-02 15:22   ` Maxime Chevallier
  1 sibling, 1 reply; 5+ messages in thread
From: Matt Pelland @ 2019-08-01 20:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, maxime.chevallier, antoine.tenart, Matt Pelland

mvpp 2.2 supports RXAUI which requires a pair of serdes lanes instead of
the usual single lane required by other interface modes. This patch
expands the number of lanes that can be associated to a port so that
both lanes are correctly configured at the appropriate times when RXAUI
is in use.

Signed-off-by: Matt Pelland <mpelland@starry.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |  7 +-
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 66 +++++++++++++------
 2 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index 256e7c796631..9ae2b3d9d0c7 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -655,6 +655,11 @@
 #define MVPP2_F_LOOPBACK		BIT(0)
 #define MVPP2_F_DT_COMPAT		BIT(1)
 
+/* MVPP22 supports RXAUI which requires two comphy lanes, all other modes
+ * require one.
+ */
+#define MVPP22_MAX_COMPHYS		2
+
 /* Marvell tag types */
 enum mvpp2_tag_type {
 	MVPP2_TAG_TYPE_NONE = 0,
@@ -935,7 +940,7 @@ struct mvpp2_port {
 	phy_interface_t phy_interface;
 	struct phylink *phylink;
 	struct phylink_config phylink_config;
-	struct phy *comphy;
+	struct phy *comphys[MVPP22_MAX_COMPHYS];
 
 	struct mvpp2_bm_pool *pool_long;
 	struct mvpp2_bm_pool *pool_short;
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 8b633af4a684..97dfe2e71b03 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1186,17 +1186,40 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
  */
 static int mvpp22_comphy_init(struct mvpp2_port *port)
 {
-	int ret;
+	int i, ret;
 
-	if (!port->comphy)
-		return 0;
+	for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
+		if (!port->comphys[i])
+			return 0;
 
-	ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
-			       port->phy_interface);
-	if (ret)
-		return ret;
+		ret = phy_set_mode_ext(port->comphys[i],
+				       PHY_MODE_ETHERNET,
+				       port->phy_interface);
+		if (ret)
+			return ret;
 
-	return phy_power_on(port->comphy);
+		ret = phy_power_on(port->comphys[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int mvpp22_comphy_deinit(struct mvpp2_port *port)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
+		if (!port->comphys[i])
+			return 0;
+
+		ret = phy_power_off(port->comphys[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static void mvpp2_port_enable(struct mvpp2_port *port)
@@ -3375,7 +3398,9 @@ static void mvpp2_stop_dev(struct mvpp2_port *port)
 
 	if (port->phylink)
 		phylink_stop(port->phylink);
-	phy_power_off(port->comphy);
+
+	if (port->priv->hw_version == MVPP22)
+		mvpp22_comphy_deinit(port);
 }
 
 static int mvpp2_check_ringparam_valid(struct net_device *dev,
@@ -4947,7 +4972,7 @@ static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
 		port->phy_interface = state->interface;
 
 		/* Reconfigure the serdes lanes */
-		phy_power_off(port->comphy);
+		mvpp22_comphy_deinit(port);
 		mvpp22_mode_reconfigure(port);
 	}
 
@@ -5038,7 +5063,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 			    struct fwnode_handle *port_fwnode,
 			    struct mvpp2 *priv)
 {
-	struct phy *comphy = NULL;
 	struct mvpp2_port *port;
 	struct mvpp2_port_pcpu *port_pcpu;
 	struct device_node *port_node = to_of_node(port_fwnode);
@@ -5085,14 +5109,20 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 		goto err_free_netdev;
 	}
 
+	port = netdev_priv(dev);
+
 	if (port_node) {
-		comphy = devm_of_phy_get(&pdev->dev, port_node, NULL);
-		if (IS_ERR(comphy)) {
-			if (PTR_ERR(comphy) == -EPROBE_DEFER) {
-				err = -EPROBE_DEFER;
-				goto err_free_netdev;
+		for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
+			port->comphys[i] = devm_of_phy_get_by_index(&pdev->dev,
+								    port_node,
+								    i);
+			if (IS_ERR(port->comphys[i])) {
+				err = PTR_ERR(port->comphys[i]);
+				port->comphys[i] = NULL;
+				if (err == -EPROBE_DEFER)
+					goto err_free_netdev;
+				err = 0;
 			}
-			comphy = NULL;
 		}
 	}
 
@@ -5107,7 +5137,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 	dev->netdev_ops = &mvpp2_netdev_ops;
 	dev->ethtool_ops = &mvpp2_eth_tool_ops;
 
-	port = netdev_priv(dev);
 	port->dev = dev;
 	port->fwnode = port_fwnode;
 	port->has_phy = !!of_find_property(port_node, "phy", NULL);
@@ -5144,7 +5173,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
 	port->of_node = port_node;
 	port->phy_interface = phy_mode;
-	port->comphy = comphy;
 
 	if (priv->hw_version == MVPP21) {
 		port->base = devm_platform_ioremap_resource(pdev, 2 + id);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] net: mvpp2: support multiple comphy lanes
  2019-08-01 20:45 ` [PATCH 2/2] net: mvpp2: support multiple comphy lanes Matt Pelland
@ 2019-08-02 15:22   ` Maxime Chevallier
  0 siblings, 0 replies; 5+ messages in thread
From: Maxime Chevallier @ 2019-08-02 15:22 UTC (permalink / raw)
  To: Matt Pelland; +Cc: netdev, davem, antoine.tenart

Hello Matt,

On Thu,  1 Aug 2019 16:45:23 -0400
Matt Pelland <mpelland@starry.com> wrote:

>mvpp 2.2 supports RXAUI which requires a pair of serdes lanes instead of
>the usual single lane required by other interface modes. This patch
>expands the number of lanes that can be associated to a port so that
>both lanes are correctly configured at the appropriate times when RXAUI
>is in use.

Thanks for the patch, it's nice to see RXAUI support moving forward.

I'll give your patches a test on my setup, although I never really got
something stable, it might simply be due to the particular hardware I
have access to.

I do have some comments below :

>Signed-off-by: Matt Pelland <mpelland@starry.com>
>---
> drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |  7 +-
> .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 66 +++++++++++++------
> 2 files changed, 53 insertions(+), 20 deletions(-)
>
>diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
>index 256e7c796631..9ae2b3d9d0c7 100644
>--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
>+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
>@@ -655,6 +655,11 @@
> #define MVPP2_F_LOOPBACK		BIT(0)
> #define MVPP2_F_DT_COMPAT		BIT(1)
> 
>+/* MVPP22 supports RXAUI which requires two comphy lanes, all other modes
>+ * require one.
>+ */
>+#define MVPP22_MAX_COMPHYS		2

This driver is "supposed" to support XAUI too, at least it appears in
the list of modes we handle. XAUI uses 4 lanes, maybe we could bump the
max number of lanes to 4.

> /* Marvell tag types */
> enum mvpp2_tag_type {
> 	MVPP2_TAG_TYPE_NONE = 0,
>@@ -935,7 +940,7 @@ struct mvpp2_port {
> 	phy_interface_t phy_interface;
> 	struct phylink *phylink;
> 	struct phylink_config phylink_config;
>-	struct phy *comphy;
>+	struct phy *comphys[MVPP22_MAX_COMPHYS];
> 
> 	struct mvpp2_bm_pool *pool_long;
> 	struct mvpp2_bm_pool *pool_short;
>diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
>index 8b633af4a684..97dfe2e71b03 100644
>--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
>+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
>@@ -1186,17 +1186,40 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
>  */
> static int mvpp22_comphy_init(struct mvpp2_port *port)
> {
>-	int ret;
>+	int i, ret;
> 
>-	if (!port->comphy)
>-		return 0;
>+	for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
>+		if (!port->comphys[i])
>+			return 0;
> 
>-	ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
>-			       port->phy_interface);
>-	if (ret)
>-		return ret;
>+		ret = phy_set_mode_ext(port->comphys[i],
>+				       PHY_MODE_ETHERNET,
>+				       port->phy_interface);
>+		if (ret)
>+			return ret;
> 
>-	return phy_power_on(port->comphy);
>+		ret = phy_power_on(port->comphys[i]);
>+		if (ret)
>+			return ret;
>+	}
>+
>+	return 0;
>+}

It could be good to add some sanity check, to make sure we do have 2
comphy lanes available when configuring RXAUI mode (and 4 for XAUI).

>+static int mvpp22_comphy_deinit(struct mvpp2_port *port)
>+{
>+	int i, ret;
>+
>+	for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
>+		if (!port->comphys[i])
>+			return 0;
>+
>+		ret = phy_power_off(port->comphys[i]);
>+		if (ret)
>+			return ret;
>+	}
>+
>+	return 0;
> }
> 
> static void mvpp2_port_enable(struct mvpp2_port *port)
>@@ -3375,7 +3398,9 @@ static void mvpp2_stop_dev(struct mvpp2_port *port)
> 
> 	if (port->phylink)
> 		phylink_stop(port->phylink);
>-	phy_power_off(port->comphy);
>+
>+	if (port->priv->hw_version == MVPP22)
>+		mvpp22_comphy_deinit(port);
> }
> 
> static int mvpp2_check_ringparam_valid(struct net_device *dev,
>@@ -4947,7 +4972,7 @@ static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
> 		port->phy_interface = state->interface;
> 
> 		/* Reconfigure the serdes lanes */
>-		phy_power_off(port->comphy);
>+		mvpp22_comphy_deinit(port);
> 		mvpp22_mode_reconfigure(port);
> 	}
> 
>@@ -5038,7 +5063,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
> 			    struct fwnode_handle *port_fwnode,
> 			    struct mvpp2 *priv)
> {
>-	struct phy *comphy = NULL;
> 	struct mvpp2_port *port;
> 	struct mvpp2_port_pcpu *port_pcpu;
> 	struct device_node *port_node = to_of_node(port_fwnode);
>@@ -5085,14 +5109,20 @@ static int mvpp2_port_probe(struct platform_device *pdev,
> 		goto err_free_netdev;
> 	}
> 
>+	port = netdev_priv(dev);
>+
> 	if (port_node) {
>-		comphy = devm_of_phy_get(&pdev->dev, port_node, NULL);
>-		if (IS_ERR(comphy)) {
>-			if (PTR_ERR(comphy) == -EPROBE_DEFER) {
>-				err = -EPROBE_DEFER;
>-				goto err_free_netdev;
>+		for (i = 0; i < ARRAY_SIZE(port->comphys); i++) {
>+			port->comphys[i] = devm_of_phy_get_by_index(&pdev->dev,
>+								    port_node,
>+								    i);
>+			if (IS_ERR(port->comphys[i])) {
>+				err = PTR_ERR(port->comphys[i]);
>+				port->comphys[i] = NULL;
>+				if (err == -EPROBE_DEFER)
>+					goto err_free_netdev;
>+				err = 0;
> 			}
>-			comphy = NULL;
> 		}
> 	}
> 
>@@ -5107,7 +5137,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
> 	dev->netdev_ops = &mvpp2_netdev_ops;
> 	dev->ethtool_ops = &mvpp2_eth_tool_ops;
> 
>-	port = netdev_priv(dev);
> 	port->dev = dev;
> 	port->fwnode = port_fwnode;
> 	port->has_phy = !!of_find_property(port_node, "phy", NULL);
>@@ -5144,7 +5173,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
> 
> 	port->of_node = port_node;
> 	port->phy_interface = phy_mode;
>-	port->comphy = comphy;
> 
> 	if (priv->hw_version == MVPP21) {
> 		port->base = devm_platform_ioremap_resource(pdev, 2 + id);



-- 
Maxime Chevallier, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] net: mvpp2: implement RXAUI support
  2019-08-01 20:45 ` [PATCH 1/2] net: mvpp2: implement RXAUI support Matt Pelland
@ 2019-08-05 18:20   ` David Miller
  0 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2019-08-05 18:20 UTC (permalink / raw)
  To: mpelland; +Cc: netdev, maxime.chevallier, antoine.tenart

From: Matt Pelland <mpelland@starry.com>
Date: Thu,  1 Aug 2019 16:45:22 -0400

> +static void mvpp22_gop_init_rxaui(struct mvpp2_port *port)
> +{
> +	struct mvpp2 *priv = port->priv;
> +	void __iomem *xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
> +	u32 val;

Reverse christmas tree please.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-08-05 18:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-01 20:45 [PATCH] net: mvpp2: Implement RXAUI Support Matt Pelland
2019-08-01 20:45 ` [PATCH 1/2] net: mvpp2: implement RXAUI support Matt Pelland
2019-08-05 18:20   ` David Miller
2019-08-01 20:45 ` [PATCH 2/2] net: mvpp2: support multiple comphy lanes Matt Pelland
2019-08-02 15:22   ` Maxime Chevallier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).