[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1420730220-20224-2-git-send-email-hadarh@mellanox.com>
Date: Thu, 8 Jan 2015 17:16:58 +0200
From: Hadar Hen Zion <hadarh@...lanox.com>
To: "David S. Miller" <davem@...emloft.net>, gregkh@...uxfoundation.org
Cc: netdev@...r.kernel.org, Amir Vadai <amirv@...lanox.com>,
Hadar Har-Zion <hadarh@...lanox.com>,
Yevgeny Petrilin <yevgenyp@...lanox.com>,
Or Gerlitz <ogerlitz@...lanox.com>, shannon.nelson@...el.com,
Doug Ledford <dledford@...hat.com>, greearb@...delatech.com
Subject: [RFC net-next 1/3] net/dev_c_mlx4: Support mlx4_core pre-load configuration
Adding a configuration Module to mlx4_core to support setting of
pre-load parameters through configfs.
When dev_c_mlx4 module is loaded, it stores and validates the parameters
sub-tree for mlx4_core driver under 'devices/mlx4_core' directory in configfs.
The parameters sub-tree is a set of directories and files representing
mlx4_core variables that should be set before mlx4_core is loaded.
mlx4_core sub-tree includes directories per device, identified by a
'BDF' name, and under each directory/device its relevant parameters.
Example of optional mlx4_core hierarchy under configfs:
$ cd /sys/kernel/config/
$ tree devices/
devices/
└── mlx4_core
└── pdevs
├── 0000:00:04.0
│ ├── dmfs
│ └── ports
│ ├── 1
│ │ └── type
│ └── 2
│ └── type
└── 0000:00:08.0
├── dmfs
└── ports
├── 1
│ └── type
└── 2
└── type
systemd service executed by the OS will set a value to those files
according to the user configuration file (/etc/devconf.d/mlx4_core.conf)
before mlx4_core is loaded.
When mlx4_core is loaded, it asks devconf for 'dmfs' and 'type' values,
devconf retrieves the values stored in dev_c_mlx4 and passes them on to
mlx4_core.
Signed-off-by: Hadar Hen Zion <hadarh@...lanox.com>
Signed-off-by: Amir Vadai <amirv@...lanox.com>
---
drivers/net/ethernet/mellanox/mlx4/Kconfig | 5 +
drivers/net/ethernet/mellanox/mlx4/Makefile | 4 +
drivers/net/ethernet/mellanox/mlx4/mlx4_conf.c | 323 ++++++++++++++++++++++++
3 files changed, 332 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx4/mlx4_conf.c
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
index 1486ce9..fa135d3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig
@@ -44,3 +44,8 @@ config MLX4_DEBUG
mlx4_core driver. The output can be turned on via the
debug_level module parameter (which can also be set after
the driver is loaded through sysfs).
+
+config MLX4_DEV_C
+ tristate "mlx4 driver pre-loading configuration module"
+ depends on DEVCONF
+ default m
diff --git a/drivers/net/ethernet/mellanox/mlx4/Makefile b/drivers/net/ethernet/mellanox/mlx4/Makefile
index 3e9c70f..33a1dc8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx4/Makefile
@@ -8,3 +8,7 @@ obj-$(CONFIG_MLX4_EN) += mlx4_en.o
mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
en_resources.o en_netdev.o en_selftest.o en_clock.o
mlx4_en-$(CONFIG_MLX4_EN_DCB) += en_dcb_nl.o
+
+obj-$(CONFIG_MLX4_DEV_C) += dev_c_mlx4.o
+
+dev_c_mlx4-y := mlx4_conf.o
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_conf.c b/drivers/net/ethernet/mellanox/mlx4/mlx4_conf.c
new file mode 100644
index 0000000..c82924b
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_conf.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+#include <linux/devconf.h>
+#include <linux/mlx4/device.h>
+
+struct mlx4_port {
+ struct devconf_config_object cobj;
+ int type;
+};
+
+struct mlx4_bdf_config {
+ struct devconf_config_object cobj;
+ int dmfs;
+};
+
+static inline struct mlx4_bdf_config *to_bdf_config(struct config_item *item)
+{
+ struct devconf_config_object *cobj = to_config_obj(item);
+
+ return cobj ? container_of(cobj, struct mlx4_bdf_config, cobj) : NULL;
+}
+
+static inline struct mlx4_port *to_simple_port(struct config_item *item)
+{
+ struct devconf_config_object *cobj = to_config_obj(item);
+
+ return cobj ? container_of(cobj, struct mlx4_port, cobj) : NULL;
+}
+
+static inline struct mlx4_bdf_config
+*cobj_to_bdf_config(struct devconf_config_object *cobj)
+{
+ return cobj ? container_of(cobj, struct mlx4_bdf_config, cobj) : NULL;
+}
+
+static inline struct mlx4_port
+*cobj_to_port(struct devconf_config_object *cobj)
+{
+ return cobj ? container_of(cobj, struct mlx4_port, cobj) : NULL;
+}
+
+static struct configfs_attribute simple_port_attr_type = {
+ .ca_owner = THIS_MODULE,
+ .ca_name = "type",
+ .ca_mode = S_IRUGO | S_IWUSR,
+};
+
+static struct configfs_attribute *simple_port_attrs[] = {
+ &simple_port_attr_type,
+ NULL,
+};
+
+static ssize_t config_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ struct mlx4_bdf_config *bdf_config;
+ struct mlx4_port *simple_port;
+ ssize_t count = -ENOENT;
+
+ if (strcmp(attr->ca_name, "dmfs")) {
+ bdf_config = to_bdf_config(item);
+ count = sprintf(page, "%d\n", bdf_config->dmfs);
+ } else if (strcmp(attr->ca_name, "type")) {
+ simple_port = to_simple_port(item);
+ count = sprintf(page, "%d\n", simple_port->type);
+ }
+ return count;
+}
+
+static ssize_t config_attr_store(struct config_item *item,
+ struct configfs_attribute *attr,
+ const char *page, size_t count)
+{
+ struct mlx4_bdf_config *bdf_config;
+ struct mlx4_port *simple_port;
+ int err;
+ unsigned long res;
+
+ err = kstrtoul(page, 10, &res);
+ if (err)
+ return err;
+ if (strcmp(attr->ca_name, "dmfs")) {
+ bdf_config = to_bdf_config(item);
+ bdf_config->dmfs = res;
+ } else if (strcmp(attr->ca_name, "type")) {
+ simple_port = to_simple_port(item);
+ simple_port->type = res;
+ }
+
+ return count;
+}
+
+static void simple_port_release(struct config_item *item)
+{
+ kfree(to_simple_port(item));
+}
+
+static struct configfs_item_operations simple_port_item_ops = {
+ .release = simple_port_release,
+ .show_attribute = config_attr_show,
+ .store_attribute = config_attr_store,
+};
+
+static struct config_item_type simple_port_config_type = {
+ .ct_item_ops = &simple_port_item_ops,
+ .ct_attrs = simple_port_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_item *simple_port_make_item(struct config_group *group,
+ const char *name)
+{
+ struct mlx4_port *simple_port;
+
+ simple_port = kzalloc(sizeof(*simple_port), GFP_KERNEL);
+ if (!simple_port)
+ return ERR_PTR(-ENOMEM);
+
+ config_item_init_type_name(&simple_port->cobj.group.cg_item, name,
+ &simple_port_config_type);
+
+ simple_port->type = 0;
+
+ return &simple_port->cobj.group.cg_item;
+}
+
+static struct configfs_group_operations ports_group_ops = {
+ .make_item = simple_port_make_item,
+};
+
+static void cobj_release(struct config_item *item)
+{
+ kfree(to_config_obj(item));
+}
+
+static struct configfs_item_operations ports_item_ops = {
+ .release = cobj_release,
+};
+
+static struct config_item_type ports_config_type = {
+ .ct_item_ops = &ports_item_ops,
+ .ct_group_ops = &ports_group_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_group *bdf_make_group(struct config_group *group,
+ const char *name)
+{
+ struct devconf_config_object *ports_config;
+
+ ports_config = kzalloc(sizeof(*ports_config), GFP_KERNEL);
+ if (!ports_config)
+ return ERR_PTR(-ENOMEM);
+
+ config_group_init_type_name(&ports_config->group, name,
+ &ports_config_type);
+
+ return &ports_config->group;
+}
+
+static struct configfs_group_operations bdf_group_ops = {
+ .make_group = bdf_make_group,
+};
+
+static void bdf_config_release(struct config_item *item)
+{
+ kfree(to_bdf_config(item));
+}
+
+static struct configfs_item_operations bdf_item_ops = {
+ .release = bdf_config_release,
+ .show_attribute = config_attr_show,
+ .store_attribute = config_attr_store,
+};
+
+static struct configfs_attribute config_attr_dmfs = {
+ .ca_owner = THIS_MODULE,
+ .ca_name = "dmfs",
+ .ca_mode = S_IRUGO | S_IWUSR,
+};
+
+static struct configfs_attribute *bdf_config_attrs[] = {
+ &config_attr_dmfs,
+ NULL,
+};
+
+static struct config_item_type bdf_config_type = {
+ .ct_item_ops = &bdf_item_ops,
+ .ct_group_ops = &bdf_group_ops,
+ .ct_attrs = bdf_config_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_group *pdevs_make_group(struct config_group *group,
+ const char *name)
+{
+ struct mlx4_bdf_config *bdf_config;
+
+ bdf_config = kzalloc(sizeof(*bdf_config), GFP_KERNEL);
+ if (!bdf_config)
+ return ERR_PTR(-ENOMEM);
+
+ config_group_init_type_name(&bdf_config->cobj.group, name,
+ &bdf_config_type);
+
+ return &bdf_config->cobj.group;
+}
+
+static struct configfs_group_operations pdevs_group_ops = {
+ .make_group = pdevs_make_group,
+};
+
+static struct configfs_item_operations pdevs_item_ops = {
+ .release = cobj_release,
+};
+
+static struct config_item_type pdevs_config_type = {
+ .ct_item_ops = &pdevs_item_ops,
+ .ct_group_ops = &pdevs_group_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_group *mlx4_make_group(struct config_group *group,
+ const char *name)
+{
+ struct devconf_config_object *pdevs_cobj;
+
+ pdevs_cobj = kzalloc(sizeof(*pdevs_cobj), GFP_KERNEL);
+ if (!pdevs_cobj)
+ return ERR_PTR(-ENOMEM);
+
+ config_group_init_type_name(&pdevs_cobj->group, name,
+ &pdevs_config_type);
+
+ return &pdevs_cobj->group;
+}
+
+static struct configfs_group_operations mlx4_group_ops = {
+ .make_group = mlx4_make_group,
+};
+
+static void mlx4_release(struct config_item *item)
+{
+ struct devconf_config_driver *cdrv = to_config_driver(item);
+
+ devconf_put_config_driver(cdrv);
+}
+
+static struct configfs_item_operations mlx4_item_ops = {
+ .release = mlx4_release,
+};
+
+static struct config_item_type mlx4_config_type = {
+ .ct_item_ops = &mlx4_item_ops,
+ .ct_group_ops = &mlx4_group_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+static int mlx4_get_int_attr(struct devconf_config_object *cobj,
+ const char *attr_name, int *val)
+{
+ struct mlx4_port *simple_port;
+ struct mlx4_bdf_config *bdf_config;
+
+ if (strcmp(attr_name, "dmfs")) {
+ bdf_config = cobj_to_bdf_config(cobj);
+ *val = bdf_config->dmfs;
+ } else if (strcmp(attr_name, "type")) {
+ simple_port = cobj_to_port(cobj);
+ *val = simple_port->type;
+ } else {
+ return -ENOENT;
+ }
+ return 0;
+}
+
+static void mlx4_set_config_object(struct devconf_config_driver *cdrv,
+ const char *name)
+{
+ config_group_init_type_name(&cdrv->cobj.group, name, &mlx4_config_type);
+}
+
+DECLARE_DEVCONF_DRIVER_INIT(mlx4_core,
+ mlx4_set_config_object,
+ mlx4_get_int_attr);
+
+MODULE_LICENSE("GPL");
--
1.7.8.2
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists