Netdev List
 help / color / mirror / Atom feed
* [RFC net-next 2/4] net: Prepare EnOcean device drivers
From: Andreas Färber @ 2019-01-29  5:01 UTC (permalink / raw)
  To: linux-lpwan, linux-wpan
  Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
	Andreas Färber
In-Reply-To: <20190129050130.10932-1-afaerber@suse.de>

Add net_device helpers for EnOcean.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 drivers/net/enocean/Makefile  |   2 +
 drivers/net/enocean/enocean.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/enocean/dev.h   |  23 ++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 drivers/net/enocean/Makefile
 create mode 100644 drivers/net/enocean/enocean.c
 create mode 100644 include/linux/enocean/dev.h

diff --git a/drivers/net/enocean/Makefile b/drivers/net/enocean/Makefile
new file mode 100644
index 000000000000..efb3cd16c7f2
--- /dev/null
+++ b/drivers/net/enocean/Makefile
@@ -0,0 +1,2 @@
+obj-m += enocean-dev.o
+enocean-dev-y := enocean.o
diff --git a/drivers/net/enocean/enocean.c b/drivers/net/enocean/enocean.c
new file mode 100644
index 000000000000..087a4de274c8
--- /dev/null
+++ b/drivers/net/enocean/enocean.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean net device
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <linux/enocean/dev.h>
+#include <linux/if_arp.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/rtnetlink.h>
+
+int open_enocean_dev(struct net_device *dev)
+{
+	if (!netif_carrier_ok(dev))
+		netif_carrier_on(dev);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(open_enocean_dev);
+
+void close_enocean_dev(struct net_device *dev)
+{
+}
+EXPORT_SYMBOL_GPL(close_enocean_dev);
+
+static void enocean_setup(struct net_device *dev)
+{
+	dev->type = ARPHRD_ENOCEAN;
+	dev->mtu = 255; /* XXX */
+	dev->hard_header_len = 0;
+	dev->addr_len = 0; /* XXX 4 */
+	dev->tx_queue_len = 10;
+
+	dev->flags = IFF_NOARP;
+	dev->features = 0;
+}
+
+struct net_device *alloc_enocean_dev(size_t priv_size)
+{
+	struct enocean_dev_priv *priv;
+	struct net_device *netdev;
+
+	netdev = alloc_netdev(priv_size, "enocean%d", NET_NAME_UNKNOWN, enocean_setup);
+	if (!netdev)
+		return NULL;
+
+	priv = netdev_priv(netdev);
+	priv->dev = netdev;
+
+	return netdev;
+}
+EXPORT_SYMBOL_GPL(alloc_enocean_dev);
+
+void free_enocean_dev(struct net_device *netdev)
+{
+	free_netdev(netdev);
+}
+EXPORT_SYMBOL_GPL(free_enocean_dev);
+
+static void devm_free_enocean_dev(struct device *dev, void *res)
+{
+	struct net_device **net = res;
+
+	free_enocean_dev(*net);
+}
+
+struct net_device *devm_alloc_enocean_dev(struct device *dev, size_t priv)
+{
+	struct net_device **ptr;
+	struct net_device *net;
+
+	net = alloc_enocean_dev(priv);
+	if (!net)
+		return NULL;
+
+	ptr = devres_alloc(devm_free_enocean_dev, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr) {
+		free_enocean_dev(net);
+		return NULL;
+	}
+
+	*ptr = net;
+	devres_add(dev, ptr);
+
+	return net;
+}
+EXPORT_SYMBOL_GPL(devm_alloc_enocean_dev);
+
+static struct rtnl_link_ops enocean_link_ops __read_mostly = {
+	.kind = "enocean",
+	.setup = enocean_setup,
+};
+
+int register_enocean_dev(struct net_device *dev)
+{
+	dev->rtnl_link_ops = &enocean_link_ops;
+	return register_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(register_enocean_dev);
+
+void unregister_enocean_dev(struct net_device *dev)
+{
+	unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_enocean_dev);
+
+static int __init enocean_dev_init(void)
+{
+	return rtnl_link_register(&enocean_link_ops);
+}
+module_init(enocean_dev_init);
+
+static void __exit enocean_dev_exit(void)
+{
+	rtnl_link_unregister(&enocean_link_ops);
+}
+module_exit(enocean_dev_exit);
+
+MODULE_DESCRIPTION("EnOcean device driver interface");
+MODULE_ALIAS_RTNL_LINK("enocean");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Andreas Färber");
diff --git a/include/linux/enocean/dev.h b/include/linux/enocean/dev.h
new file mode 100644
index 000000000000..be9d37cdde37
--- /dev/null
+++ b/include/linux/enocean/dev.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * linux/enocean/dev.h
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+#ifndef _ENOCEAN_DEV_H
+#define _ENOCEAN_DEV_H
+
+#include <linux/netdevice.h>
+
+struct net_device *alloc_enocean_dev(size_t priv_size);
+struct net_device *devm_alloc_enocean_dev(struct device *dev, size_t priv_size);
+int register_enocean_dev(struct net_device *netdev);
+void unregister_enocean_dev(struct net_device *netdev);
+int open_enocean_dev(struct net_device *netdev);
+void close_enocean_dev(struct net_device *netdev);
+
+struct enocean_dev_priv {
+	struct net_device *dev;
+};
+
+#endif
-- 
2.16.4


^ permalink raw reply related

* [RFC net-next 4/4] net: enocean: Prepare ESP2 support
From: Andreas Färber @ 2019-01-29  5:01 UTC (permalink / raw)
  To: linux-lpwan, linux-wpan
  Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
	Andreas Färber
In-Reply-To: <20190129050130.10932-1-afaerber@suse.de>

The EnOcean Serial Protocol 2 used subtelegram frames different from ESP3.
It also uses ORG identifiers differing from RORG identifiers in ERP.

Only checksumming has been tested.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 drivers/net/enocean/Makefile       |   1 +
 drivers/net/enocean/enocean_esp.c  |  10 ++
 drivers/net/enocean/enocean_esp.h  |   8 ++
 drivers/net/enocean/enocean_esp2.c | 276 +++++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+)
 create mode 100644 drivers/net/enocean/enocean_esp2.c

diff --git a/drivers/net/enocean/Makefile b/drivers/net/enocean/Makefile
index 4492e3d48c0a..f34b098997e4 100644
--- a/drivers/net/enocean/Makefile
+++ b/drivers/net/enocean/Makefile
@@ -3,4 +3,5 @@ enocean-dev-y := enocean.o
 
 obj-m += enocean-esp.o
 enocean-esp-y := enocean_esp.o
+enocean-esp-y += enocean_esp2.o
 enocean-esp-y += enocean_esp3.o
diff --git a/drivers/net/enocean/enocean_esp.c b/drivers/net/enocean/enocean_esp.c
index 61bddb77762d..74720da49369 100644
--- a/drivers/net/enocean/enocean_esp.c
+++ b/drivers/net/enocean/enocean_esp.c
@@ -150,6 +150,15 @@ static void enocean_esp_cleanup(struct enocean_device *edev)
 		edev->version->cleanup(edev);
 }
 
