/*
 * Copyright (c) 2012 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 "core_priv.h"*/
#include "mlx4_ib.h"
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/stat.h>

#include <rdma/ib_mad.h>
/*show_admin_alias_guid returns the administratively assigned value of that GUID.
 * Values returned in buf parameter string:
 *	0			- requests opensm to assign a value.
 *	ffffffffffffffff	- delete this entry.
 *	other			- value assigned by administrator.
 */
static ssize_t show_admin_alias_guid(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
	struct mlx4_ib_dev *mdev = port->dev;
	__be64 sysadmin_ag_val;

	sysadmin_ag_val = mlx4_get_admin_guid(mdev->dev,
					      mlx4_ib_iov_dentry->entry_num,
					      port->num);

	return sysfs_emit(buf, "%llx\n", be64_to_cpu(sysadmin_ag_val));
}

/* store_admin_alias_guid stores the (new) administratively assigned value of that GUID.
 * Values in buf parameter string:
 *	0			- requests opensm to assign a value.
 *	0xffffffffffffffff	- delete this entry.
 *	other			- guid value assigned by the administrator.
 */
static ssize_t store_admin_alias_guid(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	int record_num;/*0-15*/
	int guid_index_in_rec; /*0 - 7*/
	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
	struct mlx4_ib_dev *mdev = port->dev;
	u64 sysadmin_ag_val;
	unsigned long flags;

	record_num = mlx4_ib_iov_dentry->entry_num / 8;
	guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8;
	if (0 == record_num && 0 == guid_index_in_rec) {
		pr_err("GUID 0 block 0 is RO\n");
		return count;
	}
	spin_lock_irqsave(&mdev->sriov.alias_guid.ag_work_lock, flags);
	sscanf(buf, "%llx", &sysadmin_ag_val);
	*(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1].
		all_rec_per_port[record_num].
		all_recs[GUID_REC_SIZE * guid_index_in_rec] =
			cpu_to_be64(sysadmin_ag_val);

	/* Change the state to be pending for update */
	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status
		= MLX4_GUID_INFO_STATUS_IDLE ;
	mlx4_set_admin_guid(mdev->dev, cpu_to_be64(sysadmin_ag_val),
			    mlx4_ib_iov_dentry->entry_num,
			    port->num);

	/* set the record index */
	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes
		|= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec);

	spin_unlock_irqrestore(&mdev->sriov.alias_guid.ag_work_lock, flags);
	mlx4_ib_init_alias_guid_work(mdev, port->num - 1);

	return count;
}

static ssize_t show_port_gid(struct device *dev,
			     struct device_attribute *attr,
			     char *buf)
{
	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
	struct mlx4_ib_dev *mdev = port->dev;
	union ib_gid gid;
	int ret;
	__be16 *raw;

	ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num,
				  mlx4_ib_iov_dentry->entry_num, &gid, 1);
	if (ret)
		return ret;

	raw = (__be16 *)gid.raw;
	return sysfs_emit(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
			  be16_to_cpu(raw[0]),
			  be16_to_cpu(raw[1]),
			  be16_to_cpu(raw[2]),
			  be16_to_cpu(raw[3]),
			  be16_to_cpu(raw[4]),
			  be16_to_cpu(raw[5]),
			  be16_to_cpu(raw[6]),
			  be16_to_cpu(raw[7]));
}

static ssize_t show_phys_port_pkey(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
	struct mlx4_ib_dev *mdev = port->dev;
	u16 pkey;
	ssize_t ret;

	ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num,
				   mlx4_ib_iov_dentry->entry_num, &pkey, 1);
	if (ret)
		return ret;

	return sysfs_emit(buf, "0x%04x\n", pkey);
}

#define DENTRY_REMOVE(_dentry)						\
do {									\
	sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr);	\
} while (0);

static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry,
			      char *_name, struct kobject *_kobj,
			      ssize_t (*show)(struct device *dev,
					      struct device_attribute *attr,
					      char *buf),
			      ssize_t (*store)(struct device *dev,
					       struct device_attribute *attr,
					       const char *buf, size_t count)
			      )
{
	int ret = 0;
	struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry;

	vdentry->ctx = _ctx;
	vdentry->dentry.show = show;
	vdentry->dentry.store = store;
	sysfs_attr_init(&vdentry->dentry.attr);
	vdentry->dentry.attr.name = vdentry->name;
	vdentry->dentry.attr.mode = 0;
	vdentry->kobj = _kobj;
	snprintf(vdentry->name, 15, "%s", _name);

	if (vdentry->dentry.store)
		vdentry->dentry.attr.mode |= S_IWUSR;

	if (vdentry->dentry.show)
		vdentry->dentry.attr.mode |= S_IRUGO;

	ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr);
	if (ret) {
		pr_err("failed to create %s\n", vdentry->dentry.attr.name);
		vdentry->ctx = NULL;
		return ret;
	}

	return ret;
}

