All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gavin Shan <gwshan@linux.vnet.ibm.com>
To: netdev@vger.kernel.org
Cc: joe@perches.com, kubakici@wp.pl, f.fainelli@gmail.com,
	davem@davemloft.net, Gavin Shan <gwshan@linux.vnet.ibm.com>
Subject: [PATCH v4 net-next 04/10] net/ncsi: Ethtool operation to get NCSI topology
Date: Wed,  3 May 2017 14:44:35 +1000	[thread overview]
Message-ID: <1493786681-27468-5-git-send-email-gwshan@linux.vnet.ibm.com> (raw)
In-Reply-To: <1493786681-27468-1-git-send-email-gwshan@linux.vnet.ibm.com>

This adds ethtool command (ETHTOOL_GNCSICHANNELS) to retrieve the
NCSI channels that are associated with the specified netdev. The
ethtool operation (get_ncsi_channels()) is initialized or destroyed
when the NCSI device is registerred or unregistered. The userspace
and kernel has to negotiate on the total number of NCSI channels
so that userspace can allocate enough memory to convey data. Here
is the example output from modified (private) ethtool:

 # ethtool --ncsi eth0 channels
 2 channels:
 0:0     Active
 0:1

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 include/linux/ethtool.h      |  2 ++
 include/uapi/linux/ethtool.h | 17 ++++++++++
 net/core/ethtool.c           | 40 ++++++++++++++++++++++
 net/ncsi/Makefile            |  3 +-
 net/ncsi/internal.h          |  4 +++
 net/ncsi/ncsi-ethtool.c      | 80 ++++++++++++++++++++++++++++++++++++++++++++
 net/ncsi/ncsi-manage.c       |  6 ++++
 7 files changed, 151 insertions(+), 1 deletion(-)
 create mode 100644 net/ncsi/ncsi-ethtool.c

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 83cc986..720bb4d 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -374,5 +374,7 @@ struct ethtool_ops {
 				      struct ethtool_link_ksettings *);
 	int	(*set_link_ksettings)(struct net_device *,
 				      const struct ethtool_link_ksettings *);
+	int	(*get_ncsi_channels)(struct net_device *,
+				     struct ethtool_ncsi_channels *);
 };
 #endif /* _LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 5f4ea28..e43aacf 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1331,6 +1331,8 @@ struct ethtool_per_queue_op {
 #define ETHTOOL_PHY_GTUNABLE	0x0000004e /* Get PHY tunable configuration */
 #define ETHTOOL_PHY_STUNABLE	0x0000004f /* Set PHY tunable configuration */
 
+#define ETHTOOL_GNCSICHANNELS	0x00000050 /* Get NCSI channels */
+
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
 #define SPARC_ETH_SSET		ETHTOOL_SSET
@@ -1763,4 +1765,19 @@ struct ethtool_link_settings {
 	 * __u32 map_lp_advertising[link_mode_masks_nwords];
 	 */
 };
+
+/**
+ * struct ethtool_ncsi_channels - NCSI channels
+ *
+ * @cmd: Command number = %ETHTOOL_GNCSICHANNELS
+ * @nr_channels: Number of available channels
+ * @id: Array of NCSI channel IDs
+ */
+struct ethtool_ncsi_channels {
+	__u32	cmd;
+	__s16	nr_channels;
+	__u32	id[0];
+#define ETHTOOL_NCSI_CHANNEL_ACTIVE	(1 << 8)
+#define ETHTOOL_NCSI_CHANNEL_FLAGS	0x100
+};
 #endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 03111a2..7644765 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -756,6 +756,43 @@ static int ethtool_set_link_ksettings(struct net_device *dev,
 	return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
 }
 