+static const struct enocean_esp_version enocean_esp2 = {
+	.version = 2,
+	.baudrate = 9600,
+	.serdev_client_ops = &enocean_esp2_serdev_client_ops,
+	.init = enocean_esp2_init,
+	.send = enocean_esp2_send,
+	.cleanup = enocean_esp2_cleanup,
+};
+
 static const struct enocean_esp_version enocean_esp3 = {
 	.version = 3,
 	.baudrate = 57600,
@@ -160,6 +169,7 @@ static const struct enocean_esp_version enocean_esp3 = {
 };
 
 static const struct of_device_id enocean_of_match[] = {
+	{ .compatible = "enocean,esp2", .data = &enocean_esp2 },
 	{ .compatible = "enocean,esp3", .data = &enocean_esp3 },
 	{}
 };
diff --git a/drivers/net/enocean/enocean_esp.h b/drivers/net/enocean/enocean_esp.h
index e02bf5352d61..44660238043a 100644
--- a/drivers/net/enocean/enocean_esp.h
+++ b/drivers/net/enocean/enocean_esp.h
@@ -24,15 +24,23 @@ struct enocean_device {
 	void *priv;
 };
 
+extern const struct serdev_device_ops enocean_esp2_serdev_client_ops;
 extern const struct serdev_device_ops enocean_esp3_serdev_client_ops;
 
 void enocean_esp3_crc8_populate(void);
 
+int enocean_esp2_init(struct enocean_device *edev);
 int enocean_esp3_init(struct enocean_device *edev);
 
+int enocean_esp2_send(struct enocean_device *edev, u32 dest, const void *data, int data_len);
 int enocean_esp3_send(struct enocean_device *edev, u32 dest, const void *data, int data_len);
 void enocean_esp_tx_done(struct enocean_device *edev);
 
+void enocean_esp2_cleanup(struct enocean_device *edev);
 void enocean_esp3_cleanup(struct enocean_device *edev);
 
+#define ENOCEAN_RORG_RPS	0xF6
+#define ENOCEAN_RORG_1BS	0xD5
+#define ENOCEAN_RORG_4BS	0xA5
+
 #endif
diff --git a/drivers/net/enocean/enocean_esp2.c b/drivers/net/enocean/enocean_esp2.c
new file mode 100644
index 000000000000..d4cb787de22e
--- /dev/null
+++ b/drivers/net/enocean/enocean_esp2.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean Serial Protocol 2
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <linux/serdev.h>
+
+#include "enocean_esp.h"
+
+#define ESP2_SYNC_BYTE1 0xA5
+#define ESP2_SYNC_BYTE0 0x5A
+
+struct enocean_esp2_packet {
+	u8 sync[2];
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	u8 h_seq:3;
+	u8 length:5;
+#else
+	u8 length:5;
+	u8 h_seq:3;
+#endif
+	u8 org;
+	u8 data[4];
+	u8 id[4];
+	u8 status;
+	u8 checksum;
+} __packed;
+
+#define ESP2_H_SEQ_TRT	0x3
+#define ESP2_H_SEQ_RCT	0x4
+#define ESP2_H_SEQ_TCT	0x5
+
+#define ESP2_TELEGRAM_RESET	0x0A
+
+#define ENOCEAN_ORG_RPS		0x05
+#define ENOCEAN_ORG_1BS		0x06
+#define ENOCEAN_ORG_4BS		0x07
+
+/* Cf. EnOcean Equipment Profiles, Telegram Types (RORG) */
+static inline u8 enocean_org_to_rorg(u8 org)
+{
+	switch (org) {
+	case ENOCEAN_ORG_RPS:
+		return ENOCEAN_RORG_RPS;
+	case ENOCEAN_ORG_1BS:
+		return ENOCEAN_RORG_1BS;
+	case ENOCEAN_ORG_4BS:
+		return ENOCEAN_RORG_4BS;
+	default:
+		return org;
+	}
+}
+
+static u8 enocean_rorg_to_org(u8 rorg)
+{
+	switch (rorg) {
+	case ENOCEAN_RORG_RPS:
+		return ENOCEAN_ORG_RPS;
+	case ENOCEAN_RORG_1BS:
+		return ENOCEAN_ORG_1BS;
+	case ENOCEAN_RORG_4BS:
+		return ENOCEAN_ORG_4BS;
+	default:
+		return rorg;
+	}
+}
+
+struct enocean_esp2_dispatcher {
+	struct list_head list;
+	u8 h_seq;
+	void (*dispatch)(const u8 *data, u8 data_len, struct enocean_esp2_dispatcher *d);
+};
+
+static void enocean_add_esp2_dispatcher(struct enocean_device *edev,
+	struct enocean_esp2_dispatcher *entry)
+{
+	list_add_tail_rcu(&entry->list, &edev->esp_dispatchers);
+}
+
+static void enocean_remove_esp2_dispatcher(struct enocean_device *edev,
+	struct enocean_esp2_dispatcher *entry)
+{
+	list_del_rcu(&entry->list);
+}
+
+#define ESP2_RESPONSE_ERR_SYNTAX_H_SEQ	0x08
+#define ESP2_RESPONSE_ERR_SYNTAX_LENGTH	0x09
+#define ESP2_RESPONSE_ERR_SYNTAX_CHKSUM	0x0A
+#define ESP2_RESPONSE_ERR_SYNTAX_ORG	0x0B
+#define ESP2_RESPONSE_ERR		0x19
+#define ESP2_RESPONSE_ERR_IDRANGE	0x1A
+#define ESP2_RESPONSE_ERR_TX_IDRANGE	0x22
+#define ESP2_RESPONSE_OK		0x58
+
+struct enocean_esp2_priv {
+	struct enocean_device *edev;
+	struct enocean_esp2_dispatcher tx_telegram_response;
+};
+
+static u8 enocean_esp2_checksum(const u8 *data, int len)
+{
+	u8 chksum = 0;
+	int i;
+
+	for (i = 0; i < len; i++) {
+		chksum += data[i];
+	}
+	return chksum;
+}
+
+static int enocean_esp2_send_telegram(struct enocean_device *edev, u8 h_seq, u8 org,
+	const u8 *data, int data_len, unsigned long timeout)
+{
+	struct enocean_esp2_packet pkt;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	pkt.sync[0] = ESP2_SYNC_BYTE1;
+	pkt.sync[1] = ESP2_SYNC_BYTE0;
+	pkt.h_seq = h_seq;
+	pkt.length = 11;
+	dev_dbg(&edev->serdev->dev, "H_SEQ | LENGTH = %02x\n", (unsigned int)(((u8*)&pkt)[2]));
+	pkt.org = org;
+	if (data_len > 0)
+		memcpy(pkt.data, data, min(data_len, 9));
+	pkt.checksum = enocean_esp2_checksum(((u8 *)&pkt) + 2, sizeof(pkt) - 2 - 1);
+	dev_dbg(&edev->serdev->dev, "checksum = %02x\n", (unsigned int)pkt.checksum);
+
+	ret = serdev_device_write(edev->serdev, (const u8 *)&pkt, sizeof(pkt), timeout);
+	if (ret < 0)
+		return ret;
+	if (ret > 0 && ret < sizeof(pkt))
+		return -EIO;
+	return 0;
+}
+
+static void enocean_esp2_tx_telegram_response_dispatch(const u8 *data, u8 data_len,
+	struct enocean_esp2_dispatcher *d)
+{
+	struct enocean_esp2_priv *priv = container_of(d, struct enocean_esp2_priv, tx_telegram_response);
+	struct enocean_device *edev = priv->edev;
+
+	enocean_remove_esp2_dispatcher(edev, d);
+
+	if (data_len < 1)
+		return;
+
+	switch (data[0]) {
+	case ESP2_RESPONSE_OK:
+		enocean_esp_tx_done(edev);
+		break;
+	case ESP2_RESPONSE_ERR:
+	case ESP2_RESPONSE_ERR_TX_IDRANGE:
+	default:
+		break;
+	}
+}
+
+static int enocean_esp2_tx_telegram(struct enocean_device *edev, u8 org,
+	const u8 *data, int data_len, unsigned long timeout)
+{
+	struct enocean_esp2_priv *priv = edev->priv;
+	int ret;
+
+	enocean_add_esp2_dispatcher(edev, &priv->tx_telegram_response);
+
+	ret = enocean_esp2_send_telegram(edev, ESP2_H_SEQ_TRT,
+		org, data, data_len, timeout);
+	if (ret) {
+		enocean_remove_esp2_dispatcher(edev, &priv->tx_telegram_response);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int enocean_esp2_reset(struct enocean_device *edev, unsigned long timeout)
+{
+	return enocean_esp2_send_telegram(edev, ESP2_H_SEQ_TCT, ESP2_TELEGRAM_RESET, NULL, 0, timeout);
+	/* no RCT */
+}
+
+static int enocean_esp2_receive_buf(struct serdev_device *sdev, const u8 *data, size_t count)
+{
+	struct enocean_device *edev = serdev_device_get_drvdata(sdev);
+	struct enocean_esp2_dispatcher *e;
+	u8 h_seq, length, chksum;
+
+	dev_dbg(&sdev->dev, "Receive (%zu)\n", count);
+
+	if (data[0] != ESP2_SYNC_BYTE1) {
+		dev_warn(&sdev->dev, "not first Sync Byte (found 0x%02x), skipping\n",
+			(unsigned int)data[0]);
+		return 1;
+	}
+
+	if (count < 2)
+		return 0;
+
+	if (data[1] != ESP2_SYNC_BYTE0) {
+		dev_warn(&sdev->dev, "not second Sync Byte (found 0x%02x 0x%02x), skipping\n",
+			ESP2_SYNC_BYTE1, (unsigned int)data[1]);
+		return 1;
+	}
+
+	if (count < 3)
+		return 0;
+
+	h_seq = data[2] >> 5;
+	length = data[2] & 0x1f;
+
+	if (count < 3 + length)
+		return 0;
+
+	chksum = enocean_esp2_checksum(data + 2, 1 + length - 1);
+	if (data[3 + length - 1] != chksum) {
+		dev_warn(&sdev->dev, "invalid checksum (expected 0x%02x, found %02x), skipping\n",
+			(unsigned int)chksum, (unsigned int)data[3 + length - 1]);
+		return 2; /* valid second Sync Byte is not a valid first Sync Byte */
+	}
+
+	print_hex_dump_bytes("received: ", DUMP_PREFIX_OFFSET, data, 3 + length);
+
+	list_for_each_entry_rcu(e, &edev->esp_dispatchers, list) {
+		if (e->h_seq == h_seq)
+			e->dispatch(data + 3, length, e);
+	}
+
+	return 3 + length;
+}
+
+const struct serdev_device_ops enocean_esp2_serdev_client_ops = {
+	.receive_buf = enocean_esp2_receive_buf,
+	.write_wakeup = serdev_device_write_wakeup,
+};
+
+int enocean_esp2_send(struct enocean_device *edev, u32 dest, const void *data, int data_len)
+{
+	const u8 *buf = data;
+
+	return enocean_esp2_tx_telegram(edev,
+		enocean_rorg_to_org(buf[0]), buf + 1, data_len - 1, HZ);
+}
+
+int enocean_esp2_init(struct enocean_device *edev)
+{
+	struct enocean_esp2_priv *priv;
+	int ret;
+
+	ret = enocean_esp2_reset(edev, HZ);
+	if (ret)
+		return ret;
+
+	msleep(100); /* XXX */
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->edev = edev;
+	edev->priv = priv;
+
+	priv->tx_telegram_response.h_seq = ESP2_H_SEQ_RCT;
+	priv->tx_telegram_response.dispatch = enocean_esp2_tx_telegram_response_dispatch;
+
+	return 0;
+}
+
+void enocean_esp2_cleanup(struct enocean_device *edev)
+{
+	struct enocean_esp2_priv *priv = edev->priv;
+
+	kfree(priv);
+}
-- 
2.16.4


^ permalink raw reply related

* [RFC net-next 3/4] net: enocean: Add ESP3 driver
From: Andreas Färber @ 2019-01-29  5:01 UTC (permalink / raw)
  To: linux-lpwan, linux-wpan
  Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
	Andreas Färber
In-Reply-To: <20190129050130.10932-1-afaerber@suse.de>

This implements the EnOcean Serial Protocol 3.
Rudimentary sending is prepared. Error handling is lacking and
reception handling is missing.

Tested with EnOcean TCM310 gateway module.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 drivers/net/enocean/Makefile       |   4 +
 drivers/net/enocean/enocean_esp.c  | 277 +++++++++++++++++++++++++++
 drivers/net/enocean/enocean_esp.h  |  38 ++++
 drivers/net/enocean/enocean_esp3.c | 372 +++++++++++++++++++++++++++++++++++++
 4 files changed, 691 insertions(+)
 create mode 100644 drivers/net/enocean/enocean_esp.c
 create mode 100644 drivers/net/enocean/enocean_esp.h
 create mode 100644 drivers/net/enocean/enocean_esp3.c

diff --git a/drivers/net/enocean/Makefile b/drivers/net/enocean/Makefile
index efb3cd16c7f2..4492e3d48c0a 100644
--- a/drivers/net/enocean/Makefile
+++ b/drivers/net/enocean/Makefile
@@ -1,2 +1,6 @@
 obj-m += enocean-dev.o
 enocean-dev-y := enocean.o
+
+obj-m += enocean-esp.o
+enocean-esp-y := enocean_esp.o
+enocean-esp-y += enocean_esp3.o
diff --git a/drivers/net/enocean/enocean_esp.c b/drivers/net/enocean/enocean_esp.c
new file mode 100644
index 000000000000..61bddb77762d
--- /dev/null
+++ b/drivers/net/enocean/enocean_esp.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean Serial Protocol
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/enocean/dev.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/serdev.h>
+
+#include "enocean_esp.h"
+
+struct enocean_esp_version {
+	int version;
+	int baudrate;
+	const struct serdev_device_ops *serdev_client_ops;
+	int (*init)(struct enocean_device *edev);
+	int (*send)(struct enocean_device *edev, u32 dest, const void *data, int data_len);
+	void (*cleanup)(struct enocean_device *edev);
+};
+
+struct enocean_esp_priv {
+	struct enocean_dev_priv priv;
+
+	struct enocean_device *edev;
+
+	struct sk_buff *tx_skb;
+	int tx_len;
+
+	struct workqueue_struct *wq;
+	struct work_struct tx_work;
+};
+
+static netdev_tx_t enocean_dev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct enocean_esp_priv *priv = netdev_priv(netdev);
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	if (skb->protocol != htons(ETH_P_ERP1) &&
+	    skb->protocol != htons(ETH_P_ERP2)) {
+		kfree_skb(skb);
+		netdev->stats.tx_dropped++;
+		return NETDEV_TX_OK;
+	}
+
+	netif_stop_queue(netdev);
+	priv->tx_skb = skb;
+	queue_work(priv->wq, &priv->tx_work);
+
+	return NETDEV_TX_OK;
+}
+
+static int enocean_esp_tx(struct enocean_device *edev, void *data, int data_len)
+{
+	if (!edev->version->send)
+		return -ENOTSUPP;
+	return edev->version->send(edev, 0xffffffff, data, data_len);
+}
+
+static void enocean_esp_tx_work_handler(struct work_struct *ws)
+{
+	struct enocean_esp_priv *priv = container_of(ws, struct enocean_esp_priv, tx_work);
+	struct enocean_device *edev = priv->edev;
+	struct net_device *netdev = edev->netdev;
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	if (priv->tx_skb) {
+		enocean_esp_tx(edev, priv->tx_skb->data, priv->tx_skb->len);
+		priv->tx_len = 1 + priv->tx_skb->len;
+		if (!(netdev->flags & IFF_ECHO) ||
+			priv->tx_skb->pkt_type != PACKET_LOOPBACK ||
+			(priv->tx_skb->protocol != htons(ETH_P_ERP1) &&
+			 priv->tx_skb->protocol != htons(ETH_P_ERP2)))
+			kfree_skb(priv->tx_skb);
+		priv->tx_skb = NULL;
+	}
+}
+
+void enocean_esp_tx_done(struct enocean_device *edev)
+{
+	struct net_device *netdev = edev->netdev;
+	struct enocean_esp_priv *priv = netdev_priv(netdev);
+
+	netdev_info(netdev, "TX done.\n");
+	netdev->stats.tx_packets++;
+	netdev->stats.tx_bytes += priv->tx_len - 1;
+	priv->tx_len = 0;
+	netif_wake_queue(netdev);
+}
+
+static int enocean_dev_open(struct net_device *netdev)
+{
+	struct enocean_esp_priv *priv = netdev_priv(netdev);
+	int ret;
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	ret = open_enocean_dev(netdev);
+	if (ret)
+		return ret;
+
+	priv->tx_skb = NULL;
+	priv->tx_len = 0;
+
+	priv->wq = alloc_workqueue("enocean_esp_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM, 0);
+	INIT_WORK(&priv->tx_work, enocean_esp_tx_work_handler);
+
+	netif_wake_queue(netdev);
+
+	return 0;
+}
+
+static int enocean_dev_stop(struct net_device *netdev)
+{
+	struct enocean_esp_priv *priv = netdev_priv(netdev);
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	close_enocean_dev(netdev);
+
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
+
+	if (priv->tx_skb || priv->tx_len)
+		netdev->stats.tx_errors++;
+	if (priv->tx_skb)
+		dev_kfree_skb(priv->tx_skb);
+	priv->tx_skb = NULL;
+	priv->tx_len = 0;
+
+	return 0;
+}
+
+static const struct net_device_ops enocean_esp_netdev_ops =  {
+	.ndo_open = enocean_dev_open,
+	.ndo_stop = enocean_dev_stop,
+	.ndo_start_xmit = enocean_dev_start_xmit,
+};
+
+static void enocean_esp_cleanup(struct enocean_device *edev)
+{
+	if (edev->version->cleanup)
+		edev->version->cleanup(edev);
+}
+
+static const struct enocean_esp_version enocean_esp3 = {
+	.version = 3,
+	.baudrate = 57600,
+	.serdev_client_ops = &enocean_esp3_serdev_client_ops,
+	.init = enocean_esp3_init,
+	.send = enocean_esp3_send,
+	.cleanup = enocean_esp3_cleanup,
+};
+
+static const struct of_device_id enocean_of_match[] = {
+	{ .compatible = "enocean,esp3", .data = &enocean_esp3 },
+	{}
+};
+MODULE_DEVICE_TABLE(of, enocean_of_match);
+
+static int enocean_probe(struct serdev_device *sdev)
+{
+	struct enocean_esp_priv *priv;
+	struct enocean_device *edev;
+	int ret;
+
+	dev_dbg(&sdev->dev, "Probing");
+
+	edev = devm_kzalloc(&sdev->dev, sizeof(*edev), GFP_KERNEL);
+	if (!edev)
+		return -ENOMEM;
+
+	edev->version = of_device_get_match_data(&sdev->dev);
+	if (!edev->version)
+		return -ENOTSUPP;
+
+	dev_dbg(&sdev->dev, "ESP%d\n", edev->version->version);
+
+	edev->serdev = sdev;
+	INIT_LIST_HEAD(&edev->esp_dispatchers);
+	serdev_device_set_drvdata(sdev, edev);
+
+	ret = serdev_device_open(sdev);
+	if (ret) {
+		dev_err(&sdev->dev, "Failed to open (%d)\n", ret);
+		return ret;
+	}
+
+	serdev_device_set_baudrate(sdev, edev->version->baudrate);
+	serdev_device_set_flow_control(sdev, false);
+	serdev_device_set_client_ops(sdev, edev->version->serdev_client_ops);
+
+	if (edev->version->init) {
+		ret = edev->version->init(edev);
+		if (ret) {
+			serdev_device_close(sdev);
+			return ret;
+		}
+	}
+
+	edev->netdev = devm_alloc_enocean_dev(&sdev->dev, sizeof(struct enocean_esp_priv));
+	if (!edev->netdev) {
+		enocean_esp_cleanup(edev);
+		serdev_device_close(sdev);
+		return -ENOMEM;
+	}
+
+	edev->netdev->netdev_ops = &enocean_esp_netdev_ops;
+	edev->netdev->flags |= IFF_ECHO;
+	SET_NETDEV_DEV(edev->netdev, &sdev->dev);
+
+	priv = netdev_priv(edev->netdev);
+	priv->edev = edev;
+
+	ret = register_enocean_dev(edev->netdev);
+	if (ret) {
+		enocean_esp_cleanup(edev);
+		serdev_device_close(sdev);
+		return ret;
+	}
+
+	dev_dbg(&sdev->dev, "Done.\n");
+
+	return 0;
+}
+
+static void enocean_remove(struct serdev_device *sdev)
+{
+	struct enocean_device *edev = serdev_device_get_drvdata(sdev);
+
+	unregister_enocean_dev(edev->netdev);
+	enocean_esp_cleanup(edev);
+	serdev_device_close(sdev);
+
+	dev_dbg(&sdev->dev, "Removed\n");
+}
+
+static struct serdev_device_driver enocean_serdev_driver = {
+	.probe = enocean_probe,
+	.remove = enocean_remove,
+	.driver = {
+		.name = "enocean-esp",
+		.of_match_table = enocean_of_match,
+	},
+};
+
+static int __init enocean_init(void)
+{
+	int ret;
+
+	enocean_esp3_crc8_populate();
+
+	ret = serdev_device_driver_register(&enocean_serdev_driver);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void __exit enocean_exit(void)
+{
+	serdev_device_driver_unregister(&enocean_serdev_driver);
+}
+
+module_init(enocean_init);
+module_exit(enocean_exit);
+
+MODULE_DESCRIPTION("EnOcean serdev driver");
+MODULE_AUTHOR("Andreas Färber <afaerber@suse.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/enocean/enocean_esp.h b/drivers/net/enocean/enocean_esp.h
new file mode 100644
index 000000000000..e02bf5352d61
--- /dev/null
+++ b/drivers/net/enocean/enocean_esp.h
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean Serial Protocol
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+#ifndef ENOCEAN_H
+#define ENOCEAN_H
+
+#include <linux/netdevice.h>
+#include <linux/rculist.h>
+#include <linux/serdev.h>
+
+struct enocean_esp_version;
+
+struct enocean_device {
+	struct serdev_device *serdev;
+	const struct enocean_esp_version *version;
+
+	struct net_device *netdev;
+
+	struct list_head esp_dispatchers;
+
+	void *priv;
+};
+
+extern const struct serdev_device_ops enocean_esp3_serdev_client_ops;
+
+void enocean_esp3_crc8_populate(void);
+
+int enocean_esp3_init(struct enocean_device *edev);
+
+int enocean_esp3_send(struct enocean_device *edev, u32 dest, const void *data, int data_len);
+void enocean_esp_tx_done(struct enocean_device *edev);
+
+void enocean_esp3_cleanup(struct enocean_device *edev);
+
+#endif
diff --git a/drivers/net/enocean/enocean_esp3.c b/drivers/net/enocean/enocean_esp3.c
new file mode 100644
index 000000000000..707c4054ac69
--- /dev/null
+++ b/drivers/net/enocean/enocean_esp3.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean Serial Protocol 3
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <asm/unaligned.h>
+#include <linux/completion.h>
+#include <linux/crc8.h>
+#include <linux/rculist.h>
+#include <linux/serdev.h>
+#include <linux/slab.h>
+
+#include "enocean_esp.h"
+
+/* G(x) = x^8 + x^2 + x^1 + x^0 */
+#define ESP3_CRC8_POLY_MSB 0x07
+
+DECLARE_CRC8_TABLE(enocean_esp3_crc8_table);
+
+void enocean_esp3_crc8_populate(void)
+{
+	crc8_populate_msb(enocean_esp3_crc8_table, ESP3_CRC8_POLY_MSB);
+}
+
+static inline u8 enocean_esp3_crc8(u8 *pdata, size_t nbytes)
+{
+	return crc8(enocean_esp3_crc8_table, pdata, nbytes, 0x00);
+}
+
+#define ESP3_SYNC_WORD 0x55
+
+struct enocean_esp3_dispatcher {
+	struct list_head list;
+	u8 packet_type;
+	void (*dispatch)(const u8 *data, u16 data_len, struct enocean_esp3_dispatcher *d);
+};
+
+static void enocean_add_esp3_dispatcher(struct enocean_device *edev,
+	struct enocean_esp3_dispatcher *entry)
+{
+	list_add_tail_rcu(&entry->list, &edev->esp_dispatchers);
+}
+
+static void enocean_remove_esp3_dispatcher(struct enocean_device *edev,
+	struct enocean_esp3_dispatcher *entry)
+{
+	list_del_rcu(&entry->list);
+}
+
+struct enocean_esp3_response {
+	struct enocean_esp3_dispatcher disp;
+
+	u8 code;
+	void *data;
+	u16 data_len;
+
+	struct completion comp;
+};
+
+static void enocean_esp3_response_dispatch(const u8 *data, u16 data_len,
+	struct enocean_esp3_dispatcher *d)
+{
+	struct enocean_esp3_response *resp =
+		container_of(d, struct enocean_esp3_response, disp);
+
+	if (completion_done(&resp->comp))
+		return;
+
+	if (data_len < 1)
+		return;
+
+	resp->code = data[0];
+	if (data_len > 1) {
+		resp->data = kzalloc(data_len - 1, GFP_KERNEL);
+		if (resp->data)
+			memcpy(resp->data, data + 1, data_len - 1);
+		resp->data_len = data_len - 1;
+	} else {
+		resp->data = NULL;
+		resp->data_len = 0;
+	}
+
+	complete(&resp->comp);
+}
+
+struct enocean_esp3_priv {
+	struct enocean_device *edev;
+	struct enocean_esp3_dispatcher radio_erp1_response;
+};
+
+static inline int enocean_esp3_packet_size(u16 data_len, u8 optional_len)
+{
+	return 1 + 4 + 1 + data_len + optional_len + 1;
+}
+
+static int enocean_send_esp3_packet(struct enocean_device *edev, u8 packet_type,
+	const void *data, u16 data_len, const void *optional_data, u8 optional_len,
+	unsigned long timeout)
+{
+	int len = enocean_esp3_packet_size(data_len, optional_len);
+	u8 *buf;
+	int ret;
+
+	buf = kzalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	buf[0] = ESP3_SYNC_WORD;
+	put_unaligned_be16(data_len, buf + 1);
+	buf[3] = optional_len;
+	buf[4] = packet_type;
+	buf[5] = enocean_esp3_crc8(buf + 1, 4);
+	dev_dbg(&edev->serdev->dev, "CRC8H = %02x\n", (unsigned int)buf[5]);
+	memcpy(buf + 6, data, data_len);
+	memcpy(buf + 6 + data_len, optional_data, optional_len);
+	buf[6 + data_len + optional_len] = enocean_esp3_crc8(buf + 6, data_len + optional_len);
+	dev_dbg(&edev->serdev->dev, "CRC8D = %02x\n", (unsigned int)buf[6 + data_len + optional_len]);
+
+	ret = serdev_device_write(edev->serdev, buf, len, timeout);
+
+	kfree(buf);
+
+	if (ret < 0)
+		return ret;
+	if (ret > 0 && ret < len)
+		return -EIO;
+	return 0;
+}
+
+#define ESP3_RADIO_ERP1		0x1
+#define ESP3_RESPONSE		0x2
+#define ESP3_COMMON_COMMAND	0x5
+
+static void enocean_esp3_radio_erp1_response_dispatch(const u8 *data, u16 data_len,
+	struct enocean_esp3_dispatcher *d)
+{
+	struct enocean_esp3_priv *priv = container_of(d, struct enocean_esp3_priv, radio_erp1_response);
+	struct enocean_device *edev = priv->edev;
+	int ret;
+
+	enocean_remove_esp3_dispatcher(edev, d);
+
+	if (data_len < 1)
+		return;
+
+	switch (data[0]) {
+	case 0:
+		enocean_esp_tx_done(edev);
+		break;
+	case 2:
+		ret = -ENOTSUPP;
+		break;
+	case 3:
+		ret = -EINVAL;
+		break;
+	case 5:
+		ret = -EIO;
+		break;
+	default:
+		ret = -EIO;
+		break;
+	}
+}
+
+static int enocean_esp3_send_radio_erp1(struct enocean_device *edev, u32 dest,
+	const u8 *data, int data_len, unsigned long timeout)
+{
+	struct enocean_esp3_priv *priv = edev->priv;
+	struct esp3_radio_erp1_optional {
+		u8 sub_tel_num;
+		__be32 destination_id;
+		u8 dbm;
+		u8 security_level;
+	} __packed opt = {
+		.sub_tel_num = 3,
+		.destination_id = cpu_to_be32(dest),
+		.dbm = 0xff,
+		.security_level = 0,
+	};
+	int ret;
+
+	enocean_add_esp3_dispatcher(edev, &priv->radio_erp1_response);
+
+	ret = enocean_send_esp3_packet(edev, ESP3_RADIO_ERP1, data, data_len, &opt, sizeof(opt), timeout);
+	if (ret) {
+		enocean_remove_esp3_dispatcher(edev, &priv->radio_erp1_response);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int enocean_esp3_reset(struct enocean_device *edev, unsigned long timeout)
+{
+	struct enocean_esp3_response resp;
+	const u8 buf[1] = { 0x02 };
+	int ret;
+
+	init_completion(&resp.comp);
+	resp.disp.packet_type = ESP3_RESPONSE;
+	resp.disp.dispatch = enocean_esp3_response_dispatch;
+	enocean_add_esp3_dispatcher(edev, &resp.disp);
+
+	ret = enocean_send_esp3_packet(edev, ESP3_COMMON_COMMAND, buf, sizeof(buf), NULL, 0, timeout);
+	if (ret) {
+		enocean_remove_esp3_dispatcher(edev, &resp.disp);
+		return ret;
+	}
+
+	timeout = wait_for_completion_timeout(&resp.comp, timeout);
+	enocean_remove_esp3_dispatcher(edev, &resp.disp);
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	switch (resp.code) {
+	case 0:
+		return 0;
+	case 1:
+		return -EIO;
+	case 2:
+		return -ENOTSUPP;
+	default:
+		return -EIO;
+	}
+}
+
+struct enocean_esp3_version {
+	u8 app_version[4];
+	u8 api_version[4];
+	__be32 chip_id;
+	__be32 chip_version;
+	char app_desc[16];
+} __packed;
+
+static int enocean_esp3_read_version(struct enocean_device *edev, unsigned long timeout)
+{
+	struct enocean_esp3_response resp;
+	struct enocean_esp3_version *ver;
+	const u8 buf[1] = { 0x03 };
+	int ret;
+
+	init_completion(&resp.comp);
+	resp.disp.packet_type = ESP3_RESPONSE;
+	resp.disp.dispatch = enocean_esp3_response_dispatch;
+	enocean_add_esp3_dispatcher(edev, &resp.disp);
+
+	ret = enocean_send_esp3_packet(edev, ESP3_COMMON_COMMAND, buf, sizeof(buf), NULL, 0, timeout);
+	if (ret) {
+		enocean_remove_esp3_dispatcher(edev, &resp.disp);
+		return ret;
+	}
+
+	timeout = wait_for_completion_timeout(&resp.comp, timeout);
+	enocean_remove_esp3_dispatcher(edev, &resp.disp);
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	switch (resp.code) {
+	case 0:
+		if (!resp.data)
+			return -ENOMEM;
+		break;
+	case 2:
+		if (resp.data)
+			kfree(resp.data);
+		return -ENOTSUPP;
+	default:
+		if (resp.data)
+			kfree(resp.data);
+		return -EIO;
+	}
+
+	ver = resp.data;
+	ver->app_desc[15] = '\0';
+	dev_info(&edev->serdev->dev, "'%s'\n", ver->app_desc);
+	kfree(resp.data);
+
+	return 0;
+}
+
+static int enocean_esp3_receive_buf(struct serdev_device *sdev, const u8 *data, size_t count)
+{
+	struct enocean_device *edev = serdev_device_get_drvdata(sdev);
+	struct enocean_esp3_dispatcher *e;
+	u8 crc8h, crc8d, optional_len;
+	u16 data_len;
+
+	dev_dbg(&sdev->dev, "Receive (%zu)\n", count);
+
+	if (data[0] != ESP3_SYNC_WORD) {
+		dev_warn(&sdev->dev, "not Sync Word (found 0x%02x), skipping\n",
+			(unsigned int)data[0]);
+		return 1;
+	}
+
+	if (count < 6)
+		return 0;
+
+	crc8h = enocean_esp3_crc8((u8*)data + 1, 4);
+	if (data[5] != crc8h) {
+		dev_warn(&sdev->dev, "invalid CRC8H (expected 0x%02x, found 0x%02x), skipping\n",
+			(unsigned int)crc8h, (unsigned int)data[5]);
+		return 1;
+	}
+
+	data_len = be16_to_cpup((__be16 *)(data + 1));
+	optional_len = data[3];
+	if (count < enocean_esp3_packet_size(data_len, optional_len))
+		return 0;
+
+	crc8d = enocean_esp3_crc8((u8*)data + 6, data_len + optional_len);
+	if (data[6 + data_len + optional_len] != crc8d) {
+		dev_warn(&sdev->dev, "invalid CRC8D (expected 0x%02x, found 0x%02x), skipping\n",
+			(unsigned int)crc8d, (unsigned int)data[6 + data_len + optional_len]);
+		return 1;
+	}
+
+	print_hex_dump_debug("received: ", DUMP_PREFIX_NONE, 16, 1, data,
+		enocean_esp3_packet_size(data_len, optional_len), false);
+
+	list_for_each_entry_rcu(e, &edev->esp_dispatchers, list) {
+		if (e->packet_type == data[4])
+			e->dispatch(data + 6, data_len, e);
+	}
+
+	return enocean_esp3_packet_size(data_len, optional_len);
+}
+
+const struct serdev_device_ops enocean_esp3_serdev_client_ops = {
+	.receive_buf = enocean_esp3_receive_buf,
+	.write_wakeup = serdev_device_write_wakeup,
+};
+
+int enocean_esp3_send(struct enocean_device *edev, u32 dest, const void *data, int data_len)
+{
+	return enocean_esp3_send_radio_erp1(edev, dest, data, data_len, HZ / 10);
+}
+
+int enocean_esp3_init(struct enocean_device *edev)
+{
+	struct enocean_esp3_priv *priv;
+	int ret;
+
+	ret = enocean_esp3_reset(edev, HZ / 10);
+	if (ret)
+		return ret;
+
+	msleep(100); /* XXX */
+
+	ret = enocean_esp3_read_version(edev, HZ / 10);
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->edev = edev;
+	edev->priv = priv;
+
+	priv->radio_erp1_response.packet_type = ESP3_RESPONSE;
+	priv->radio_erp1_response.dispatch = enocean_esp3_radio_erp1_response_dispatch;
+
+	return 0;
+}
+
+void enocean_esp3_cleanup(struct enocean_device *edev)
+{
+	struct enocean_esp3_priv *priv = edev->priv;
+
+	kfree(priv);
+}
-- 
2.16.4


^ permalink raw reply related

* [RFC net-next 0/4] net: EnOcean prototype driver
From: Andreas Färber @ 2019-01-29  5:01 UTC (permalink / raw)
  To: linux-lpwan, linux-wpan
  Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
	Andreas Färber

Hello,

This series implements a serdev driver for the EnOcean Serial Protocol (ESP).

It follows previous weekend's Z-Wave serdev driver [1], exploring various
wireless technologies surrounding LoRa/FSK/OOK in quest of a solid PHY layer.

The EnOcean Radio Protocol 1 (ERP1) is based on ASK; ERP2 on FSK for sub-GHz
and on IEEE 802.15.4 for 2.4 GHz. The company EnOcean also manufactures some
BLE based devices unrelated to ERP or this patchset.

ESP3 has been tested with basic host -> module -> host communication and
radio transmission via PF_PACKET datagram sockets.
ESP2 has only been tested for telegram checksums and served for abstraction.
Both handle the same radio telegrams, with transparent translation for ESP2.

Note how much further this implementation got on one weekend plus an evening
in comparison with [1], thanks to solid, open protocol documentation.

Unlike Z-Wave's Command Classes, EnOcean relies on a Learn-in process to
interpret incoming telegram data from a certain device ID correctly, i.e.,
the receiver needs to maintain a mapping from device ID to Equipment Profile.

By exposing the radio (sub)telegrams on a socket, userspace still gets to
handle all the gory Equipment Profile dependent data, while abstracting the
ESP-specific frames and checksumming algorithms. So far no netlink layer was
required; BaseID and receiver sensitivity would in theory be ESP2 options,
and ESP3 offers several more. The selection of ESP2 vs. ESP3 is done via DT.

Again, these have been tested as external modules and lack Kbuild/Makefile
integration with the net subsystem for now. A test program is at [2].

The receive path could not yet be tested for lack of devices and is left out.

Have a lot of fun!

Cheers,
Andreas

[1] https://patchwork.ozlabs.org/patch/1028209/
[2] https://github.com/afaerber/lora-modules/blob/master/txenocean.c

P.S. My conclusion here is that PF_PACKET is a viable alternative to my
current PF_LORA, if we extend my recent cfglora patches with more commands:
https://lists.infradead.org/pipermail/linux-lpwan/2019-January/000154.html
Only downside was that for lack of an include/uapi/linux/enocean.h header
file I had to resort to a patch not included here to define ETH_P_ERP2 etc.
for lack of obvious ways to prepend my own if_{ether,arp}.h files.

Andreas Färber (4):
  net: Reserve protocol identifiers for EnOcean
  net: Prepare EnOcean device drivers
  net: enocean: Add ESP3 driver
  net: enocean: Prepare ESP2 support

 drivers/net/enocean/Makefile       |   7 +
 drivers/net/enocean/enocean.c      | 124 +++++++++++++
 drivers/net/enocean/enocean_esp.c  | 287 ++++++++++++++++++++++++++++
 drivers/net/enocean/enocean_esp.h  |  46 +++++
 drivers/net/enocean/enocean_esp2.c | 276 +++++++++++++++++++++++++++
 drivers/net/enocean/enocean_esp3.c | 372 +++++++++++++++++++++++++++++++++++++
 include/linux/enocean/dev.h        |  23 +++
 include/uapi/linux/if_arp.h        |   1 +
 include/uapi/linux/if_ether.h      |   2 +
 9 files changed, 1138 insertions(+)
 create mode 100644 drivers/net/enocean/Makefile
 create mode 100644 drivers/net/enocean/enocean.c
 create mode 100644 drivers/net/enocean/enocean_esp.c
 create mode 100644 drivers/net/enocean/enocean_esp.h
 create mode 100644 drivers/net/enocean/enocean_esp2.c
 create mode 100644 drivers/net/enocean/enocean_esp3.c
 create mode 100644 include/linux/enocean/dev.h

-- 
2.16.4


^ permalink raw reply

* [RFC net-next 1/4] net: Reserve protocol identifiers for EnOcean
From: Andreas Färber @ 2019-01-29  5:01 UTC (permalink / raw)
  To: linux-lpwan, linux-wpan
  Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
	Andreas Färber
In-Reply-To: <20190129050130.10932-1-afaerber@suse.de>

EnOcean wireless technology is based on ASK (ERP1) and FSK (ERP2) modulations
for sub-GHz and on IEEE 802.15.4 for 2.4 GHz.

ARPHRD_ENOCEAN
ETH_P_ERP{1,2}

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/uapi/linux/if_arp.h   | 1 +
 include/uapi/linux/if_ether.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h
index dd7992a441c9..327ef052329f 100644
--- a/include/uapi/linux/if_arp.h
+++ b/include/uapi/linux/if_arp.h
@@ -102,6 +102,7 @@
 #define ARPHRD_LORAWAN	828		/* LoRaWAN			*/
 #define ARPHRD_OOK	829		/* On/Off Keying modulation	*/
 #define ARPHRD_FSK	830		/* Frequency Shift Keying modulation */
+#define ARPHRD_ENOCEAN	832		/* EnOcean			*/
 
 #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
 #define ARPHRD_NONE	  0xFFFE	/* zero header length */
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index 0b5c30f78261..3e22948cc329 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -152,6 +152,8 @@
 #define ETH_P_OOK	0x00FC		/* On/Off Keying modulation	*/
 #define ETH_P_FSK	0x00FD		/* Frequency Shift Keying mod.	*/
 #define ETH_P_FLRC	0x00FE		/* Fast Long Range Communication */
+#define ETH_P_ERP1	0x00FF		/* EnOcean Radio Protocol 1	*/
+#define ETH_P_ERP2	0x0100		/* EnOcean Radio Protocol 2	*/
 
 /*
  *	This is an Ethernet frame header.
-- 
2.16.4


^ permalink raw reply related

* linux-next: build failure after merge of the net-next tree
From: Stephen Rothwell @ 2019-01-29  5:17 UTC (permalink / raw)
  To: David Miller, Networking
  Cc: Linux Next Mailing List, Linux Kernel Mailing List,
	Claudiu Manoil

[-- Attachment #1: Type: text/plain, Size: 2370 bytes --]

Hi all,

After merging the net-next tree, today's linux-next build (powerpc
allyesconfig) failed like this:

drivers/net/ethernet/freescale/enetc/enetc.c: In function 'enetc_alloc_txbdr':
drivers/net/ethernet/freescale/enetc/enetc.c:685:17: error: implicit declaration of function 'vzalloc'; did you mean 'kzalloc'? [-Werror=implicit-function-declaration]
  txr->tx_swbd = vzalloc(txr->bd_count * sizeof(struct enetc_tx_swbd));
                 ^~~~~~~
                 kzalloc
drivers/net/ethernet/freescale/enetc/enetc.c:685:15: warning: assignment to 'struct enetc_tx_swbd *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
  txr->tx_swbd = vzalloc(txr->bd_count * sizeof(struct enetc_tx_swbd));
               ^
drivers/net/ethernet/freescale/enetc/enetc.c:691:3: error: implicit declaration of function 'vfree'; did you mean 'kfree'? [-Werror=implicit-function-declaration]
   vfree(txr->tx_swbd);
   ^~~~~
   kfree
drivers/net/ethernet/freescale/enetc/enetc.c: In function 'enetc_alloc_rxbdr':
drivers/net/ethernet/freescale/enetc/enetc.c:749:15: warning: assignment to 'struct enetc_rx_swbd *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
  rxr->rx_swbd = vzalloc(rxr->bd_count * sizeof(struct enetc_rx_swbd));
               ^

Caused by commit

  d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers")

I have added the following fix patch for today:

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue, 29 Jan 2019 16:13:08 +1100
Subject: [PATCH] enetc: include linux/vmalloc.h for vzalloc etc

Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers")
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 37b587c541ee..5bb9eb35d76d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -5,6 +5,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/of_mdio.h>
+#include <linux/vmalloc.h>
 
 /* ENETC overhead: optional extension BD + 1 BD gap */
 #define ENETC_TXBDS_NEEDED(val)	((val) + 2)
-- 
2.20.1

-- 
Cheers,
Stephen Rothwell

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply related

* Re: [PATCH 06/33] netfilter: nf_tables: Support RULE_ID reference in new rule
From: Cong Wang @ 2019-01-29  5:24 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: NetFilter, David Miller, Linux Kernel Network Developers
In-Reply-To: <20190128235750.18412-7-pablo@netfilter.org>

On Mon, Jan 28, 2019 at 4:00 PM Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>
> From: Phil Sutter <phil@nwl.cc>
>
> To allow for a batch to contain rules in arbitrary ordering, introduce
> NFTA_RULE_POSITION_ID attribute which works just like NFTA_RULE_POSITION
> but contains the ID of another rule within the same batch. This helps
> iptables-nft-restore handling dumps with mixed insert/append commands
> correctly.
>
> Note that NFTA_RULE_POSITION takes precedence over
> NFTA_RULE_POSITION_ID, so if the former is present, the latter is
> ignored.

It looks like you forgot to add NFTA_RULE_POSITION_ID into
nft_rule_policy[]?

^ permalink raw reply

* Re: [PATCH] ath10k: snoc: remove set but not used variable 'ar_snoc'
From: YueHaibing @ 2019-01-29  5:53 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, netdev, linux-wireless, kernel-janitors
In-Reply-To: <1536200965-121172-1-git-send-email-yuehaibing@huawei.com>

ping...

On 2018/9/6 10:29, YueHaibing wrote:
> From: Yue Haibing <yuehaibing@huawei.com>
> 
> Fixes gcc '-Wunused-but-set-variable' warning:
> 
> drivers/net/wireless/ath/ath10k/snoc.c: In function 'ath10k_snoc_tx_pipe_cleanup':
> drivers/net/wireless/ath/ath10k/snoc.c:681:22: warning:
>  variable 'ar_snoc' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
> ---
>  drivers/net/wireless/ath/ath10k/snoc.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
> index fa1843a..2d6ae00 100644
> --- a/drivers/net/wireless/ath/ath10k/snoc.c
> +++ b/drivers/net/wireless/ath/ath10k/snoc.c
> @@ -678,13 +678,11 @@ static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
>  {
>  	struct ath10k_ce_pipe *ce_pipe;
>  	struct ath10k_ce_ring *ce_ring;
> -	struct ath10k_snoc *ar_snoc;
>  	struct sk_buff *skb;
>  	struct ath10k *ar;
>  	int i;
>  
>  	ar = snoc_pipe->hif_ce_state;
> -	ar_snoc = ath10k_snoc_priv(ar);
>  	ce_pipe = snoc_pipe->ce_hdl;
>  	ce_ring = ce_pipe->src_ring;
> 
> 
> .
> 


^ permalink raw reply

* Re: [PATCH] rtlwifi: remove set but not used variable 'cmd_seq'
From: YueHaibing @ 2019-01-29  6:03 UTC (permalink / raw)
  To: Ping-Ke Shih, Kalle Valo; +Cc: linux-wireless, netdev
In-Reply-To: <581817ea-a414-e6ed-3615-5e44837a5221@huawei.com>

+cc netdev@vger.kernel.org

On 2019/1/29 13:57, YueHaibing wrote:
> ping...
> 
> On 2018/9/11 20:12, YueHaibing wrote:
>> Fixes gcc '-Wunused-but-set-variable' warning:
>>
>> drivers/net/wireless/realtek/rtlwifi/base.c: In function 'rtl_c2h_content_parsing':
>> drivers/net/wireless/realtek/rtlwifi/base.c:2313:13: warning:
>>  variable 'cmd_seq' set but not used [-Wunused-but-set-variable]
>>
>> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
>> ---
>>  drivers/net/wireless/realtek/rtlwifi/base.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
>> index f4122c8..92b6918 100644
>> --- a/drivers/net/wireless/realtek/rtlwifi/base.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/base.c
>> @@ -2310,11 +2310,10 @@ static void rtl_c2h_content_parsing(struct ieee80211_hw *hw,
>>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>>  	struct rtl_hal_ops *hal_ops = rtlpriv->cfg->ops;
>>  	const struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
>> -	u8 cmd_id, cmd_seq, cmd_len;
>> +	u8 cmd_id, cmd_len;
>>  	u8 *cmd_buf = NULL;
>>  
>>  	cmd_id = GET_C2H_CMD_ID(skb->data);
>> -	cmd_seq = GET_C2H_SEQ(skb->data);
>>  	cmd_len = skb->len - C2H_DATA_OFFSET;
>>  	cmd_buf = GET_C2H_DATA_PTR(skb->data);
>>
>>
>> .
>>


^ permalink raw reply

* [PATCH] include/linux/bpf.h - fix missing prototype warnings...
From: valdis.kletnieks @ 2019-01-29  6:04 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev, linux-kernel

Compiling with W=1 generates warnings:

  CC      kernel/bpf/core.o
kernel/bpf/core.c:721:12: warning: no previous prototype for ?bpf_jit_alloc_exec_limit? [-Wmissing-prototypes]
  721 | u64 __weak bpf_jit_alloc_exec_limit(void)
      |            ^~~~~~~~~~~~~~~~~~~~~~~~
kernel/bpf/core.c:757:14: warning: no previous prototype for ?bpf_jit_alloc_exec? [-Wmissing-prototypes]
  757 | void *__weak bpf_jit_alloc_exec(unsigned long size)
      |              ^~~~~~~~~~~~~~~~~~
kernel/bpf/core.c:762:13: warning: no previous prototype for ?bpf_jit_free_exec? [-Wmissing-prototypes]
  762 | void __weak bpf_jit_free_exec(void *addr)
      |             ^~~~~~~~~~~~~~~~~

All three are weak functions that archs can override, although none do so
currently.  Provide prototypes for when a new arch provides its own.

Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 3851529062ec..99e55313123f 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -472,6 +472,10 @@ _out:							\
 #define BPF_PROG_RUN_ARRAY_CHECK(array, ctx, func)	\
 	__BPF_PROG_RUN_ARRAY(array, ctx, func, true)
 
+u64 __weak bpf_jit_alloc_exec_limit(void);
+void *__weak bpf_jit_alloc_exec(unsigned long size);
+void __weak bpf_jit_free_exec(void *addr);
+
 #ifdef CONFIG_BPF_SYSCALL
 DECLARE_PER_CPU(int, bpf_prog_active);
 


^ permalink raw reply related

* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: maowenan @ 2019-01-29  6:04 UTC (permalink / raw)
  To: Tom Herbert
  Cc: Linux Kernel Network Developers, David S. Miller, Eric Dumazet
In-Reply-To: <CALx6S37xYJAWbpV1f7V0F3d8XKTwWt7sDQLt8hhawwiBzqXLUg@mail.gmail.com>



On 2019/1/29 12:01, Tom Herbert wrote:
> On Mon, Jan 28, 2019 at 7:00 PM maowenan <maowenan@huawei.com> wrote:
>>
>> Hi all,
>> Do you have any comments about this change?
>>
>>
>> On 2019/1/23 11:33, Mao Wenan wrote:
>>> When udp4_gro_receive() get one packet that uh->check=0,
>>> skb_gro_checksum_validate_zero_check() will set the
>>> skb->ip_summed = CHECKSUM_UNNECESSARY;
>>> skb->csum_level = 0;
>>> Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
>>> It is not our expect,  because check=0 in udp header indicates this
>>> packet is no need to caculate checksum, we should go further to do GRO.
>>>
>>> This patch changes the value of csum_cnt according to skb->csum_level.
>>> ---
>>>  include/linux/netdevice.h | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>> index 1377d08..9c819f1 100644
>>> --- a/include/linux/netdevice.h
>>> +++ b/include/linux/netdevice.h
>>> @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
>>>                * during GRO. This saves work if we fallback to normal path.
>>>                */
>>>               __skb_incr_checksum_unnecessary(skb);
>>> +             NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
> 
> That doesn't look right. This would be reinitializing the GRO
> checksums from the beginning.
> 
>>>       }
>>>  }
>>>
>>>
>>
> I assume the code is bailing on this conditional:
> 
> if (NAPI_GRO_CB(skb)->encap_mark ||
>             (skb->ip_summed != CHECKSUM_PARTIAL &&
>              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
>              !NAPI_GRO_CB(skb)->csum_valid) ||
>             !udp_sk(sk)->gro_receive)
>                 goto out_unlock;
> 
> I am trying to remember why this needs to check csum_cnt. If there was
> a csum_cnt for the UDP csum being zero from checksum-unnecessary, it
> was consumed by skb_gro_checksum_validate_zero_check in UDP4 GRO
> received.

We have met the scene about two VMs in different host with vxlan packets, when udp4_gro_receive receives
one packet with ip_summed=CHECKSUM_NONE,csum_cnt=0,csum_valid=0,and udp->check=0, then skb_gro_checksum_validate_zero_check()->
skb_gro_incr_csum_unnecessary() validate it and set ip_summed=CHECKSUM_UNNECESSARY,csum_level=0, but csum_cnt and csum_valid
keep zero value. Then it will be flushed in udp_gro_receive(), the codes as you have showed.

so I think it forgets to modify csum_cnt since csum_level is changed in skb_gro_incr_csum_unnecessary()->__skb_incr_checksum_unnecessary().

> 
> .
> 


^ permalink raw reply

* Re: r8169 Driver - Poor Network Performance Since Kernel 4.19
From: Heiner Kallweit @ 2019-01-29  6:16 UTC (permalink / raw)
  To: Peter Ceiley, Realtek linux nic maintainers; +Cc: netdev
In-Reply-To: <CAMLO_R4rmtLOWwMSqLXLNG5k3fvnfVPSe=vNR=EMUo73mp2=YA@mail.gmail.com>

Hi Peter,

at a first glance it doesn't look like a typical driver issue.
What you could do:

- Test the r8169.c from 4.18 on top of 4.19.

- Check whether disabling ASPM (/sys/module/pcie_aspm) has an effect.

- Bisect between 4.18 and 4.19 to find the offending commit.

Any specific reason why you think root cause is in the driver and not
elsewhere in the network subsystem?

Heiner


On 28.01.2019 23:10, Peter Ceiley wrote:
> Hi Heiner,
> 
> Thanks for getting back to me.
> 
> No, I don't use jumbo packets.
> 
> Bandwidth is *generally* good, and iperf results to my NAS provide
> over 900 Mbits/s in both circumstances. The issue seems to appear when
> establishing a connection and is most notable, for example, on my
> mounted NFS shares where it takes seconds (up to 10's of seconds on
> larger directories) to list the contents of each directory. Once a
> transfer begins on a file, I appear to get good bandwidth.
> 
> I'm unsure of the best scientific data to provide you in order to
> troubleshoot this issue. Running the following
> 
>     netstat -s |grep retransmitted
> 
> shows a steady increase in retransmitted segments each time I list the
> contents of a remote directory, for example, running 'ls' on a
> directory containing 345 media files did the following using kernel
> 4.19.18:
> 
> increased retransmitted segments by 21 and the 'time' command showed
> the following:
>     real    0m19.867s
>     user    0m0.012s
>     sys    0m0.036s
> 
> The same command shows no retransmitted segments running kernel
> 4.18.16 and 'time' showed:
>     real    0m0.300s
>     user    0m0.004s
>     sys    0m0.007s
> 
> ifconfig does not show any RX/TX errors nor dropped packets in either case.
> 
> dmesg XID:
> [    2.979984] r8169 0000:03:00.0 eth0: RTL8168g/8111g,
> f8:b1:56:fe:67:e0, XID 4c000800, IRQ 32
> 
> # lspci -vv
> 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
> RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
>     Subsystem: Dell RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
>     Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B- DisINTx+
>     Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
>     Latency: 0, Cache Line Size: 64 bytes
>     Interrupt: pin A routed to IRQ 19
>     Region 0: I/O ports at d000 [size=256]
>     Region 2: Memory at f7b00000 (64-bit, non-prefetchable) [size=4K]
>     Region 4: Memory at f2100000 (64-bit, prefetchable) [size=16K]
>     Capabilities: [40] Power Management version 3
>         Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA
> PME(D0+,D1+,D2+,D3hot+,D3cold+)
>         Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
>     Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
>         Address: 0000000000000000  Data: 0000
>     Capabilities: [70] Express (v2) Endpoint, MSI 01
>         DevCap:    MaxPayload 128 bytes, PhantFunc 0, Latency L0s
> <512ns, L1 <64us
>             ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
> SlotPowerLimit 10.000W
>         DevCtl:    CorrErr- NonFatalErr- FatalErr- UnsupReq-
>             RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>             MaxPayload 128 bytes, MaxReadReq 4096 bytes
>         DevSta:    CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
>         LnkCap:    Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit
> Latency L0s unlimited, L1 <64us
>             ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
>         LnkCtl:    ASPM L1 Enabled; RCB 64 bytes Disabled- CommClk+
>             ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
>         LnkSta:    Speed 2.5GT/s (ok), Width x1 (ok)
>             TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>         DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+,
> OBFF Via message/WAKE#
>              AtomicOpsCap: 32bit- 64bit- 128bitCAS-
>         DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR+,
> OBFF Disabled
>              AtomicOpsCtl: ReqEn-
>         LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
>              Transmit Margin: Normal Operating Range,
> EnterModifiedCompliance- ComplianceSOS-
>              Compliance De-emphasis: -6dB
>         LnkSta2: Current De-emphasis Level: -6dB,
> EqualizationComplete-, EqualizationPhase1-
>              EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
>     Capabilities: [b0] MSI-X: Enable+ Count=4 Masked-
>         Vector table: BAR=4 offset=00000000
>         PBA: BAR=4 offset=00000800
>     Capabilities: [d0] Vital Product Data
> pcilib: sysfs_read_vpd: read failed: Input/output error
>         Not readable
>     Capabilities: [100 v1] Advanced Error Reporting
>         UESta:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>         UEMsk:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>         UESvrt:    DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
>         CESta:    RxErr+ BadTLP+ BadDLLP+ Rollover- Timeout+ AdvNonFatalErr-
>         CEMsk:    RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
>         AERCap:    First Error Pointer: 00, ECRCGenCap+ ECRCGenEn-
> ECRCChkCap+ ECRCChkEn-
>             MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
>         HeaderLog: 00000000 00000000 00000000 00000000
>     Capabilities: [140 v1] Virtual Channel
>         Caps:    LPEVC=0 RefClk=100ns PATEntryBits=1
>         Arb:    Fixed- WRR32- WRR64- WRR128-
>         Ctrl:    ArbSelect=Fixed
>         Status:    InProgress-
>         VC0:    Caps:    PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
>             Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
>             Ctrl:    Enable+ ID=0 ArbSelect=Fixed TC/VC=01
>             Status:    NegoPending- InProgress-
>     Capabilities: [160 v1] Device Serial Number 01-00-00-00-68-4c-e0-00
>     Capabilities: [170 v1] Latency Tolerance Reporting
>         Max snoop latency: 71680ns
>         Max no snoop latency: 71680ns
>     Kernel driver in use: r8169
>     Kernel modules: r8169
> 
> Please let me know if you have any other ideas in terms of testing.
> 
> Thanks!
> 
> Peter.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> On Tue, 29 Jan 2019 at 05:28, Heiner Kallweit <hkallweit1@gmail.com> wrote:
>>
>> On 28.01.2019 12:13, Peter Ceiley wrote:
>>> Hi,
>>>
>>> I have been experiencing very poor network performance since Kernel
>>> 4.19 and I'm confident it's related to the r8169 driver.
>>>
>>> I have no issue with kernel versions 4.18 and prior. I am experiencing
>>> this issue in kernels 4.19 and 4.20 (currently running/testing with
>>> 4.20.4 & 4.19.18).
>>>
>>> If someone could guide me in the right direction, I'm happy to help
>>> troubleshoot this issue. Note that I have been keeping an eye on one
>>> issue related to loading of the PHY driver, however, my symptoms
>>> differ in that I still have a network connection. I have attempted to
>>> reload the driver on a running system, but this does not improve the
>>> situation.
>>>
>>> Using the proprietary r8168 driver returns my device to proper working order.
>>>
>>> lshw shows:
>>>        description: Ethernet interface
>>>        product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
>>>        vendor: Realtek Semiconductor Co., Ltd.
>>>        physical id: 0
>>>        bus info: pci@0000:03:00.0
>>>        logical name: enp3s0
>>>        version: 0c
>>>        serial:
>>>        size: 1Gbit/s
>>>        capacity: 1Gbit/s
>>>        width: 64 bits
>>>        clock: 33MHz
>>>        capabilities: pm msi pciexpress msix vpd bus_master cap_list
>>> ethernet physical tp aui bnc mii fibre 10bt 10bt-fd 100bt 100bt-fd
>>> 1000bt-fd autonegotiation
>>>        configuration: autonegotiation=on broadcast=yes driver=r8169
>>> duplex=full firmware=rtl8168g-2_0.0.1 02/06/13 ip=192.168.1.25
>>> latency=0 link=yes multicast=yes port=MII speed=1Gbit/s
>>>        resources: irq:19 ioport:d000(size=256)
>>> memory:f7b00000-f7b00fff memory:f2100000-f2103fff
>>>
>>> Kind Regards,
>>>
>>> Peter.
>>>
>> Hi Peter,
>>
>> the description "poor network performance" is quite vague, therefore:
>>
>> - Can you provide any measurements?
>> - iperf results before and after
>> - statistics about dropped packets (rx and/or tx)
>> - Do you use jumbo packets?
>>
>> Also help would be a "lspci -vv" output for the network card and
>> the dmesg output line with the chip XID.
>>
>> Heiner
> 


^ permalink raw reply

* [PATCH net v3] net: l2tp: fix reading optional fields of L2TPv3
From: Jacob Wen @ 2019-01-29  6:18 UTC (permalink / raw)
  To: netdev; +Cc: eric.dumazet, gnault

Use pskb_may_pull() to make sure the optional fields are in skb linear
parts, so we can safely read them in l2tp_recv_common.

It's easy to reproduce the issue with a net driver that supports paged
skb data. Just create a L2TPv3 over IP tunnel and then generates some
network traffic.
Once reproduced, rx err in /sys/kernel/debug/l2tp/tunnels will increase.

Signed-off-by: Jacob Wen <jian.w.wen@oracle.com>
---
Changes in v3:
1. To keep consistency, move the code out of l2tp_recv_common.
2. Use "net" instead of "net-next", since this is a bug fix.

Changes in v2:
1. Only fix L2TPv3 to make code simple. 
   To fix both L2TPv3 and L2TPv2, we'd better refactor l2tp_recv_common. 
   It's complicated to do so.
2. Reloading pointers after pskb_may_pull
---
 net/l2tp/l2tp_core.c |  4 ++++
 net/l2tp/l2tp_core.h | 21 +++++++++++++++++++++
 net/l2tp/l2tp_ip.c   |  3 +++
 net/l2tp/l2tp_ip6.c  |  3 +++
 4 files changed, 31 insertions(+)

diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 26f1d435696a..82c28008b438 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -884,6 +884,10 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
 		goto error;
 	}
 
+	if (tunnel->version != L2TP_HDR_VER_2 &&
+	    l2tp_v3_pull_opt(session, skb, &ptr, &optr))
+		goto error;
+
 	l2tp_recv_common(session, skb, ptr, optr, hdrflags, length);
 	l2tp_session_dec_refcount(session);
 
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 9c9afe94d389..870f8ccf95f7 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -301,6 +301,27 @@ static inline bool l2tp_tunnel_uses_xfrm(const struct l2tp_tunnel *tunnel)
 }
 #endif
 
+/* Pull optional fields of L2TPv3 */
+static inline int l2tp_v3_pull_opt(struct l2tp_session *session, struct sk_buff *skb,
+				   unsigned char **ptr, unsigned char **optr)
+{
+	int opt_len = session->peer_cookie_len + l2tp_get_l2specific_len(session);
+
+	if (opt_len > 0) {
+		int off = *ptr - *optr;
+
+		if (!pskb_may_pull(skb, off + opt_len))
+			return -1;
+
+		if (skb->data != *optr) {
+			*optr = skb->data;
+			*ptr = skb->data + off;
+		}
+	}
+
+	return 0;
+}
+
 #define l2tp_printk(ptr, type, func, fmt, ...)				\
 do {									\
 	if (((ptr)->debug) & (type))					\
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 35f6f86d4dcc..adc736d0a553 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -165,6 +165,9 @@ static int l2tp_ip_recv(struct sk_buff *skb)
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
 	}
 
+	if (l2tp_v3_pull_opt(session, skb, &ptr, &optr))
+		goto discard_sess;
+
 	l2tp_recv_common(session, skb, ptr, optr, 0, skb->len);
 	l2tp_session_dec_refcount(session);
 
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 237f1a4a0b0c..a023bb6eae03 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -178,6 +178,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
 	}
 
+	if (l2tp_v3_pull_opt(session, skb, &ptr, &optr))
+		goto discard_sess;
+
 	l2tp_recv_common(session, skb, ptr, optr, 0, skb->len);
 	l2tp_session_dec_refcount(session);
 
-- 
2.17.1


^ permalink raw reply related

* Re: r8169 Driver - Poor Network Performance Since Kernel 4.19
From: Peter Ceiley @ 2019-01-29  6:20 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Realtek linux nic maintainers, netdev
In-Reply-To: <aa7f3b13-55da-cc09-4d86-9f4ca0db24f7@gmail.com>

Hi Heiner,

Thanks, I'll do some more testing. It might not be the driver - I
assumed it was due to the fact that using the r8168 driver 'resolves'
the issue. I'll see if I can test the r8169.c on top of 4.19 - this is
a good idea.

Cheers,

Peter.

On Tue, 29 Jan 2019 at 17:16, Heiner Kallweit <hkallweit1@gmail.com> wrote:
>
> Hi Peter,
>
> at a first glance it doesn't look like a typical driver issue.
> What you could do:
>
> - Test the r8169.c from 4.18 on top of 4.19.
>
> - Check whether disabling ASPM (/sys/module/pcie_aspm) has an effect.
>
> - Bisect between 4.18 and 4.19 to find the offending commit.
>
> Any specific reason why you think root cause is in the driver and not
> elsewhere in the network subsystem?
>
> Heiner
>
>
> On 28.01.2019 23:10, Peter Ceiley wrote:
> > Hi Heiner,
> >
> > Thanks for getting back to me.
> >
> > No, I don't use jumbo packets.
> >
> > Bandwidth is *generally* good, and iperf results to my NAS provide
> > over 900 Mbits/s in both circumstances. The issue seems to appear when
> > establishing a connection and is most notable, for example, on my
> > mounted NFS shares where it takes seconds (up to 10's of seconds on
> > larger directories) to list the contents of each directory. Once a
> > transfer begins on a file, I appear to get good bandwidth.
> >
> > I'm unsure of the best scientific data to provide you in order to
> > troubleshoot this issue. Running the following
> >
> >     netstat -s |grep retransmitted
> >
> > shows a steady increase in retransmitted segments each time I list the
> > contents of a remote directory, for example, running 'ls' on a
> > directory containing 345 media files did the following using kernel
> > 4.19.18:
> >
> > increased retransmitted segments by 21 and the 'time' command showed
> > the following:
> >     real    0m19.867s
> >     user    0m0.012s
> >     sys    0m0.036s
> >
> > The same command shows no retransmitted segments running kernel
> > 4.18.16 and 'time' showed:
> >     real    0m0.300s
> >     user    0m0.004s
> >     sys    0m0.007s
> >
> > ifconfig does not show any RX/TX errors nor dropped packets in either case.
> >
> > dmesg XID:
> > [    2.979984] r8169 0000:03:00.0 eth0: RTL8168g/8111g,
> > f8:b1:56:fe:67:e0, XID 4c000800, IRQ 32
> >
> > # lspci -vv
> > 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
> > RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
> >     Subsystem: Dell RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
> >     Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> > ParErr- Stepping- SERR- FastB2B- DisINTx+
> >     Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
> > <TAbort- <MAbort- >SERR- <PERR- INTx-
> >     Latency: 0, Cache Line Size: 64 bytes
> >     Interrupt: pin A routed to IRQ 19
> >     Region 0: I/O ports at d000 [size=256]
> >     Region 2: Memory at f7b00000 (64-bit, non-prefetchable) [size=4K]
> >     Region 4: Memory at f2100000 (64-bit, prefetchable) [size=16K]
> >     Capabilities: [40] Power Management version 3
> >         Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA
> > PME(D0+,D1+,D2+,D3hot+,D3cold+)
> >         Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
> >     Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
> >         Address: 0000000000000000  Data: 0000
> >     Capabilities: [70] Express (v2) Endpoint, MSI 01
> >         DevCap:    MaxPayload 128 bytes, PhantFunc 0, Latency L0s
> > <512ns, L1 <64us
> >             ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
> > SlotPowerLimit 10.000W
> >         DevCtl:    CorrErr- NonFatalErr- FatalErr- UnsupReq-
> >             RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
> >             MaxPayload 128 bytes, MaxReadReq 4096 bytes
> >         DevSta:    CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
> >         LnkCap:    Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit
> > Latency L0s unlimited, L1 <64us
> >             ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
> >         LnkCtl:    ASPM L1 Enabled; RCB 64 bytes Disabled- CommClk+
> >             ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
> >         LnkSta:    Speed 2.5GT/s (ok), Width x1 (ok)
> >             TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
> >         DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+,
> > OBFF Via message/WAKE#
> >              AtomicOpsCap: 32bit- 64bit- 128bitCAS-
> >         DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR+,
> > OBFF Disabled
> >              AtomicOpsCtl: ReqEn-
> >         LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
> >              Transmit Margin: Normal Operating Range,
> > EnterModifiedCompliance- ComplianceSOS-
> >              Compliance De-emphasis: -6dB
> >         LnkSta2: Current De-emphasis Level: -6dB,
> > EqualizationComplete-, EqualizationPhase1-
> >              EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
> >     Capabilities: [b0] MSI-X: Enable+ Count=4 Masked-
> >         Vector table: BAR=4 offset=00000000
> >         PBA: BAR=4 offset=00000800
> >     Capabilities: [d0] Vital Product Data
> > pcilib: sysfs_read_vpd: read failed: Input/output error
> >         Not readable
> >     Capabilities: [100 v1] Advanced Error Reporting
> >         UESta:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> > RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> >         UEMsk:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> > RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> >         UESvrt:    DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
> > RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
> >         CESta:    RxErr+ BadTLP+ BadDLLP+ Rollover- Timeout+ AdvNonFatalErr-
> >         CEMsk:    RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
> >         AERCap:    First Error Pointer: 00, ECRCGenCap+ ECRCGenEn-
> > ECRCChkCap+ ECRCChkEn-
> >             MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
> >         HeaderLog: 00000000 00000000 00000000 00000000
> >     Capabilities: [140 v1] Virtual Channel
> >         Caps:    LPEVC=0 RefClk=100ns PATEntryBits=1
> >         Arb:    Fixed- WRR32- WRR64- WRR128-
> >         Ctrl:    ArbSelect=Fixed
> >         Status:    InProgress-
> >         VC0:    Caps:    PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
> >             Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
> >             Ctrl:    Enable+ ID=0 ArbSelect=Fixed TC/VC=01
> >             Status:    NegoPending- InProgress-
> >     Capabilities: [160 v1] Device Serial Number 01-00-00-00-68-4c-e0-00
> >     Capabilities: [170 v1] Latency Tolerance Reporting
> >         Max snoop latency: 71680ns
> >         Max no snoop latency: 71680ns
> >     Kernel driver in use: r8169
> >     Kernel modules: r8169
> >
> > Please let me know if you have any other ideas in terms of testing.
> >
> > Thanks!
> >
> > Peter.
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Tue, 29 Jan 2019 at 05:28, Heiner Kallweit <hkallweit1@gmail.com> wrote:
> >>
> >> On 28.01.2019 12:13, Peter Ceiley wrote:
> >>> Hi,
> >>>
> >>> I have been experiencing very poor network performance since Kernel
> >>> 4.19 and I'm confident it's related to the r8169 driver.
> >>>
> >>> I have no issue with kernel versions 4.18 and prior. I am experiencing
> >>> this issue in kernels 4.19 and 4.20 (currently running/testing with
> >>> 4.20.4 & 4.19.18).
> >>>
> >>> If someone could guide me in the right direction, I'm happy to help
> >>> troubleshoot this issue. Note that I have been keeping an eye on one
> >>> issue related to loading of the PHY driver, however, my symptoms
> >>> differ in that I still have a network connection. I have attempted to
> >>> reload the driver on a running system, but this does not improve the
> >>> situation.
> >>>
> >>> Using the proprietary r8168 driver returns my device to proper working order.
> >>>
> >>> lshw shows:
> >>>        description: Ethernet interface
> >>>        product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
> >>>        vendor: Realtek Semiconductor Co., Ltd.
> >>>        physical id: 0
> >>>        bus info: pci@0000:03:00.0
> >>>        logical name: enp3s0
> >>>        version: 0c
> >>>        serial:
> >>>        size: 1Gbit/s
> >>>        capacity: 1Gbit/s
> >>>        width: 64 bits
> >>>        clock: 33MHz
> >>>        capabilities: pm msi pciexpress msix vpd bus_master cap_list
> >>> ethernet physical tp aui bnc mii fibre 10bt 10bt-fd 100bt 100bt-fd
> >>> 1000bt-fd autonegotiation
> >>>        configuration: autonegotiation=on broadcast=yes driver=r8169
> >>> duplex=full firmware=rtl8168g-2_0.0.1 02/06/13 ip=192.168.1.25
> >>> latency=0 link=yes multicast=yes port=MII speed=1Gbit/s
> >>>        resources: irq:19 ioport:d000(size=256)
> >>> memory:f7b00000-f7b00fff memory:f2100000-f2103fff
> >>>
> >>> Kind Regards,
> >>>
> >>> Peter.
> >>>
> >> Hi Peter,
> >>
> >> the description "poor network performance" is quite vague, therefore:
> >>
> >> - Can you provide any measurements?
> >> - iperf results before and after
> >> - statistics about dropped packets (rx and/or tx)
> >> - Do you use jumbo packets?
> >>
> >> Also help would be a "lspci -vv" output for the network card and
> >> the dmesg output line with the chip XID.
> >>
> >> Heiner
> >
>

^ permalink raw reply

* Re: [PATCH] netfilter: nat: Update comment of get_unique_tuple
From: YueHaibing @ 2019-01-29  6:20 UTC (permalink / raw)
  To: pablo, kadlec, fw, davem; +Cc: linux-kernel, netdev, netfilter-devel, coreteam
In-Reply-To: <20190110130618.25344-1-yuehaibing@huawei.com>

Friendly ping...

On 2019/1/10 21:06, YueHaibing wrote:
> Replace outdated __ip_conntrack_confirm in comment.
> 
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
>  net/netfilter/nf_nat_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
> index d159e9e..f54a8db 100644
> --- a/net/netfilter/nf_nat_core.c
> +++ b/net/netfilter/nf_nat_core.c
> @@ -460,7 +460,8 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
>   * and NF_INET_LOCAL_OUT, we change the destination to map into the
>   * range. It might not be possible to get a unique tuple, but we try.
>   * At worst (or if we race), we will end up with a final duplicate in
> - * __ip_conntrack_confirm and drop the packet. */
> + * __nf_conntrack_confirm and drop the packet.
> + */
>  static void
>  get_unique_tuple(struct nf_conntrack_tuple *tuple,
>  		 const struct nf_conntrack_tuple *orig_tuple,
> 


^ permalink raw reply

* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: Tom Herbert @ 2019-01-29  6:24 UTC (permalink / raw)
  To: maowenan; +Cc: Linux Kernel Network Developers, David S. Miller, Eric Dumazet
In-Reply-To: <038cf844-ca2f-8db2-7ed6-fee39cbcfc7d@huawei.com>

On Mon, Jan 28, 2019 at 10:04 PM maowenan <maowenan@huawei.com> wrote:
>
>
>
> On 2019/1/29 12:01, Tom Herbert wrote:
> > On Mon, Jan 28, 2019 at 7:00 PM maowenan <maowenan@huawei.com> wrote:
> >>
> >> Hi all,
> >> Do you have any comments about this change?
> >>
> >>
> >> On 2019/1/23 11:33, Mao Wenan wrote:
> >>> When udp4_gro_receive() get one packet that uh->check=0,
> >>> skb_gro_checksum_validate_zero_check() will set the
> >>> skb->ip_summed = CHECKSUM_UNNECESSARY;
> >>> skb->csum_level = 0;
> >>> Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
> >>> It is not our expect,  because check=0 in udp header indicates this
> >>> packet is no need to caculate checksum, we should go further to do GRO.
> >>>
> >>> This patch changes the value of csum_cnt according to skb->csum_level.
> >>> ---
> >>>  include/linux/netdevice.h | 1 +
> >>>  1 file changed, 1 insertion(+)
> >>>
> >>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> >>> index 1377d08..9c819f1 100644
> >>> --- a/include/linux/netdevice.h
> >>> +++ b/include/linux/netdevice.h
> >>> @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
> >>>                * during GRO. This saves work if we fallback to normal path.
> >>>                */
> >>>               __skb_incr_checksum_unnecessary(skb);
> >>> +             NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
> >
> > That doesn't look right. This would be reinitializing the GRO
> > checksums from the beginning.
> >
> >>>       }
> >>>  }
> >>>
> >>>
> >>
> > I assume the code is bailing on this conditional:
> >
> > if (NAPI_GRO_CB(skb)->encap_mark ||
> >             (skb->ip_summed != CHECKSUM_PARTIAL &&
> >              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
> >              !NAPI_GRO_CB(skb)->csum_valid) ||
> >             !udp_sk(sk)->gro_receive)
> >                 goto out_unlock;
> >
> > I am trying to remember why this needs to check csum_cnt. If there was
> > a csum_cnt for the UDP csum being zero from checksum-unnecessary, it
> > was consumed by skb_gro_checksum_validate_zero_check in UDP4 GRO
> > received.
>
> We have met the scene about two VMs in different host with vxlan packets, when udp4_gro_receive receives
> one packet with ip_summed=CHECKSUM_NONE,csum_cnt=0,csum_valid=0,and udp->check=0, then skb_gro_checksum_validate_zero_check()->
> skb_gro_incr_csum_unnecessary() validate it and set ip_summed=CHECKSUM_UNNECESSARY,csum_level=0, but csum_cnt and csum_valid
> keep zero value. Then it will be flushed in udp_gro_receive(), the codes as you have showed.
>
> so I think it forgets to modify csum_cnt since csum_level is changed in skb_gro_incr_csum_unnecessary()->__skb_incr_checksum_unnecessary().
>
Yes, but the csum_level is changing since we've gone beyond the
checksums initially reported inc checksum-unnecessary. GRO csum_cnt is
initialized to skb->csum_level + 1 at the start of GRO processing.

If I recall, the rule is that UDP GRO requires at least one non-zero
checksum to be verified. The idea is that if we end up computing
packet checksums on the host for inner checksums like TCP during GRO,
then that's negating the performance benefits of GRO. Had UDP check
not been zero then we would do checksum unnecessary conversion and so
csum_valid would be set for the remainded of GRO processing. The
existing code is following the rule I believe, so this may be working
as intended.

Tom

> >
> > .
> >
>

^ permalink raw reply

* [PATCH] selftests/netfilter: fix config fragment CONFIG_NF_TABLES_INET
From: Naresh Kamboju @ 2019-01-29  6:28 UTC (permalink / raw)
  To: netfilter-devel, netdev; +Cc: fw, pablo, davem, linux-kselftest, Naresh Kamboju

In selftests the config fragment for netfilter was added as
NF_TABLES_INET=y and this patch correct it as CONFIG_NF_TABLES_INET=y

Signed-off-by: Naresh Kamboju <naresh.kamboju@linaro.org>
---
 tools/testing/selftests/netfilter/config | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config
index 1017313e41a8..59caa8f71cd8 100644
--- a/tools/testing/selftests/netfilter/config
+++ b/tools/testing/selftests/netfilter/config
@@ -1,2 +1,2 @@
 CONFIG_NET_NS=y
-NF_TABLES_INET=y
+CONFIG_NF_TABLES_INET=y
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: Stefan Hajnoczi @ 2019-01-29  6:30 UTC (permalink / raw)
  To: Jason Wang; +Cc: mst, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190128070505.18335-1-jasowang@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2566 bytes --]

On Mon, Jan 28, 2019 at 03:05:05PM +0800, Jason Wang wrote:
> After batched used ring updating was introduced in commit e2b3b35eb989
> ("vhost_net: batch used ring update in rx"). We tend to batch heads in
> vq->heads for more than one packet. But the quota passed to
> get_rx_bufs() was not correctly limited, which can result a OOB write
> in vq->heads.
> 
>         headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
>                     vhost_len, &in, vq_log, &log,
>                     likely(mergeable) ? UIO_MAXIOV : 1);
> 
> UIO_MAXIOV was still used which is wrong since we could have batched
> used in vq->heads, this will cause OOB if the next buffer needs more
> than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
> batched 64 (VHOST_NET_BATCH) heads:
> 
> =============================================================================
> BUG kmalloc-8k (Tainted: G    B            ): Redzone overwritten
> -----------------------------------------------------------------------------
> 
> INFO: 0x00000000fd93b7a2-0x00000000f0713384. First byte 0xa9 instead of 0xcc
> INFO: Allocated in alloc_pd+0x22/0x60 age=3933677 cpu=2 pid=2674
>     kmem_cache_alloc_trace+0xbb/0x140
>     alloc_pd+0x22/0x60
>     gen8_ppgtt_create+0x11d/0x5f0
>     i915_ppgtt_create+0x16/0x80
>     i915_gem_create_context+0x248/0x390
>     i915_gem_context_create_ioctl+0x4b/0xe0
>     drm_ioctl_kernel+0xa5/0xf0
>     drm_ioctl+0x2ed/0x3a0
>     do_vfs_ioctl+0x9f/0x620
>     ksys_ioctl+0x6b/0x80
>     __x64_sys_ioctl+0x11/0x20
>     do_syscall_64+0x43/0xf0
>     entry_SYSCALL_64_after_hwframe+0x44/0xa9
> INFO: Slab 0x00000000d13e87af objects=3 used=3 fp=0x          (null) flags=0x200000000010201
> INFO: Object 0x0000000003278802 @offset=17064 fp=0x00000000e2e6652b
> 
> Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
> vhost-net. This is done through set the limitation through
> vhost_dev_init(), then set_owner can allocate the number of iov in a
> per device manner.
> 
> This fixes CVE-2018-16880.
> 
> Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>  drivers/vhost/net.c   | 3 ++-
>  drivers/vhost/scsi.c  | 2 +-
>  drivers/vhost/vhost.c | 7 ++++---
>  drivers/vhost/vhost.h | 4 +++-
>  drivers/vhost/vsock.c | 2 +-
>  5 files changed, 11 insertions(+), 7 deletions(-)

No change in the scsi and vsock cases.  I haven't reviewed the net case.

Acked-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply

* Re: linux-next: build failure after merge of the net-next tree
From: David Miller @ 2019-01-29  6:43 UTC (permalink / raw)
  To: sfr; +Cc: netdev, linux-next, linux-kernel, claudiu.manoil
In-Reply-To: <20190129161742.6b1b7338@canb.auug.org.au>

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue, 29 Jan 2019 16:17:42 +1100

> I have added the following fix patch for today:
> 
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Tue, 29 Jan 2019 16:13:08 +1100
> Subject: [PATCH] enetc: include linux/vmalloc.h for vzalloc etc
> 
> Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers")
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>

Applied to net-next.

^ permalink raw reply

* Re: r8169 Driver - Poor Network Performance Since Kernel 4.19
From: Heiner Kallweit @ 2019-01-29  6:44 UTC (permalink / raw)
  To: Peter Ceiley; +Cc: Realtek linux nic maintainers, netdev
In-Reply-To: <CAMLO_R5ksPHdAm-q-t3XB_AKyHTGNf76wZNLSHeOR5iYQTzoHg@mail.gmail.com>

Hi Peter,

I think the vendor driver doesn't enable ASPM per default.
So it's worth a try to disable ASPM in the BIOS or via sysfs.
Few older systems seem to have issues with ASPM, what kind of
system / mainboard are you using? The RTL8168 is the onboard
network chip?

Rgds, Heiner


On 29.01.2019 07:20, Peter Ceiley wrote:
> Hi Heiner,
> 
> Thanks, I'll do some more testing. It might not be the driver - I
> assumed it was due to the fact that using the r8168 driver 'resolves'
> the issue. I'll see if I can test the r8169.c on top of 4.19 - this is
> a good idea.
> 
> Cheers,
> 
> Peter.
> 
> On Tue, 29 Jan 2019 at 17:16, Heiner Kallweit <hkallweit1@gmail.com> wrote:
>>
>> Hi Peter,
>>
>> at a first glance it doesn't look like a typical driver issue.
>> What you could do:
>>
>> - Test the r8169.c from 4.18 on top of 4.19.
>>
>> - Check whether disabling ASPM (/sys/module/pcie_aspm) has an effect.
>>
>> - Bisect between 4.18 and 4.19 to find the offending commit.
>>
>> Any specific reason why you think root cause is in the driver and not
>> elsewhere in the network subsystem?
>>
>> Heiner
>>
>>
>> On 28.01.2019 23:10, Peter Ceiley wrote:
>>> Hi Heiner,
>>>
>>> Thanks for getting back to me.
>>>
>>> No, I don't use jumbo packets.
>>>
>>> Bandwidth is *generally* good, and iperf results to my NAS provide
>>> over 900 Mbits/s in both circumstances. The issue seems to appear when
>>> establishing a connection and is most notable, for example, on my
>>> mounted NFS shares where it takes seconds (up to 10's of seconds on
>>> larger directories) to list the contents of each directory. Once a
>>> transfer begins on a file, I appear to get good bandwidth.
>>>
>>> I'm unsure of the best scientific data to provide you in order to
>>> troubleshoot this issue. Running the following
>>>
>>>     netstat -s |grep retransmitted
>>>
>>> shows a steady increase in retransmitted segments each time I list the
>>> contents of a remote directory, for example, running 'ls' on a
>>> directory containing 345 media files did the following using kernel
>>> 4.19.18:
>>>
>>> increased retransmitted segments by 21 and the 'time' command showed
>>> the following:
>>>     real    0m19.867s
>>>     user    0m0.012s
>>>     sys    0m0.036s
>>>
>>> The same command shows no retransmitted segments running kernel
>>> 4.18.16 and 'time' showed:
>>>     real    0m0.300s
>>>     user    0m0.004s
>>>     sys    0m0.007s
>>>
>>> ifconfig does not show any RX/TX errors nor dropped packets in either case.
>>>
>>> dmesg XID:
>>> [    2.979984] r8169 0000:03:00.0 eth0: RTL8168g/8111g,
>>> f8:b1:56:fe:67:e0, XID 4c000800, IRQ 32
>>>
>>> # lspci -vv
>>> 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
>>> RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)
>>>     Subsystem: Dell RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
>>>     Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
>>> ParErr- Stepping- SERR- FastB2B- DisINTx+
>>>     Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
>>> <TAbort- <MAbort- >SERR- <PERR- INTx-
>>>     Latency: 0, Cache Line Size: 64 bytes
>>>     Interrupt: pin A routed to IRQ 19
>>>     Region 0: I/O ports at d000 [size=256]
>>>     Region 2: Memory at f7b00000 (64-bit, non-prefetchable) [size=4K]
>>>     Region 4: Memory at f2100000 (64-bit, prefetchable) [size=16K]
>>>     Capabilities: [40] Power Management version 3
>>>         Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA
>>> PME(D0+,D1+,D2+,D3hot+,D3cold+)
>>>         Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
>>>     Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
>>>         Address: 0000000000000000  Data: 0000
>>>     Capabilities: [70] Express (v2) Endpoint, MSI 01
>>>         DevCap:    MaxPayload 128 bytes, PhantFunc 0, Latency L0s
>>> <512ns, L1 <64us
>>>             ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
>>> SlotPowerLimit 10.000W
>>>         DevCtl:    CorrErr- NonFatalErr- FatalErr- UnsupReq-
>>>             RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>>>             MaxPayload 128 bytes, MaxReadReq 4096 bytes
>>>         DevSta:    CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
>>>         LnkCap:    Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit
>>> Latency L0s unlimited, L1 <64us
>>>             ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
>>>         LnkCtl:    ASPM L1 Enabled; RCB 64 bytes Disabled- CommClk+
>>>             ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
>>>         LnkSta:    Speed 2.5GT/s (ok), Width x1 (ok)
>>>             TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>>>         DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+,
>>> OBFF Via message/WAKE#
>>>              AtomicOpsCap: 32bit- 64bit- 128bitCAS-
>>>         DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR+,
>>> OBFF Disabled
>>>              AtomicOpsCtl: ReqEn-
>>>         LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
>>>              Transmit Margin: Normal Operating Range,
>>> EnterModifiedCompliance- ComplianceSOS-
>>>              Compliance De-emphasis: -6dB
>>>         LnkSta2: Current De-emphasis Level: -6dB,
>>> EqualizationComplete-, EqualizationPhase1-
>>>              EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
>>>     Capabilities: [b0] MSI-X: Enable+ Count=4 Masked-
>>>         Vector table: BAR=4 offset=00000000
>>>         PBA: BAR=4 offset=00000800
>>>     Capabilities: [d0] Vital Product Data
>>> pcilib: sysfs_read_vpd: read failed: Input/output error
>>>         Not readable
>>>     Capabilities: [100 v1] Advanced Error Reporting
>>>         UESta:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
>>> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>>>         UEMsk:    DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
>>> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>>>         UESvrt:    DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
>>> RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
>>>         CESta:    RxErr+ BadTLP+ BadDLLP+ Rollover- Timeout+ AdvNonFatalErr-
>>>         CEMsk:    RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
>>>         AERCap:    First Error Pointer: 00, ECRCGenCap+ ECRCGenEn-
>>> ECRCChkCap+ ECRCChkEn-
>>>             MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
>>>         HeaderLog: 00000000 00000000 00000000 00000000
>>>     Capabilities: [140 v1] Virtual Channel
>>>         Caps:    LPEVC=0 RefClk=100ns PATEntryBits=1
>>>         Arb:    Fixed- WRR32- WRR64- WRR128-
>>>         Ctrl:    ArbSelect=Fixed
>>>         Status:    InProgress-
>>>         VC0:    Caps:    PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
>>>             Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
>>>             Ctrl:    Enable+ ID=0 ArbSelect=Fixed TC/VC=01
>>>             Status:    NegoPending- InProgress-
>>>     Capabilities: [160 v1] Device Serial Number 01-00-00-00-68-4c-e0-00
>>>     Capabilities: [170 v1] Latency Tolerance Reporting
>>>         Max snoop latency: 71680ns
>>>         Max no snoop latency: 71680ns
>>>     Kernel driver in use: r8169
>>>     Kernel modules: r8169
>>>
>>> Please let me know if you have any other ideas in terms of testing.
>>>
>>> Thanks!
>>>
>>> Peter.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Tue, 29 Jan 2019 at 05:28, Heiner Kallweit <hkallweit1@gmail.com> wrote:
>>>>
>>>> On 28.01.2019 12:13, Peter Ceiley wrote:
>>>>> Hi,
>>>>>
>>>>> I have been experiencing very poor network performance since Kernel
>>>>> 4.19 and I'm confident it's related to the r8169 driver.
>>>>>
>>>>> I have no issue with kernel versions 4.18 and prior. I am experiencing
>>>>> this issue in kernels 4.19 and 4.20 (currently running/testing with
>>>>> 4.20.4 & 4.19.18).
>>>>>
>>>>> If someone could guide me in the right direction, I'm happy to help
>>>>> troubleshoot this issue. Note that I have been keeping an eye on one
>>>>> issue related to loading of the PHY driver, however, my symptoms
>>>>> differ in that I still have a network connection. I have attempted to
>>>>> reload the driver on a running system, but this does not improve the
>>>>> situation.
>>>>>
>>>>> Using the proprietary r8168 driver returns my device to proper working order.
>>>>>
>>>>> lshw shows:
>>>>>        description: Ethernet interface
>>>>>        product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
>>>>>        vendor: Realtek Semiconductor Co., Ltd.
>>>>>        physical id: 0
>>>>>        bus info: pci@0000:03:00.0
>>>>>        logical name: enp3s0
>>>>>        version: 0c
>>>>>        serial:
>>>>>        size: 1Gbit/s
>>>>>        capacity: 1Gbit/s
>>>>>        width: 64 bits
>>>>>        clock: 33MHz
>>>>>        capabilities: pm msi pciexpress msix vpd bus_master cap_list
>>>>> ethernet physical tp aui bnc mii fibre 10bt 10bt-fd 100bt 100bt-fd
>>>>> 1000bt-fd autonegotiation
>>>>>        configuration: autonegotiation=on broadcast=yes driver=r8169
>>>>> duplex=full firmware=rtl8168g-2_0.0.1 02/06/13 ip=192.168.1.25
>>>>> latency=0 link=yes multicast=yes port=MII speed=1Gbit/s
>>>>>        resources: irq:19 ioport:d000(size=256)
>>>>> memory:f7b00000-f7b00fff memory:f2100000-f2103fff
>>>>>
>>>>> Kind Regards,
>>>>>
>>>>> Peter.
>>>>>
>>>> Hi Peter,
>>>>
>>>> the description "poor network performance" is quite vague, therefore:
>>>>
>>>> - Can you provide any measurements?
>>>> - iperf results before and after
>>>> - statistics about dropped packets (rx and/or tx)
>>>> - Do you use jumbo packets?
>>>>
>>>> Also help would be a "lspci -vv" output for the network card and
>>>> the dmesg output line with the chip XID.
>>>>
>>>> Heiner
>>>
>>
> 