int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
		struct attribute *attr)
{
	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
	int ret;

	ret = sysfs_create_file(port->mcgs_parent, attr);
	if (ret)
		pr_err("failed to create %s\n", attr->name);

	return ret;
}

void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
		struct attribute *attr)
{
	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];

	sysfs_remove_file(port->mcgs_parent, attr);
}

static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
{
	int i;
	char buff[11];
	struct mlx4_ib_iov_port *port = NULL;
	int ret = 0 ;
	struct ib_port_attr attr;

	memset(&attr, 0, sizeof(attr));
	/* get the physical gid and pkey table sizes.*/
	ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1);
	if (ret)
		goto err;

	port = &device->iov_ports[port_num - 1];
	port->dev = device;
	port->num = port_num;
	/* Directory structure:
	 * iov -
	 *   port num -
	 *	admin_guids
	 *	gids (operational)
	 *	mcg_table
	 */
	port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar),
				 GFP_KERNEL);
	if (!port->dentr_ar) {
		ret = -ENOMEM;
		goto err;
	}
	sprintf(buff, "%d", port_num);
	port->cur_port = kobject_create_and_add(buff,
				 kobject_get(device->ports_parent));
	if (!port->cur_port) {
		ret = -ENOMEM;
		goto kobj_create_err;
	}
	/* admin GUIDs */
	port->admin_alias_parent = kobject_create_and_add("admin_guids",
						  kobject_get(port->cur_port));
	if (!port->admin_alias_parent) {
		ret = -ENOMEM;
		goto err_admin_guids;
	}
	for (i = 0 ; i < attr.gid_tbl_len; i++) {
		sprintf(buff, "%d", i);
		port->dentr_ar->dentries[i].entry_num = i;
		ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i],
					  buff, port->admin_alias_parent,
					  show_admin_alias_guid, store_admin_alias_guid);
		if (ret)
			goto err_admin_alias_parent;
	}

	/* gids subdirectory (operational gids) */
	port->gids_parent = kobject_create_and_add("gids",
						  kobject_get(port->cur_port));
	if (!port->gids_parent) {
		ret = -ENOMEM;
		goto err_gids;
	}

	for (i = 0 ; i < attr.gid_tbl_len; i++) {
		sprintf(buff, "%d", i);
		port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i;
		ret = create_sysfs_entry(port,
					 &port->dentr_ar->dentries[attr.gid_tbl_len + i],
					 buff,
					 port->gids_parent, show_port_gid, NULL);
		if (ret)
			goto err_gids_parent;
	}

	/* physical port pkey table */
	port->pkeys_parent =
		kobject_create_and_add("pkeys", kobject_get(port->cur_port));
	if (!port->pkeys_parent) {
		ret = -ENOMEM;
		goto err_pkeys;
	}

	for (i = 0 ; i < attr.pkey_tbl_len; i++) {
		sprintf(buff, "%d", i);
		port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i;
		ret = create_sysfs_entry(port,
					 &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i],
					 buff, port->pkeys_parent,
					 show_phys_port_pkey, NULL);
		if (ret)
			goto err_pkeys_parent;
	}

	/* MCGs table */
	port->mcgs_parent =
		kobject_create_and_add("mcgs", kobject_get(port->cur_port));
	if (!port->mcgs_parent) {
		ret = -ENOMEM;
		goto err_mcgs;
	}
	return 0;

err_mcgs:
	kobject_put(port->cur_port);

err_pkeys_parent:
	kobject_put(port->pkeys_parent);

err_pkeys:
	kobject_put(port->cur_port);

err_gids_parent:
	kobject_put(port->gids_parent);

err_gids:
	kobject_put(port->cur_port);

err_admin_alias_parent:
	kobject_put(port->admin_alias_parent);

err_admin_guids:
	kobject_put(port->cur_port);
	kobject_put(port->cur_port); /* once more for create_and_add buff */

kobj_create_err:
	kobject_put(device->ports_parent);
	kfree(port->dentr_ar);

err:
	pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
	       port_num, ret);
	return ret;
}

