From: Wojciech Drewek <wojciech.drewek@intel.com>
To: Romain Gantois <romain.gantois@bootlin.com>,
<davem@davemloft.net>, "Rob Herring" <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Jakub Kicinski <kuba@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
<thomas.petazzoni@bootlin.com>, Andrew Lunn <andrew@lunn.ch>,
"Florian Fainelli" <f.fainelli@gmail.com>,
Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
<linux-arm-kernel@lists.infradead.org>,
Vladimir Oltean <vladimir.oltean@nxp.com>,
Luka Perkov <luka.perkov@sartura.hr>,
Robert Marko <robert.marko@sartura.hr>,
Andy Gross <agross@kernel.org>,
Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konrad.dybcio@somainline.org>
Subject: Re: [PATCH net-next v3 4/8] net: qualcomm: ipqess: Add Ethtool ops to IPQESS port netdevices
Date: Wed, 15 Nov 2023 14:07:39 +0100 [thread overview]
Message-ID: <271ef021-c0f7-4fd3-a64d-e94e24d46516@intel.com> (raw)
In-Reply-To: <20231114105600.1012056-5-romain.gantois@bootlin.com>
On 14.11.2023 11:55, Romain Gantois wrote:
> The IPQESS driver registers one netdevice for each front-facing switch
> port. Add support for several ethtool operations to these netdevices.
>
> Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
> ---
> drivers/net/ethernet/qualcomm/ipqess/Makefile | 2 +-
> .../ethernet/qualcomm/ipqess/ipqess_ethtool.c | 245 ++++++++++++++++++
> .../ethernet/qualcomm/ipqess/ipqess_port.c | 1 +
> .../ethernet/qualcomm/ipqess/ipqess_port.h | 3 +
> 4 files changed, 250 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
>
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/Makefile b/drivers/net/ethernet/qualcomm/ipqess/Makefile
> index f389080cc5aa..6253f1b0ffd2 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/Makefile
> +++ b/drivers/net/ethernet/qualcomm/ipqess/Makefile
> @@ -5,4 +5,4 @@
>
> obj-$(CONFIG_QCOM_IPQ4019_ESS) += ipqess.o
>
> -ipqess-objs := ipqess_port.o ipqess_switch.o ipqess_edma.o
> +ipqess-objs := ipqess_port.o ipqess_switch.o ipqess_edma.o ipqess_ethtool.o
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c b/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
> new file mode 100644
> index 000000000000..06a8f2cccc4e
> --- /dev/null
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Ethtool operations for a single switch port
> + *
> + * Copyright (c) 2023, Romain Gantois <romain.gantois@bootlin.com>
> + * Based on net/dsa
> + */
> +
> +#include <net/selftests.h>
> +
> +#include "ipqess_port.h"
> +
> +static void ipqess_port_get_drvinfo(struct net_device *dev,
> + struct ethtool_drvinfo *drvinfo)
> +{
> + strscpy(drvinfo->driver, "qca8k-ipqess", sizeof(drvinfo->driver));
> + strscpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info));
> +}
> +
> +static int ipqess_port_nway_reset(struct net_device *dev)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_nway_reset(port->pl);
> +}
> +
> +static const char ipqess_gstrings_base_stats[][ETH_GSTRING_LEN] = {
> + "tx_packets",
> + "tx_bytes",
> + "rx_packets",
> + "rx_bytes",
> +};
> +
> +static void ipqess_port_get_strings(struct net_device *dev,
> + u32 stringset, u8 *data)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> + int i;
> +
> + if (stringset == ETH_SS_STATS) {
> + memcpy(data, &ipqess_gstrings_base_stats,
> + sizeof(ipqess_gstrings_base_stats));
> +
> + if (stringset != ETH_SS_STATS)
> + return;
> +
> + for (i = 0; i < priv->info->mib_count; i++)
> + memcpy(data + (4 + i) * ETH_GSTRING_LEN,
> + ar8327_mib[i].name,
> + ETH_GSTRING_LEN);
> +
> + } else if (stringset == ETH_SS_TEST) {
> + net_selftest_get_strings(data);
> + }
> +}
> +
> +static void ipqess_port_get_ethtool_stats(struct net_device *dev,
> + struct ethtool_stats *stats,
> + uint64_t *data)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> + const struct qca8k_mib_desc *mib;
> + struct pcpu_sw_netstats *s;
> + unsigned int start;
> + u32 reg, c, val;
> + u32 hi = 0;
> + int ret;
> + int i;
> +
> + for_each_possible_cpu(i) {
> + u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
> +
> + s = per_cpu_ptr(dev->tstats, i);
> + do {
> + start = u64_stats_fetch_begin(&s->syncp);
> + tx_packets = u64_stats_read(&s->tx_packets);
> + tx_bytes = u64_stats_read(&s->tx_bytes);
> + rx_packets = u64_stats_read(&s->rx_packets);
> + rx_bytes = u64_stats_read(&s->rx_bytes);
> + } while (u64_stats_fetch_retry(&s->syncp, start));
> + data[0] += tx_packets;
> + data[1] += tx_bytes;
> + data[2] += rx_packets;
> + data[3] += rx_bytes;
> + }
> +
> + for (c = 0; c < priv->info->mib_count; c++) {
> + mib = &ar8327_mib[c];
> + reg = QCA8K_PORT_MIB_COUNTER(port->index) + mib->offset;
> +
> + ret = qca8k_read(priv, reg, &val);
> + if (ret < 0)
if (ret)
> + continue;
> +
> + if (mib->size == 2) {
> + ret = qca8k_read(priv, reg + 4, &hi);
> + if (ret < 0)
same
> + continue;
> + }
> +
> + data[4 + c] = val;
> + if (mib->size == 2)
> + data[4 + c] |= (u64)hi << 32;
> + }
> +}
> +
> +static int ipqess_port_get_sset_count(struct net_device *dev, int sset)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> +
> + if (sset == ETH_SS_STATS) {
> + int count = 0;
> +
> + if (sset != ETH_SS_STATS)
> + count = 0;
> + else
> + count = priv->info->mib_count;
> +
> + if (count < 0)
> + return count;
> +
> + return count + 4;
> + } else if (sset == ETH_SS_TEST) {
> + return net_selftest_get_count();
> + }
> +
> + return -EOPNOTSUPP;
> +}
> +
> +static int ipqess_port_set_wol(struct net_device *dev,
> + struct ethtool_wolinfo *w)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_set_wol(port->pl, w);
> +}
> +
> +static void ipqess_port_get_wol(struct net_device *dev,
> + struct ethtool_wolinfo *w)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + phylink_ethtool_get_wol(port->pl, w);
> +}
> +
> +static int ipqess_port_set_eee(struct net_device *dev, struct ethtool_eee *eee)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + int ret;
> + u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port->index);
> + struct qca8k_priv *priv = port->sw->priv;
> + u32 lpi_ctl1;
RCT
> +
> + /* Port's PHY and MAC both need to be EEE capable */
> + if (!dev->phydev || !port->pl)
> + return -ENODEV;
> +
> + mutex_lock(&priv->reg_mutex);
> + lpi_ctl1 = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &lpi_ctl1);
> + if (lpi_ctl1 < 0) {
if (lpi_ctl1)
> + mutex_unlock(&priv->reg_mutex);
> + return ret;
ret is not initialized at this point
> + }
> +
> + if (eee->tx_lpi_enabled && eee->eee_enabled)
> + lpi_ctl1 |= lpi_en;
> + else
> + lpi_ctl1 &= ~lpi_en;
> + ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, lpi_ctl1);
> + mutex_unlock(&priv->reg_mutex);
> +
> + if (ret)
> + return ret;
> +
> + return phylink_ethtool_set_eee(port->pl, eee);
> +}
> +
> +static int ipqess_port_get_eee(struct net_device *dev, struct ethtool_eee *e)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + /* Port's PHY and MAC both need to be EEE capable */
> + if (!dev->phydev || !port->pl)
> + return -ENODEV;
> +
> + return phylink_ethtool_get_eee(port->pl, e);
> +}
> +
> +static int ipqess_port_get_link_ksettings(struct net_device *dev,
> + struct ethtool_link_ksettings *cmd)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_ksettings_get(port->pl, cmd);
> +}
> +
> +static int ipqess_port_set_link_ksettings(struct net_device *dev,
> + const struct ethtool_link_ksettings *cmd)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_ksettings_set(port->pl, cmd);
> +}
> +
> +static void ipqess_port_get_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pause)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + phylink_ethtool_get_pauseparam(port->pl, pause);
> +}
> +
> +static int ipqess_port_set_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pause)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_set_pauseparam(port->pl, pause);
> +}
> +
> +static const struct ethtool_ops ipqess_port_ethtool_ops = {
> + .get_drvinfo = ipqess_port_get_drvinfo,
> + .nway_reset = ipqess_port_nway_reset,
> + .get_link = ethtool_op_get_link,
> + .get_strings = ipqess_port_get_strings,
> + .get_ethtool_stats = ipqess_port_get_ethtool_stats,
> + .get_sset_count = ipqess_port_get_sset_count,
> + .self_test = net_selftest,
> + .set_wol = ipqess_port_set_wol,
> + .get_wol = ipqess_port_get_wol,
> + .set_eee = ipqess_port_set_eee,
> + .get_eee = ipqess_port_get_eee,
> + .get_link_ksettings = ipqess_port_get_link_ksettings,
> + .set_link_ksettings = ipqess_port_set_link_ksettings,
> + .get_pauseparam = ipqess_port_get_pauseparam,
> + .set_pauseparam = ipqess_port_set_pauseparam,
> +};
> +
> +void ipqess_port_set_ethtool_ops(struct net_device *netdev)
> +{
> + netdev->ethtool_ops = &ipqess_port_ethtool_ops;
> +}
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> index f0f5fe3a7c24..52d7baa7cae0 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> @@ -684,6 +684,7 @@ int ipqess_port_register(struct ipqess_switch *sw,
> netdev->dev.of_node = port->dn;
>
> netdev->rtnl_link_ops = &ipqess_port_link_ops;
> + ipqess_port_set_ethtool_ops(netdev);
>
> netdev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
> if (!netdev->tstats) {
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> index 26bac45dd811..19d4b5d73625 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> @@ -59,4 +59,7 @@ int ipqess_port_register(struct ipqess_switch *sw,
> struct device_node *port_node);
> void ipqess_port_unregister(struct ipqess_port *port);
>
> +/* Defined in ipqess_ethtool.c */
> +void ipqess_port_set_ethtool_ops(struct net_device *netdev);
> +
> #endif
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Wojciech Drewek <wojciech.drewek@intel.com>
To: Romain Gantois <romain.gantois@bootlin.com>,
<davem@davemloft.net>, "Rob Herring" <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: Jakub Kicinski <kuba@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
<thomas.petazzoni@bootlin.com>, Andrew Lunn <andrew@lunn.ch>,
"Florian Fainelli" <f.fainelli@gmail.com>,
Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
<linux-arm-kernel@lists.infradead.org>,
Vladimir Oltean <vladimir.oltean@nxp.com>,
Luka Perkov <luka.perkov@sartura.hr>,
Robert Marko <robert.marko@sartura.hr>,
Andy Gross <agross@kernel.org>,
Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konrad.dybcio@somainline.org>
Subject: Re: [PATCH net-next v3 4/8] net: qualcomm: ipqess: Add Ethtool ops to IPQESS port netdevices
Date: Wed, 15 Nov 2023 14:07:39 +0100 [thread overview]
Message-ID: <271ef021-c0f7-4fd3-a64d-e94e24d46516@intel.com> (raw)
In-Reply-To: <20231114105600.1012056-5-romain.gantois@bootlin.com>
On 14.11.2023 11:55, Romain Gantois wrote:
> The IPQESS driver registers one netdevice for each front-facing switch
> port. Add support for several ethtool operations to these netdevices.
>
> Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
> ---
> drivers/net/ethernet/qualcomm/ipqess/Makefile | 2 +-
> .../ethernet/qualcomm/ipqess/ipqess_ethtool.c | 245 ++++++++++++++++++
> .../ethernet/qualcomm/ipqess/ipqess_port.c | 1 +
> .../ethernet/qualcomm/ipqess/ipqess_port.h | 3 +
> 4 files changed, 250 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
>
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/Makefile b/drivers/net/ethernet/qualcomm/ipqess/Makefile
> index f389080cc5aa..6253f1b0ffd2 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/Makefile
> +++ b/drivers/net/ethernet/qualcomm/ipqess/Makefile
> @@ -5,4 +5,4 @@
>
> obj-$(CONFIG_QCOM_IPQ4019_ESS) += ipqess.o
>
> -ipqess-objs := ipqess_port.o ipqess_switch.o ipqess_edma.o
> +ipqess-objs := ipqess_port.o ipqess_switch.o ipqess_edma.o ipqess_ethtool.o
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c b/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
> new file mode 100644
> index 000000000000..06a8f2cccc4e
> --- /dev/null
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_ethtool.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Ethtool operations for a single switch port
> + *
> + * Copyright (c) 2023, Romain Gantois <romain.gantois@bootlin.com>
> + * Based on net/dsa
> + */
> +
> +#include <net/selftests.h>
> +
> +#include "ipqess_port.h"
> +
> +static void ipqess_port_get_drvinfo(struct net_device *dev,
> + struct ethtool_drvinfo *drvinfo)
> +{
> + strscpy(drvinfo->driver, "qca8k-ipqess", sizeof(drvinfo->driver));
> + strscpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info));
> +}
> +
> +static int ipqess_port_nway_reset(struct net_device *dev)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_nway_reset(port->pl);
> +}
> +
> +static const char ipqess_gstrings_base_stats[][ETH_GSTRING_LEN] = {
> + "tx_packets",
> + "tx_bytes",
> + "rx_packets",
> + "rx_bytes",
> +};
> +
> +static void ipqess_port_get_strings(struct net_device *dev,
> + u32 stringset, u8 *data)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> + int i;
> +
> + if (stringset == ETH_SS_STATS) {
> + memcpy(data, &ipqess_gstrings_base_stats,
> + sizeof(ipqess_gstrings_base_stats));
> +
> + if (stringset != ETH_SS_STATS)
> + return;
> +
> + for (i = 0; i < priv->info->mib_count; i++)
> + memcpy(data + (4 + i) * ETH_GSTRING_LEN,
> + ar8327_mib[i].name,
> + ETH_GSTRING_LEN);
> +
> + } else if (stringset == ETH_SS_TEST) {
> + net_selftest_get_strings(data);
> + }
> +}
> +
> +static void ipqess_port_get_ethtool_stats(struct net_device *dev,
> + struct ethtool_stats *stats,
> + uint64_t *data)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> + const struct qca8k_mib_desc *mib;
> + struct pcpu_sw_netstats *s;
> + unsigned int start;
> + u32 reg, c, val;
> + u32 hi = 0;
> + int ret;
> + int i;
> +
> + for_each_possible_cpu(i) {
> + u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
> +
> + s = per_cpu_ptr(dev->tstats, i);
> + do {
> + start = u64_stats_fetch_begin(&s->syncp);
> + tx_packets = u64_stats_read(&s->tx_packets);
> + tx_bytes = u64_stats_read(&s->tx_bytes);
> + rx_packets = u64_stats_read(&s->rx_packets);
> + rx_bytes = u64_stats_read(&s->rx_bytes);
> + } while (u64_stats_fetch_retry(&s->syncp, start));
> + data[0] += tx_packets;
> + data[1] += tx_bytes;
> + data[2] += rx_packets;
> + data[3] += rx_bytes;
> + }
> +
> + for (c = 0; c < priv->info->mib_count; c++) {
> + mib = &ar8327_mib[c];
> + reg = QCA8K_PORT_MIB_COUNTER(port->index) + mib->offset;
> +
> + ret = qca8k_read(priv, reg, &val);
> + if (ret < 0)
if (ret)
> + continue;
> +
> + if (mib->size == 2) {
> + ret = qca8k_read(priv, reg + 4, &hi);
> + if (ret < 0)
same
> + continue;
> + }
> +
> + data[4 + c] = val;
> + if (mib->size == 2)
> + data[4 + c] |= (u64)hi << 32;
> + }
> +}
> +
> +static int ipqess_port_get_sset_count(struct net_device *dev, int sset)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + struct qca8k_priv *priv = port->sw->priv;
> +
> + if (sset == ETH_SS_STATS) {
> + int count = 0;
> +
> + if (sset != ETH_SS_STATS)
> + count = 0;
> + else
> + count = priv->info->mib_count;
> +
> + if (count < 0)
> + return count;
> +
> + return count + 4;
> + } else if (sset == ETH_SS_TEST) {
> + return net_selftest_get_count();
> + }
> +
> + return -EOPNOTSUPP;
> +}
> +
> +static int ipqess_port_set_wol(struct net_device *dev,
> + struct ethtool_wolinfo *w)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_set_wol(port->pl, w);
> +}
> +
> +static void ipqess_port_get_wol(struct net_device *dev,
> + struct ethtool_wolinfo *w)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + phylink_ethtool_get_wol(port->pl, w);
> +}
> +
> +static int ipqess_port_set_eee(struct net_device *dev, struct ethtool_eee *eee)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> + int ret;
> + u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port->index);
> + struct qca8k_priv *priv = port->sw->priv;
> + u32 lpi_ctl1;
RCT
> +
> + /* Port's PHY and MAC both need to be EEE capable */
> + if (!dev->phydev || !port->pl)
> + return -ENODEV;
> +
> + mutex_lock(&priv->reg_mutex);
> + lpi_ctl1 = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &lpi_ctl1);
> + if (lpi_ctl1 < 0) {
if (lpi_ctl1)
> + mutex_unlock(&priv->reg_mutex);
> + return ret;
ret is not initialized at this point
> + }
> +
> + if (eee->tx_lpi_enabled && eee->eee_enabled)
> + lpi_ctl1 |= lpi_en;
> + else
> + lpi_ctl1 &= ~lpi_en;
> + ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, lpi_ctl1);
> + mutex_unlock(&priv->reg_mutex);
> +
> + if (ret)
> + return ret;
> +
> + return phylink_ethtool_set_eee(port->pl, eee);
> +}
> +
> +static int ipqess_port_get_eee(struct net_device *dev, struct ethtool_eee *e)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + /* Port's PHY and MAC both need to be EEE capable */
> + if (!dev->phydev || !port->pl)
> + return -ENODEV;
> +
> + return phylink_ethtool_get_eee(port->pl, e);
> +}
> +
> +static int ipqess_port_get_link_ksettings(struct net_device *dev,
> + struct ethtool_link_ksettings *cmd)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_ksettings_get(port->pl, cmd);
> +}
> +
> +static int ipqess_port_set_link_ksettings(struct net_device *dev,
> + const struct ethtool_link_ksettings *cmd)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_ksettings_set(port->pl, cmd);
> +}
> +
> +static void ipqess_port_get_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pause)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + phylink_ethtool_get_pauseparam(port->pl, pause);
> +}
> +
> +static int ipqess_port_set_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pause)
> +{
> + struct ipqess_port *port = netdev_priv(dev);
> +
> + return phylink_ethtool_set_pauseparam(port->pl, pause);
> +}
> +
> +static const struct ethtool_ops ipqess_port_ethtool_ops = {
> + .get_drvinfo = ipqess_port_get_drvinfo,
> + .nway_reset = ipqess_port_nway_reset,
> + .get_link = ethtool_op_get_link,
> + .get_strings = ipqess_port_get_strings,
> + .get_ethtool_stats = ipqess_port_get_ethtool_stats,
> + .get_sset_count = ipqess_port_get_sset_count,
> + .self_test = net_selftest,
> + .set_wol = ipqess_port_set_wol,
> + .get_wol = ipqess_port_get_wol,
> + .set_eee = ipqess_port_set_eee,
> + .get_eee = ipqess_port_get_eee,
> + .get_link_ksettings = ipqess_port_get_link_ksettings,
> + .set_link_ksettings = ipqess_port_set_link_ksettings,
> + .get_pauseparam = ipqess_port_get_pauseparam,
> + .set_pauseparam = ipqess_port_set_pauseparam,
> +};
> +
> +void ipqess_port_set_ethtool_ops(struct net_device *netdev)
> +{
> + netdev->ethtool_ops = &ipqess_port_ethtool_ops;
> +}
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> index f0f5fe3a7c24..52d7baa7cae0 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.c
> @@ -684,6 +684,7 @@ int ipqess_port_register(struct ipqess_switch *sw,
> netdev->dev.of_node = port->dn;
>
> netdev->rtnl_link_ops = &ipqess_port_link_ops;
> + ipqess_port_set_ethtool_ops(netdev);
>
> netdev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
> if (!netdev->tstats) {
> diff --git a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> index 26bac45dd811..19d4b5d73625 100644
> --- a/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> +++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess_port.h
> @@ -59,4 +59,7 @@ int ipqess_port_register(struct ipqess_switch *sw,
> struct device_node *port_node);
> void ipqess_port_unregister(struct ipqess_port *port);
>
> +/* Defined in ipqess_ethtool.c */
> +void ipqess_port_set_ethtool_ops(struct net_device *netdev);
> +
> #endif
next prev parent reply other threads:[~2023-11-15 13:08 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-14 10:55 [PATCH net-next v3 0/8] net: qualcomm: ipqess: introduce Qualcomm IPQESS driver Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 10:55 ` [PATCH net-next v3 1/8] dt-bindings: net: Introduce the Qualcomm IPQESS Ethernet switch Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-16 12:22 ` Krzysztof Kozlowski
2023-11-16 12:22 ` Krzysztof Kozlowski
2023-11-14 10:55 ` [PATCH net-next v3 2/8] net: dsa: qca8k: Make the QCA8K hardware library available globally Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 18:15 ` Andrew Lunn
2023-11-14 18:15 ` Andrew Lunn
2023-11-14 10:55 ` [PATCH net-next v3 3/8] net: qualcomm: ipqess: introduce the Qualcomm IPQESS driver Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 19:10 ` Andrew Lunn
2023-11-14 19:10 ` Andrew Lunn
2023-11-15 14:24 ` Romain Gantois
2023-11-15 14:24 ` Romain Gantois
2023-11-15 12:55 ` Wojciech Drewek
2023-11-15 12:55 ` Wojciech Drewek
2023-11-15 15:07 ` Romain Gantois
2023-11-15 15:07 ` Romain Gantois
2023-11-16 14:39 ` Vladimir Oltean
2023-11-16 14:39 ` Vladimir Oltean
2023-11-15 18:11 ` Simon Horman
2023-11-15 18:11 ` Simon Horman
2023-11-16 16:08 ` kernel test robot
2023-11-16 16:08 ` kernel test robot
2023-11-16 21:56 ` Vladimir Oltean
2023-11-16 21:56 ` Vladimir Oltean
2023-11-17 0:28 ` kernel test robot
2023-11-17 0:28 ` kernel test robot
2023-11-14 10:55 ` [PATCH net-next v3 4/8] net: qualcomm: ipqess: Add Ethtool ops to IPQESS port netdevices Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-15 13:07 ` Wojciech Drewek [this message]
2023-11-15 13:07 ` Wojciech Drewek
2023-11-15 18:18 ` Simon Horman
2023-11-15 18:18 ` Simon Horman
2023-11-21 12:18 ` kernel test robot
2023-11-21 12:18 ` kernel test robot
2023-11-14 10:55 ` [PATCH net-next v3 5/8] net: qualcomm: ipqess: add bridge offloading features to the IPQESS driver Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-15 11:56 ` kernel test robot
2023-11-15 11:56 ` kernel test robot
2023-11-16 7:04 ` kernel test robot
2023-11-16 7:04 ` kernel test robot
2023-11-16 13:23 ` Wojciech Drewek
2023-11-16 13:23 ` Wojciech Drewek
2023-11-17 2:07 ` kernel test robot
2023-11-17 2:07 ` kernel test robot
2023-11-21 14:04 ` kernel test robot
2023-11-21 14:04 ` kernel test robot
2023-12-04 16:26 ` kernel test robot
2023-12-04 16:26 ` kernel test robot
2023-12-07 19:06 ` kernel test robot
2023-12-07 19:06 ` kernel test robot
2023-12-11 20:16 ` kernel test robot
2023-12-11 20:16 ` kernel test robot
2023-12-15 18:39 ` kernel test robot
2023-12-15 18:39 ` kernel test robot
2023-11-14 10:55 ` [PATCH net-next v3 6/8] net: phy: add calibration callbacks to phy_driver Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 19:14 ` Andrew Lunn
2023-11-14 19:14 ` Andrew Lunn
2023-11-15 15:31 ` Romain Gantois
2023-11-15 15:31 ` Romain Gantois
2023-11-15 16:12 ` Andrew Lunn
2023-11-15 16:12 ` Andrew Lunn
2023-11-14 19:20 ` Andrew Lunn
2023-11-14 19:20 ` Andrew Lunn
2023-11-14 10:55 ` [PATCH net-next v3 7/8] net: qualcomm: ipqess: add a PSGMII calibration procedure to the IPQESS driver Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 10:55 ` [PATCH net-next v3 8/8] ARM: dts: qcom: ipq4019: Add description for the IPQ4019 ESS EDMA and switch Romain Gantois
2023-11-14 10:55 ` Romain Gantois
2023-11-14 18:12 ` [PATCH net-next v3 0/8] net: qualcomm: ipqess: introduce Qualcomm IPQESS driver Andrew Lunn
2023-11-14 18:12 ` Andrew Lunn
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=271ef021-c0f7-4fd3-a64d-e94e24d46516@intel.com \
--to=wojciech.drewek@intel.com \
--cc=agross@kernel.org \
--cc=andersson@kernel.org \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=hkallweit1@gmail.com \
--cc=konrad.dybcio@somainline.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=luka.perkov@sartura.hr \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=robert.marko@sartura.hr \
--cc=robh+dt@kernel.org \
--cc=romain.gantois@bootlin.com \
--cc=thomas.petazzoni@bootlin.com \
--cc=vladimir.oltean@nxp.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.