^ permalink raw reply

* [PATCH] kernel/bpf/cgroup.c - clean up kerneldoc warnings
From: valdis.kletnieks @ 2019-01-29  6:47 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev, linux-kernel

Building with W=1 reveals some bitrot 

  CC      kernel/bpf/cgroup.o
kernel/bpf/cgroup.c:238: warning: Function parameter or member 'flags' not described in '__cgroup_bpf_attach'
kernel/bpf/cgroup.c:367: warning: Function parameter or member 'unused_flags' not described in '__cgroup_bpf_detach'

Add a kerneldoc line for 'flags'.

Fixing the warning for 'unused_flags' is best approached by
removing the unused parameter on the function call.

Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 588dd5f0bd85..695b2a880d9a 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -78,7 +78,7 @@ int cgroup_bpf_inherit(struct cgroup *cgrp);
 int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 			enum bpf_attach_type type, u32 flags);
 int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
-			enum bpf_attach_type type, u32 flags);
+			enum bpf_attach_type type);
 int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
 		       union bpf_attr __user *uattr);
 
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index ab612fe9862f..d78cfec5807d 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -230,6 +230,7 @@ static int update_effective_progs(struct cgroup *cgrp,
  * @cgrp: The cgroup which descendants to traverse
  * @prog: A program to attach
  * @type: Type of attach operation
+ * @flags: Option flags
  *
  * Must be called with cgroup_mutex held.
  */
@@ -363,7 +364,7 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
  * Must be called with cgroup_mutex held.
  */
 int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
-			enum bpf_attach_type type, u32 unused_flags)
+			enum bpf_attach_type type)
 {
 	struct list_head *progs = &cgrp->bpf.progs[type];
 	enum bpf_cgroup_storage_type stype;
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 6d03a27918f4..9802ab424397 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -6059,7 +6059,7 @@ int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 	int ret;
 
 	mutex_lock(&cgroup_mutex);
-	ret = __cgroup_bpf_detach(cgrp, prog, type, flags);
+	ret = __cgroup_bpf_detach(cgrp, prog, type);
 	mutex_unlock(&cgroup_mutex);
 	return ret;
 }