static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max)
{
	/* pci_name format is: bus:dev:func -> xxxx:yy:zz.n
	 * with no ARI only 3 last bits are used so when the fn is higher than 8
	 * need to add it to the dev num, so count in the last number will be
	 * modulo 8 */
	snprintf(name, max, "%.8s%.2d.%d", pci_name(dev->dev->persist->pdev),
		 i / 8, i % 8);
}

struct mlx4_port {
	struct kobject         kobj;
	struct mlx4_ib_dev    *dev;
	struct attribute_group pkey_group;
	struct attribute_group gid_group;
	struct device_attribute	enable_smi_admin;
	struct device_attribute	smi_enabled;
	int		       slave;
	u8                     port_num;
};


static void mlx4_port_release(struct kobject *kobj)
{
	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
	struct attribute *a;
	int i;

	for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
		kfree(a);
	kfree(p->pkey_group.attrs);
	for (i = 0; (a = p->gid_group.attrs[i]); ++i)
		kfree(a);
	kfree(p->gid_group.attrs);
	kfree(p);
}

struct port_attribute {
	struct attribute attr;
	ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf);
	ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
			 const char *buf, size_t count);
};

static ssize_t port_attr_show(struct kobject *kobj,
			      struct attribute *attr, char *buf)
{
	struct port_attribute *port_attr =
		container_of(attr, struct port_attribute, attr);
	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);

	if (!port_attr->show)
		return -EIO;
	return port_attr->show(p, port_attr, buf);
}

static ssize_t port_attr_store(struct kobject *kobj,
			       struct attribute *attr,
			       const char *buf, size_t size)
{
	struct port_attribute *port_attr =
		container_of(attr, struct port_attribute, attr);
	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);

	if (!port_attr->store)
		return -EIO;
	return port_attr->store(p, port_attr, buf, size);
}

static const struct sysfs_ops port_sysfs_ops = {
	.show = port_attr_show,
	.store = port_attr_store,
};

static struct kobj_type port_type = {
	.release    = mlx4_port_release,
	.sysfs_ops  = &port_sysfs_ops,
};

struct port_table_attribute {
	struct port_attribute	attr;
	char			name[8];
	int			index;
};

static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
			      char *buf)
{
	struct port_table_attribute *tab_attr =
		container_of(attr, struct port_table_attribute, attr);
	struct pkey_mgt *m = &p->dev->pkeys;
	u8 key = m->virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index];

	if (key >= p->dev->dev->caps.pkey_table_len[p->port_num])
		return sysfs_emit(buf, "none\n");
	return sysfs_emit(buf, "%d\n", key);
}

static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
			       const char *buf, size_t count)
{
	struct port_table_attribute *tab_attr =
		container_of(attr, struct port_table_attribute, attr);
	int idx;
	int err;

	/* do not allow remapping Dom0 virtual pkey table */
	if (p->slave == mlx4_master_func_num(p->dev->dev))
		return -EINVAL;

	if (!strncasecmp(buf, "no", 2))
		idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1;
	else if (sscanf(buf, "%i", &idx) != 1 ||
		 idx >= p->dev->dev->caps.pkey_table_len[p->port_num] ||
		 idx < 0)
		return -EINVAL;

	p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1]
				    [tab_attr->index] = idx;
	mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num,
			     tab_attr->index, idx);
	err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num);
	if (err) {
		pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
		       " port %d, index %d\n", p->slave, p->port_num, idx);
		return err;
	}
	return count;
}

static ssize_t show_port_gid_idx(struct mlx4_port *p,
				 struct port_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "%d\n", p->slave);
}

static struct attribute **
alloc_group_attrs(ssize_t (*show)(struct mlx4_port *,
				  struct port_attribute *, char *buf),
		  ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
				   const char *buf, size_t count),
		  int len)
{
	struct attribute **tab_attr;
	struct port_table_attribute *element;
	int i;

	tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL);
	if (!tab_attr)
		return NULL;

	for (i = 0; i < len; i++) {
		element = kzalloc(sizeof (struct port_table_attribute),
				  GFP_KERNEL);
		if (!element)
			goto err;
		if (snprintf(element->name, sizeof (element->name),
			     "%d", i) >= sizeof (element->name)) {
			kfree(element);
			goto err;
		}
		sysfs_attr_init(&element->attr.attr);
		element->attr.attr.name  = element->name;
		if (store) {
			element->attr.attr.mode  = S_IWUSR | S_IRUGO;
			element->attr.store	 = store;
		} else
			element->attr.attr.mode  = S_IRUGO;

		element->attr.show       = show;
		element->index		 = i;
		tab_attr[i] = &element->attr.attr;
	}
	return tab_attr;

