From: Jiri Pirko
Introduce devlink infrastructure for drivers to register and expose to
userspace via generic Netlink interface.
There are two basic objects defined:
devlink - one instance for every "parent device", for example switch ASIC
devlink port - one instance for every physical port of the device.
This initial portion implements basic get/dump of objects to userspace.
Also, hardware message monitoring and port type setting is implemented.
Signed-off-by: Jiri Pirko
---
MAINTAINERS | 8 +
include/net/devlink.h| 152
include/uapi/linux/devlink.h | 83 +
net/Kconfig | 7 +
net/core/Makefile| 1 +
net/core/devlink.c | 856 +++
6 files changed, 1107 insertions(+)
create mode 100644 include/net/devlink.h
create mode 100644 include/uapi/linux/devlink.h
create mode 100644 net/core/devlink.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f678c37..c4efa8d7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3501,6 +3501,14 @@ F: include/linux/device-mapper.h
F: include/linux/dm-*.h
F: include/uapi/linux/dm-*.h
+DEVLINK
+M: Jiri Pirko
+L: netdev@vger.kernel.org
+S: Supported
+F: net/core/devlink.c
+F: include/net/devlink.h
+F: include/uapi/linux/devlink.h
+
DIALOG SEMICONDUCTOR DRIVERS
M: Support Opensource
W: http://www.dialog-semiconductor.com/products
diff --git a/include/net/devlink.h b/include/net/devlink.h
new file mode 100644
index 000..a7888e2
--- /dev/null
+++ b/include/net/devlink.h
@@ -0,0 +1,152 @@
+/*
+ * include/net/devlink.h - Network physical device Netlink interface
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Jiri Pirko
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef _NET_DEVLINK_H_
+#define _NET_DEVLINK_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct devlink_ops;
+
+struct devlink {
+ struct list_head list;
+ struct list_head port_list;
+ int index;
+ const struct devlink_ops *ops;
+ struct device dev;
+ possible_net_t _net;
+ char priv[0] __aligned(NETDEV_ALIGN);
+};
+
+struct devlink_port {
+ struct list_head list;
+ struct devlink *devlink;
+ unsigned index;
+ enum devlink_port_type type;
+ enum devlink_port_type desired_type;
+ void *type_dev;
+};
+
+struct devlink_ops {
+ size_t priv_size;
+ int (*port_type_set)(struct devlink_port *devlink_port,
+enum devlink_port_type port_type);
+};
+
+static inline void *devlink_priv(struct devlink *devlink)
+{
+ BUG_ON(!devlink);
+ return >priv;
+}
+
+static inline struct devlink *priv_to_devlink(void *priv)
+{
+ BUG_ON(!priv);
+ return container_of(priv, struct devlink, priv);
+}
+
+static inline struct device *devlink_dev(struct devlink *devlink)
+{
+ return >dev;
+}
+
+static inline void set_devlink_dev(struct devlink *devlink, struct device *dev)
+{
+ devlink->dev.parent = dev;
+}
+
+static inline const char *devlink_name(const struct devlink *devlink)
+{
+ return dev_name(>dev);
+}
+
+struct ib_device;
+
+#if IS_ENABLED(CONFIG_NET_DEVLINK)
+
+struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size);
+int devlink_register(struct devlink *devlink);
+void devlink_unregister(struct devlink *devlink);
+void devlink_free(struct devlink *devlink);
+void devlink_hwmsg_notify(struct devlink *devlink,
+ const char *buf, size_t buf_len,
+ enum devlink_hwmsg_type type,
+ enum devlink_hwmsg_dir dir,
+ gfp_t gfp_mask);
+int devlink_port_register(struct devlink *devlink,
+ struct devlink_port *devlink_port,
+ unsigned int port_index);
+void devlink_port_unregister(struct devlink_port *devlink_port);
+void devlink_port_type_eth_set(struct devlink_port *devlink_port,
+ struct net_device *netdev);
+void devlink_port_type_ib_set(struct devlink_port *devlink_port,
+ struct ib_device *ibdev);
+void devlink_port_type_clear(struct devlink_port *devlink_port);
+
+#else
+
+static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
+ size_t priv_size)
+{
+ return kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
+}
+
+static inline int devlink_register(struct devlink *devlink)
+{
+ return 0;
+}
+
+static inline void