^ permalink raw reply related

* [PATCH net] ipv6: sr: clear IP6CB(skb) on SRH ip4ip6 encapsulation
From: Yohei Kanemaru @ 2019-01-29  6:52 UTC (permalink / raw)
  To: netdev, davem, dlebrun; +Cc: Yohei Kanemaru

skb->cb may contain data from previous layers (in an observed case
IPv4 with L3 Master Device). In the observed scenario, the data in
IPCB(skb)->frags was misinterpreted as IP6CB(skb)->frag_max_size,
eventually caused an unexpected IPv6 fragmentation in ip6_fragment()
through ip6_finish_output().

This patch clears IP6CB(skb), which potentially contains garbage data,
on the SRH ip4ip6 encapsulation.

Fixes: 32d99d0b6702 ("ipv6: sr: add support for ip4ip6 encapsulation")
Signed-off-by: Yohei Kanemaru <yohei.kanemaru@gmail.com>
---
 net/ipv6/seg6_iptunnel.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 8181ee7..ee5403c 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -146,6 +146,8 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
 	} else {
 		ip6_flow_hdr(hdr, 0, flowlabel);
 		hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));
+
+		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
 	}
 
 	hdr->nexthdr = NEXTHDR_ROUTING;
-- 
2.10.0


^ permalink raw reply related

* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29  6:54 UTC (permalink / raw)
  To: jasowang; +Cc: mst, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190128070505.18335-1-jasowang@redhat.com>

From: Jason Wang <jasowang@redhat.com>
Date: Mon, 28 Jan 2019 15:05:05 +0800

> After batched used ring updating was introduced in commit e2b3b35eb989
> ("vhost_net: batch used ring update in rx"). We tend to batch heads in
> vq->heads for more than one packet. But the quota passed to
> get_rx_bufs() was not correctly limited, which can result a OOB write
> in vq->heads.
> 
>         headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
>                     vhost_len, &in, vq_log, &log,
>                     likely(mergeable) ? UIO_MAXIOV : 1);
> 
> UIO_MAXIOV was still used which is wrong since we could have batched
> used in vq->heads, this will cause OOB if the next buffer needs more
> than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
> batched 64 (VHOST_NET_BATCH) heads:
 ...
> Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
> vhost-net. This is done through set the limitation through
> vhost_dev_init(), then set_owner can allocate the number of iov in a
> per device manner.
> 
> This fixes CVE-2018-16880.
> 
> Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
> Signed-off-by: Jason Wang <jasowang@redhat.com>

Applied and queued up for -stable, thanks!

^ permalink raw reply

* [PATCH net-next] net: nci: remove set-but-not-used variable 'status'
From: YueHaibing @ 2019-01-29  6:40 UTC (permalink / raw)
  To: davem, sameo; +Cc: linux-kernel, netdev, linux-wireless, YueHaibing