err:
	while (--i >= 0)
		kfree(tab_attr[i]);
	kfree(tab_attr);
	return NULL;
}

static ssize_t sysfs_show_smi_enabled(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct mlx4_port *p =
		container_of(attr, struct mlx4_port, smi_enabled);

	return sysfs_emit(buf, "%d\n",
			  !!mlx4_vf_smi_enabled(p->dev->dev, p->slave,
						p->port_num));
}

static ssize_t sysfs_show_enable_smi_admin(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct mlx4_port *p =
		container_of(attr, struct mlx4_port, enable_smi_admin);

	return sysfs_emit(buf, "%d\n",
			  !!mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave,
							 p->port_num));
}

static ssize_t sysfs_store_enable_smi_admin(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct mlx4_port *p =
		container_of(attr, struct mlx4_port, enable_smi_admin);
	int enable;

	if (sscanf(buf, "%i", &enable) != 1 ||
	    enable < 0 || enable > 1)
		return -EINVAL;

	if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable))
		return -EINVAL;
	return count;
}

static int add_vf_smi_entries(struct mlx4_port *p)
{
	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
			IB_LINK_LAYER_ETHERNET;
	int ret;

	/* do not display entries if eth transport, or if master */
	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
		return 0;

	sysfs_attr_init(&p->smi_enabled.attr);
	p->smi_enabled.show = sysfs_show_smi_enabled;
	p->smi_enabled.store = NULL;
	p->smi_enabled.attr.name = "smi_enabled";
	p->smi_enabled.attr.mode = 0444;
	ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr);
	if (ret) {
		pr_err("failed to create smi_enabled\n");
		return ret;
	}

	sysfs_attr_init(&p->enable_smi_admin.attr);
	p->enable_smi_admin.show = sysfs_show_enable_smi_admin;
	p->enable_smi_admin.store = sysfs_store_enable_smi_admin;
	p->enable_smi_admin.attr.name = "enable_smi_admin";
	p->enable_smi_admin.attr.mode = 0644;
	ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr);
	if (ret) {
		pr_err("failed to create enable_smi_admin\n");
		sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
		return ret;
	}
	return 0;
}

static void remove_vf_smi_entries(struct mlx4_port *p)
{
	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
			IB_LINK_LAYER_ETHERNET;

	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
		return;

	sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
	sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr);
}

static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
{
	struct mlx4_port *p;
	int i;
	int ret;
	int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) ==
			IB_LINK_LAYER_ETHERNET;

	p = kzalloc(sizeof *p, GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	p->dev = dev;
	p->port_num = port_num;
	p->slave = slave;

	ret = kobject_init_and_add(&p->kobj, &port_type,
				   kobject_get(dev->dev_ports_parent[slave]),
				   "%d", port_num);
	if (ret)
		goto err_alloc;

	p->pkey_group.name  = "pkey_idx";
	p->pkey_group.attrs =
		alloc_group_attrs(show_port_pkey,
				  is_eth ? NULL : store_port_pkey,
				  dev->dev->caps.pkey_table_len[port_num]);
	if (!p->pkey_group.attrs) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
	if (ret)
		goto err_free_pkey;

	p->gid_group.name  = "gid_idx";
	p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
	if (!p->gid_group.attrs) {
		ret = -ENOMEM;
		goto err_free_pkey;
	}

	ret = sysfs_create_group(&p->kobj, &p->gid_group);
	if (ret)
		goto err_free_gid;

	ret = add_vf_smi_entries(p);
	if (ret)
		goto err_free_gid;

	list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
	return 0;

err_free_gid:
	kfree(p->gid_group.attrs[0]);
	kfree(p->gid_group.attrs);

err_free_pkey:
	for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
		kfree(p->pkey_group.attrs[i]);
	kfree(p->pkey_group.attrs);

err_alloc:
	kobject_put(dev->dev_ports_parent[slave]);
	kfree(p);
	return ret;
}

