|
@@ -389,8 +389,10 @@ struct mlx4_port {
|
|
|
struct mlx4_ib_dev *dev;
|
|
|
struct attribute_group pkey_group;
|
|
|
struct attribute_group gid_group;
|
|
|
- u8 port_num;
|
|
|
+ struct device_attribute enable_smi_admin;
|
|
|
+ struct device_attribute smi_enabled;
|
|
|
int slave;
|
|
|
+ u8 port_num;
|
|
|
};
|
|
|
|
|
|
|
|
@@ -558,6 +560,101 @@ err:
|
|
|
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);
|
|
|
+ ssize_t len = 0;
|
|
|
+
|
|
|
+ if (mlx4_vf_smi_enabled(p->dev->dev, p->slave, p->port_num))
|
|
|
+ len = sprintf(buf, "%d\n", 1);
|
|
|
+ else
|
|
|
+ len = sprintf(buf, "%d\n", 0);
|
|
|
+
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+ ssize_t len = 0;
|
|
|
+
|
|
|
+ if (mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave, p->port_num))
|
|
|
+ len = sprintf(buf, "%d\n", 1);
|
|
|
+ else
|
|
|
+ len = sprintf(buf, "%d\n", 0);
|
|
|
+
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
@@ -602,6 +699,10 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
|
|
|
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;
|
|
|
|
|
@@ -669,6 +770,7 @@ err_add:
|
|
|
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]);
|
|
@@ -713,6 +815,7 @@ static void unregister_pkey_tree(struct mlx4_ib_dev *device)
|
|
|
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]);
|
|
|
}
|