Thread (24 messages) 24 messages, 7 authors, 2012-07-17

Re: [RFC 2/2] net: Add support for NTB virtual ethernet device

flat view

From: Stephen Hemminger <hidden>
Date: 2012-07-14 00:08:50
Also in: linux-pci, lkml

On Fri, 13 Jul 2012 14:45:00 -0700
Jon Mason [off-list ref] wrote:
A virtual ethernet device that uses the NTB transport API to send/receive data.

Signed-off-by: Jon Mason <redacted>
---
 drivers/net/Kconfig      |    4 +
 drivers/net/Makefile     |    1 +
 drivers/net/ntb_netdev.c |  411 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 416 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/ntb_netdev.c
quoted hunk ↗ jump to hunk
+static void ntb_get_drvinfo(__attribute__((unused)) struct net_device *dev,
+			    struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+	strlcpy(info->version, NTB_NETDEV_VER, sizeof(info->version));
+}
+
+static const char ntb_nic_stats[][ETH_GSTRING_LEN] = {
+	"rx_packets", "rx_bytes", "rx_errors", "rx_dropped", "rx_length_errors",
+	"rx_frame_errors", "rx_fifo_errors",
+	"tx_packets", "tx_bytes", "tx_errors", "tx_dropped",
+};
+
+static int ntb_get_stats_count(__attribute__((unused)) struct net_device *dev)
+{
+	return ARRAY_SIZE(ntb_nic_stats);
+}
+
+static int ntb_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ntb_get_stats_count(dev);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void ntb_get_strings(__attribute__((unused)) struct net_device *dev,
+			    u32 sset, u8 *data)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		memcpy(data, *ntb_nic_stats, sizeof(ntb_nic_stats));
+	}
+}
+
+static void
+ntb_get_ethtool_stats(struct net_device *dev,
+		      __attribute__((unused)) struct ethtool_stats *stats,
+		      u64 *data)
+{
+	int i = 0;
+
+	data[i++] = dev->stats.rx_packets;
+	data[i++] = dev->stats.rx_bytes;
+	data[i++] = dev->stats.rx_errors;
+	data[i++] = dev->stats.rx_dropped;
+	data[i++] = dev->stats.rx_length_errors;
+	data[i++] = dev->stats.rx_frame_errors;
+	data[i++] = dev->stats.rx_fifo_errors;
+	data[i++] = dev->stats.tx_packets;
+	data[i++] = dev->stats.tx_bytes;
+	data[i++] = dev->stats.tx_errors;
+	data[i++] = dev->stats.tx_dropped;
+}
These statistics add no value over existing network stats.
Don't implement ethtool stats unless device has something more
interesting to say.
quoted hunk ↗ jump to hunk
+static const struct ethtool_ops ntb_ethtool_ops = {
+	.get_drvinfo = ntb_get_drvinfo,
+	.get_sset_count = ntb_get_sset_count,
+	.get_strings = ntb_get_strings,
+	.get_ethtool_stats = ntb_get_ethtool_stats,
+	.get_link = ethtool_op_get_link,
+};
If you want to implement bonding or bridging then implementing
get_settings would help.
quoted hunk ↗ jump to hunk
+static int __init ntb_netdev_init_module(void)
+{
+	struct ntb_netdev *dev;
+	int rc;
+
+	pr_info("%s: Probe\n", KBUILD_MODNAME);
Useless message
quoted hunk ↗ jump to hunk
+	netdev = alloc_etherdev(sizeof(struct ntb_netdev));
+	if (!netdev)
+		return -ENOMEM;
+
+	dev = netdev_priv(netdev);
+	dev->ndev = netdev;
+	netdev->features = NETIF_F_HIGHDMA;
+
+	netdev->hw_features = netdev->features;
+	netdev->watchdog_timeo = msecs_to_jiffies(NTB_TX_TIMEOUT_MS);
+
+	random_ether_addr(netdev->perm_addr);
+	memcpy(netdev->dev_addr, netdev->perm_addr, netdev->addr_len);
+
+	netdev->netdev_ops = &ntb_netdev_ops;
+	SET_ETHTOOL_OPS(netdev, &ntb_ethtool_ops);
+
+	dev->qp = ntb_transport_create_queue(ntb_netdev_rx_handler,
+					     ntb_netdev_tx_handler,
+					     ntb_netdev_event_handler);
+	if (!dev->qp) {
+		rc = -EIO;
+		goto err;
+	}
+
+	netdev->mtu = ntb_transport_max_size(dev->qp) - ETH_HLEN;
+
+	rc = register_netdev(netdev);
+	if (rc)
+		goto err1;
+
+	pr_info("%s: %s created\n", KBUILD_MODNAME, netdev->name);
+	return 0;
+
+err1:
+	ntb_transport_free_queue(dev->qp);
+err:
+	free_netdev(netdev);
+	return rc;
+}
+module_init(ntb_netdev_init_module);
+
+static void __exit ntb_netdev_exit_module(void)
+{
+	struct ntb_netdev *dev = netdev_priv(netdev);
+
+	unregister_netdev(netdev);
+	ntb_transport_free_queue(dev->qp);
+	free_netdev(netdev);
+
+	pr_info("%s: Driver removed\n", KBUILD_MODNAME);
+}
+module_exit(ntb_netdev_exit_module);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help