static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
{
	char name[32];
	int err;
	int port;
	struct kobject *p, *t;
	struct mlx4_port *mport;
	struct mlx4_active_ports actv_ports;

	get_name(dev, name, slave, sizeof name);

	dev->pkeys.device_parent[slave] =
		kobject_create_and_add(name, kobject_get(dev->iov_parent));

	if (!dev->pkeys.device_parent[slave]) {
		err = -ENOMEM;
		goto fail_dev;
	}

	INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]);

	dev->dev_ports_parent[slave] =
		kobject_create_and_add("ports",
				       kobject_get(dev->pkeys.device_parent[slave]));

	if (!dev->dev_ports_parent[slave]) {
		err = -ENOMEM;
		goto err_ports;
	}

	actv_ports = mlx4_get_active_ports(dev->dev, slave);

	for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
		if (!test_bit(port - 1, actv_ports.ports))
			continue;
		err = add_port(dev, port, slave);
		if (err)
			goto err_add;
	}
	return 0;

err_add:
	list_for_each_entry_safe(p, t,
				 &dev->pkeys.pkey_port_list[slave],
				 entry) {
		list_del(&p->entry);
		mport = container_of(p, struct mlx4_port, kobj);
		sysfs_remove_group(p, &mport->pkey_group);
		sysfs_remove_group(p, &mport->gid_group);
		remove_vf_smi_entries(mport);
		kobject_put(p);
	}
	kobject_put(dev->dev_ports_parent[slave]);

err_ports:
	kobject_put(dev->pkeys.device_parent[slave]);
	/* extra put for the device_parent create_and_add */
	kobject_put(dev->pkeys.device_parent[slave]);

fail_dev:
	kobject_put(dev->iov_parent);
	return err;
}

static int register_pkey_tree(struct mlx4_ib_dev *device)
{
	int i;

	if (!mlx4_is_master(device->dev))
		return 0;

	for (i = 0; i <= device->dev->persist->num_vfs; ++i)
		register_one_pkey_tree(device, i);

	return 0;
}

static void unregister_pkey_tree(struct mlx4_ib_dev *device)
{
	int slave;
	struct kobject *p, *t;
	struct mlx4_port *port;

	if (!mlx4_is_master(device->dev))
		return;

	for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
		list_for_each_entry_safe(p, t,
					 &device->pkeys.pkey_port_list[slave],
					 entry) {
			list_del(&p->entry);
			port = container_of(p, struct mlx4_port, kobj);
			sysfs_remove_group(p, &port->pkey_group);
			sysfs_remove_group(p, &port->gid_group);
			remove_vf_smi_entries(port);
			kobject_put(p);
			kobject_put(device->dev_ports_parent[slave]);
		}
		kobject_put(device->dev_ports_parent[slave]);
		kobject_put(device->pkeys.device_parent[slave]);
		kobject_put(device->pkeys.device_parent[slave]);
		kobject_put(device->iov_parent);
	}
}

int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *dev)
{
	unsigned int i;
	int ret = 0;

	if (!mlx4_is_master(dev->dev))
		return 0;

	dev->iov_parent = kobject_create_and_add("iov", &dev->ib_dev.dev.kobj);
	if (!dev->iov_parent) {
		ret = -ENOMEM;
		goto err;
	}
	dev->ports_parent =
		kobject_create_and_add("ports",
				       kobject_get(dev->iov_parent));
	if (!dev->ports_parent) {
		ret = -ENOMEM;
		goto err_ports;
	}

	rdma_for_each_port(&dev->ib_dev, i) {
		ret = add_port_entries(dev, i);
		if (ret)
			goto err_add_entries;
	}

	ret = register_pkey_tree(dev);
	if (ret)
		goto err_add_entries;
	return 0;

err_add_entries:
	kobject_put(dev->ports_parent);

err_ports:
	kobject_put(dev->iov_parent);
err:
	pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret);
	return ret;
}

static void unregister_alias_guid_tree(struct mlx4_ib_dev *device)
{
	struct mlx4_ib_iov_port *p;
	int i;

	if (!mlx4_is_master(device->dev))
		return;

	for (i = 0; i < device->dev->caps.num_ports; i++) {
		p = &device->iov_ports[i];
		kobject_put(p->admin_alias_parent);
		kobject_put(p->gids_parent);
		kobject_put(p->pkeys_parent);
		kobject_put(p->mcgs_parent);
		kobject_put(p->cur_port);
		kobject_put(p->cur_port);
		kobject_put(p->cur_port);
		kobject_put(p->cur_port);
		kobject_put(p->cur_port);
		kobject_put(p->dev->ports_parent);
		kfree(p->dentr_ar);
	}
}

void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device)
{
	unregister_alias_guid_tree(device);
	unregister_pkey_tree(device);
	kobject_put(device->ports_parent);
	kobject_put(device->iov_parent);
	kobject_put(device->iov_parent);
}