+static int ethtool_get_ncsi_channels(struct net_device *dev,
+				     void __user *useraddr)
+{
+	struct ethtool_ncsi_channels *enc;
+	short nr_channels;
+	ssize_t size = 0;
+	int ret;
+
+	if (!dev->ethtool_ops->get_ncsi_channels)
+		return -EOPNOTSUPP;
+
+	if (copy_from_user(&nr_channels, useraddr + sizeof(enc->cmd),
+			   sizeof(nr_channels)))
+		return -EFAULT;
+
+	size = sizeof(*enc);
+	if (nr_channels > 0)
+		size += nr_channels * sizeof(enc->id[0]);
+
+	enc = kzalloc(size, GFP_KERNEL);
+	if (!enc)
+		return -ENOMEM;
+
+	if (copy_from_user(enc, useraddr, size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	ret = dev->ethtool_ops->get_ncsi_channels(dev, enc);
+	if (copy_to_user(useraddr, enc, size))
+		ret = -EFAULT;
+
+out:
+	kfree(enc);
+	return ret;
+}
+
 static void
 warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
 {
@@ -2793,6 +2830,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 	case ETHTOOL_PHY_STUNABLE:
 		rc = set_phy_tunable(dev, useraddr);
 		break;
+	case ETHTOOL_GNCSICHANNELS:
+		rc = ethtool_get_ncsi_channels(dev, useraddr);
+		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile
index dd12b56..71a258a 100644
--- a/net/ncsi/Makefile
+++ b/net/ncsi/Makefile
@@ -1,4 +1,5 @@
 #
 # Makefile for NCSI API
 #
-obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o
+obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o \
+			  ncsi-ethtool.o
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index 1308a56..09a7ba7 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -337,4 +337,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
 		 struct packet_type *pt, struct net_device *orig_dev);
 int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb);
 
+/* ethtool */
+void ncsi_ethtool_register_dev(struct net_device *dev);
+void ncsi_ethtool_unregister_dev(struct net_device *dev);
+
 #endif /* __NCSI_INTERNAL_H__ */
diff --git a/net/ncsi/ncsi-ethtool.c b/net/ncsi/ncsi-ethtool.c
new file mode 100644
index 0000000..747aab6
--- /dev/null
+++ b/net/ncsi/ncsi-ethtool.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright Gavin Shan, IBM Corporation 2017.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+
+#include <net/ncsi.h>
+
+#include "internal.h"
+#include "ncsi-pkt.h"
+
+static int ncsi_get_channels(struct net_device *dev,
+			     struct ethtool_ncsi_channels *enc)
+{
+	struct ncsi_dev *nd;
+	struct ncsi_dev_priv *ndp;
+	struct ncsi_package *np;
+	struct ncsi_channel *nc;
+	bool fill_data = !!(enc->nr_channels > 0);
+	short nr_channels = 0;
+	unsigned long flags;
+
+	nd = ncsi_find_dev(dev);
+	if (!nd)
+		return -ENXIO;
+
+	ndp = TO_NCSI_DEV_PRIV(nd);
+	NCSI_FOR_EACH_PACKAGE(ndp, np) {
+		NCSI_FOR_EACH_CHANNEL(np, nc) {
+			if (!fill_data) {
+				nr_channels++;
+				continue;
+			}
+
+			enc->id[nr_channels] = NCSI_TO_CHANNEL(np->id, nc->id);
+			spin_lock_irqsave(&nc->lock, flags);
+			if (nc->state == NCSI_CHANNEL_ACTIVE)
+				enc->id[nr_channels] |=
+					ETHTOOL_NCSI_CHANNEL_ACTIVE;
+			spin_unlock_irqrestore(&nc->lock, flags);
+			nr_channels++;
+		}
+	}
+
+	if (!fill_data)
+		enc->nr_channels = nr_channels;
+
+	return 0;
+}
+
+void ncsi_ethtool_register_dev(struct net_device *dev)
+{
+	struct ethtool_ops *ops;
+
+	ops = (struct ethtool_ops *)(dev->ethtool_ops);
+	if (!ops)
+		return;
+
+	ops->get_ncsi_channels = ncsi_get_channels;
+}
+
+void ncsi_ethtool_unregister_dev(struct net_device *dev)
+{
+	struct ethtool_ops *ops;
+
+	ops = (struct ethtool_ops *)(dev->ethtool_ops);
+	if (!ops)
+		return;
+
+	ops->get_ncsi_channels = NULL;
+}
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 13ad1f26..f1c10f0 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -1260,6 +1260,9 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
 	list_add_tail_rcu(&ndp->node, &ncsi_dev_list);
 	spin_unlock_irqrestore(&ncsi_dev_lock, flags);
 
+	/* Change ethtool operations */
+	ncsi_ethtool_register_dev(dev);
+
 	/* Register NCSI packet Rx handler */
 	ndp->ptype.type = cpu_to_be16(ETH_P_NCSI);
 	ndp->ptype.func = ncsi_rcv_rsp;
@@ -1331,6 +1334,9 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
 
 	dev_remove_pack(&ndp->ptype);
 
+	/* Restore ethtool operations */
+	ncsi_ethtool_unregister_dev(nd->dev);
+
 	list_for_each_entry_safe(np, tmp, &ndp->packages, node)
 		ncsi_remove_package(np);
 
-- 
2.7.4

  parent reply	other threads:[~2017-05-03  4:45 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-03  4:44 [PATCH v4 net-next 00/10] net/ncsi: Add debugging functionality Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 01/10] net/ncsi: Disable HWA mode when no channels are found Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 02/10] net/ncsi: Properly track channel monitor timer state Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 03/10] net/ncsi: Enforce failover on link monitor timeout Gavin Shan
2017-05-03  4:44 ` Gavin Shan [this message]
2017-05-04  0:49   ` [PATCH v4 net-next 04/10] net/ncsi: Ethtool operation to get NCSI topology Andrew Lunn
2017-05-04  1:36     ` Gavin Shan
2017-05-04  5:19   ` Stephen Hemminger
2017-05-04  6:15     ` Gavin Shan
2017-05-04  9:31       ` David Laight
2017-05-08  0:19         ` Gavin Shan
2017-05-08 12:40           ` David Laight
2017-05-04  5:21   ` Stephen Hemminger
2017-05-04  6:17     ` Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 05/10] net/ncsi: Ethtool operation to get NCSI channel info Gavin Shan
2017-05-03 20:53   ` kbuild test robot
2017-05-03  4:44 ` [PATCH v4 net-next 06/10] net/ncsi: Ethtool operation to get NCSI hw statistics Gavin Shan
2017-05-03 12:47   ` Andrew Lunn
2017-05-03 13:18     ` David Miller
2017-05-04  0:05       ` Gavin Shan
2017-05-04  0:16         ` David Miller
2017-05-04  0:38           ` Gavin Shan
2017-05-04  0:34         ` Andrew Lunn
2017-05-04  0:55           ` Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 07/10] net/ncsi: Ethtool operation to get NCSI sw statistics Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 08/10] net/ncsi: Support NCSI packet generation Gavin Shan
2017-05-03 12:52   ` Andrew Lunn
2017-05-04  6:31     ` Gavin Shan
2017-05-04 12:00       ` Andrew Lunn
2017-05-08  0:25         ` Gavin Shan
2017-05-08  0:56           ` Andrew Lunn
2017-05-08  6:27             ` Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 09/10] net/ncsi: No error report on DP response to non-existing package Gavin Shan
2017-05-03  4:44 ` [PATCH v4 net-next 10/10] net/ncsi: Fix length of GVI response packet Gavin Shan
2017-05-03  5:25 ` [PATCH v4 net-next 00/10] net/ncsi: Add debugging functionality David Miller
2017-05-04  0:06   ` Gavin Shan
2017-05-03 12:58 ` Andrew Lunn
2017-05-04  0:09   ` Gavin Shan

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=1493786681-27468-5-git-send-email-gwshan@linux.vnet.ibm.com \
    --to=gwshan@linux.vnet.ibm.com \
    --cc=davem@davemloft.net \
    --cc=f.fainelli@gmail.com \
    --cc=joe@perches.com \
    --cc=kubakici@wp.pl \
    --cc=netdev@vger.kernel.org \
    /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.