gcc warning this:
net/nfc/nci/hci.c:373:5:
 warning: variable 'status' set but not used [-Wunused-but-set-variable]

It not used since commit d8cd37ed2fc8 ("NFC: nci: Fix improper
management of HCI return code"), so can be removed.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 net/nfc/nci/hci.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
index ddfc52a..4debba8 100644
--- a/net/nfc/nci/hci.c
+++ b/net/nfc/nci/hci.c
@@ -370,17 +370,11 @@ static void nci_hci_resp_received(struct nci_dev *ndev, u8 pipe,
 				  u8 result, struct sk_buff *skb)
 {
 	struct nci_conn_info    *conn_info;
-	u8 status = result;
 
 	conn_info = ndev->hci_dev->conn_info;
-	if (!conn_info) {
-		status = NCI_STATUS_REJECTED;
-		goto exit;
-	}
-
-	conn_info->rx_skb = skb;
+	if (conn_info)
+		conn_info->rx_skb = skb;
 
-exit:
 	nci_req_complete(ndev, NCI_STATUS_OK);
 }
 
-- 
2.7.0



^ permalink raw reply related

* Re: [PATCH bpf-next] bpf: check that BPF programs run with preemption disabled
From: Song Liu @ 2019-01-29  7:00 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David Miller, Daniel Borkmann, peterz@infradead.org,
	jannh@google.com, paulmck@linux.ibm.com, will.deacon@arm.com,
	mingo@redhat.com, netdev@vger.kernel.org, Kernel Team
In-Reply-To: <20190129012152.251061-1-ast@kernel.org>



> On Jan 28, 2019, at 5:21 PM, Alexei Starovoitov <ast@kernel.org> wrote:
> 
> From: Peter Zijlstra <peterz@infradead.org>
> 
> Introduce cant_sleep() macro for annotation of functions that cannot sleep.
> 
> Use it in BPF_PROG_RUN to catch execution of BPF programs
> in preemptable context.
> 
> Suggested-by: Jann Horn <jannh@google.com>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>

Acked-by: Song Liu <songliubraving@fb.com>


> ---
> include/linux/filter.h |  2 +-
> include/linux/kernel.h | 14 ++++++++++++--
> kernel/sched/core.c    | 28 ++++++++++++++++++++++++++++
> 3 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index e4b473f85b46..7e87863617b3 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -533,7 +533,7 @@ struct sk_filter {
> 	struct bpf_prog	*prog;
> };
> 
> -#define BPF_PROG_RUN(filter, ctx)  (*(filter)->bpf_func)(ctx, (filter)->insnsi)
> +#define BPF_PROG_RUN(filter, ctx)  ({ cant_sleep(); (*(filter)->bpf_func)(ctx, (filter)->insnsi); })
> 
> #define BPF_SKB_CB_LEN QDISC_CB_PRIV_LEN
> 
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 8f0e68e250a7..a8868a32098c 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -245,8 +245,10 @@ extern int _cond_resched(void);
> #endif
> 
> #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
> -  void ___might_sleep(const char *file, int line, int preempt_offset);
> -  void __might_sleep(const char *file, int line, int preempt_offset);
> +extern void ___might_sleep(const char *file, int line, int preempt_offset);
> +extern void __might_sleep(const char *file, int line, int preempt_offset);
> +extern void __cant_sleep(const char *file, int line, int preempt_offset);
> +
> /**
>  * might_sleep - annotation for functions that can sleep
>  *
> @@ -259,6 +261,13 @@ extern int _cond_resched(void);
>  */
> # define might_sleep() \
> 	do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)
> +/**
> + * cant_sleep - annotation for functions that cannot sleep
> + *
> + * this macro will print a stack trace if it is executed with preemption enabled
> + */
> +# define cant_sleep() \
> +	do { __cant_sleep(__FILE__, __LINE__, 0); } while (0)
> # define sched_annotate_sleep()	(current->task_state_change = 0)
> #else
>   static inline void ___might_sleep(const char *file, int line,
> @@ -266,6 +275,7 @@ extern int _cond_resched(void);
>   static inline void __might_sleep(const char *file, int line,
> 				   int preempt_offset) { }
> # define might_sleep() do { might_resched(); } while (0)
> +# define cant_sleep() do { } while (0)
> # define sched_annotate_sleep() do { } while (0)
> #endif
> 
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index a674c7db2f29..1dcbff62f973 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -6149,6 +6149,34 @@ void ___might_sleep(const char *file, int line, int preempt_offset)
> 	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
> }
> EXPORT_SYMBOL(___might_sleep);
> +
> +void __cant_sleep(const char *file, int line, int preempt_offset)
> +{
> +	static unsigned long prev_jiffy;
> +
> +	if (irqs_disabled())
> +		return;
> +
> +	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
> +		return;
> +
> +	if (preempt_count() > preempt_offset)
> +		return;
> +
> +	if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
> +		return;
> +	prev_jiffy = jiffies;
> +
> +	printk(KERN_ERR "BUG: assuming atomic context at %s:%d\n", file, line);
> +	printk(KERN_ERR "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
> +			in_atomic(), irqs_disabled(),
> +			current->pid, current->comm);
> +
> +	debug_show_held_locks(current);
> +	dump_stack();
> +	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
> +}
> +EXPORT_SYMBOL_GPL(__cant_sleep);
> #endif
> 
> #ifdef CONFIG_MAGIC_SYSRQ
> -- 
> 2.20.0
> 


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox