diff mbox series

[net-next,2/2] net: ethernet: cortina: Implement .set_pauseparam()

Message ID 20240509-gemini-ethernet-fix-tso-v1-2-10cd07b54d1c@linaro.org (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: ethernet: cortina: TSO and pause param | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 926 this patch: 926
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: linux-arm-kernel@lists.infradead.org
netdev/build_clang success Errors and warnings before: 937 this patch: 937
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 937 this patch: 937
netdev/checkpatch warning CHECK: Alignment should match open parenthesis CHECK: Please don't use multiple blank lines
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 3 this patch: 3
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-05-09--15-00 (tests: 1006)

Commit Message

Linus Walleij May 9, 2024, 7:48 a.m. UTC
The Cortina Gemini ethernet can very well set up TX or RX
pausing, so add this functionality to the driver in a
.set_pauseparam() callback.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/net/ethernet/cortina/gemini.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Andrew Lunn May 9, 2024, 8:08 p.m. UTC | #1
On Thu, May 09, 2024 at 09:48:38AM +0200, Linus Walleij wrote:
> The Cortina Gemini ethernet can very well set up TX or RX
> pausing, so add this functionality to the driver in a
> .set_pauseparam() callback.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/net/ethernet/cortina/gemini.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
> index 599de7914122..c732e985055f 100644
> --- a/drivers/net/ethernet/cortina/gemini.c
> +++ b/drivers/net/ethernet/cortina/gemini.c
> @@ -2138,6 +2138,28 @@ static void gmac_get_pauseparam(struct net_device *netdev,
>  	pparam->autoneg = true;
>  }
>  
> +static int gmac_set_pauseparam(struct net_device *netdev,
> +				struct ethtool_pauseparam *pparam)
> +{
> +	struct gemini_ethernet_port *port = netdev_priv(netdev);
> +	union gmac_config0 config0;
> +
> +	config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0);
> +
> +	if (pparam->rx_pause)
> +		config0.bits.rx_fc_en = 1;
> +	if (pparam->tx_pause)
> +		config0.bits.tx_fc_en = 1;
> +	/* We only support autonegotiation */
> +	if (!pparam->autoneg)
> +		return -EINVAL;
> +
> +	writel(config0.bits32, port->gmac_base + GMAC_CONFIG0);

Everybody gets pause wrong. You even say it yourself:

> +	/* We only support autonegotiation */

After connecting to the PHY, you need to call
phy_support_asym_pause(), to let phylib know the MAC support
asymmetric pause. The PHY will then advertise this to the link peer.
Gemini does seem to be doing that already.

When auto-neg is complete, it calls the adjust link callback. Ideally
you then want to call phy_get_pause() which gives you the results of
the negotiation, and so how to configure the MAC. gmac_speed_set()
kind of does this, but it directly reads PHY registers, rather than
asking phylib. It would be nice to update this code.

This ethtool call allows you to change what the device advertises to
the link partner. You should pass this onto phylib using
phy_set_asym_pause(). If something has changed, phylib will kick off a
new auto-neg, and then call the adjust link callback so you can
configure the hardware with the new negotiation results. It is
unlikely that gmac_set_pauseparam() needs to change the hardware
configuration when pparam->autoneg is true.

If pparam->autoneg is false, that means we are not using auto-neg for
pause, and then you can directly program the MAC hardware. But it does
not look like you intend to support this, which is fine.

    Andrew

---
pw-bot: cr
diff mbox series

Patch

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 599de7914122..c732e985055f 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2138,6 +2138,28 @@  static void gmac_get_pauseparam(struct net_device *netdev,
 	pparam->autoneg = true;
 }
 
+static int gmac_set_pauseparam(struct net_device *netdev,
+				struct ethtool_pauseparam *pparam)
+{
+	struct gemini_ethernet_port *port = netdev_priv(netdev);
+	union gmac_config0 config0;
+
+	config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0);
+
+	if (pparam->rx_pause)
+		config0.bits.rx_fc_en = 1;
+	if (pparam->tx_pause)
+		config0.bits.tx_fc_en = 1;
+	/* We only support autonegotiation */
+	if (!pparam->autoneg)
+		return -EINVAL;
+
+	writel(config0.bits32, port->gmac_base + GMAC_CONFIG0);
+
+	return 0;
+}
+
+
 static void gmac_get_ringparam(struct net_device *netdev,
 			       struct ethtool_ringparam *rp,
 			       struct kernel_ethtool_ringparam *kernel_rp,
@@ -2258,6 +2280,7 @@  static const struct ethtool_ops gmac_351x_ethtool_ops = {
 	.set_link_ksettings = gmac_set_ksettings,
 	.nway_reset	= gmac_nway_reset,
 	.get_pauseparam	= gmac_get_pauseparam,
+	.set_pauseparam = gmac_set_pauseparam,
 	.get_ringparam	= gmac_get_ringparam,
 	.set_ringparam	= gmac_set_ringparam,
 	.get_coalesce	= gmac_get_coalesce,