0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "mlx4_ib.h"
0035 #include <linux/slab.h>
0036 #include <linux/string.h>
0037 #include <linux/stat.h>
0038
0039 #include <rdma/ib_mad.h>
0040
0041
0042
0043
0044
0045
0046 static ssize_t show_admin_alias_guid(struct device *dev,
0047 struct device_attribute *attr, char *buf)
0048 {
0049 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
0050 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
0051 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
0052 struct mlx4_ib_dev *mdev = port->dev;
0053 __be64 sysadmin_ag_val;
0054
0055 sysadmin_ag_val = mlx4_get_admin_guid(mdev->dev,
0056 mlx4_ib_iov_dentry->entry_num,
0057 port->num);
0058
0059 return sysfs_emit(buf, "%llx\n", be64_to_cpu(sysadmin_ag_val));
0060 }
0061
0062
0063
0064
0065
0066
0067
0068 static ssize_t store_admin_alias_guid(struct device *dev,
0069 struct device_attribute *attr,
0070 const char *buf, size_t count)
0071 {
0072 int record_num;
0073 int guid_index_in_rec;
0074 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
0075 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
0076 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
0077 struct mlx4_ib_dev *mdev = port->dev;
0078 u64 sysadmin_ag_val;
0079 unsigned long flags;
0080
0081 record_num = mlx4_ib_iov_dentry->entry_num / 8;
0082 guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8;
0083 if (0 == record_num && 0 == guid_index_in_rec) {
0084 pr_err("GUID 0 block 0 is RO\n");
0085 return count;
0086 }
0087 spin_lock_irqsave(&mdev->sriov.alias_guid.ag_work_lock, flags);
0088 sscanf(buf, "%llx", &sysadmin_ag_val);
0089 *(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1].
0090 all_rec_per_port[record_num].
0091 all_recs[GUID_REC_SIZE * guid_index_in_rec] =
0092 cpu_to_be64(sysadmin_ag_val);
0093
0094
0095 mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status
0096 = MLX4_GUID_INFO_STATUS_IDLE ;
0097 mlx4_set_admin_guid(mdev->dev, cpu_to_be64(sysadmin_ag_val),
0098 mlx4_ib_iov_dentry->entry_num,
0099 port->num);
0100
0101
0102 mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes
0103 |= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec);
0104
0105 spin_unlock_irqrestore(&mdev->sriov.alias_guid.ag_work_lock, flags);
0106 mlx4_ib_init_alias_guid_work(mdev, port->num - 1);
0107
0108 return count;
0109 }
0110
0111 static ssize_t show_port_gid(struct device *dev,
0112 struct device_attribute *attr,
0113 char *buf)
0114 {
0115 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
0116 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
0117 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
0118 struct mlx4_ib_dev *mdev = port->dev;
0119 union ib_gid gid;
0120 int ret;
0121 __be16 *raw;
0122
0123 ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num,
0124 mlx4_ib_iov_dentry->entry_num, &gid, 1);
0125 if (ret)
0126 return ret;
0127
0128 raw = (__be16 *)gid.raw;
0129 return sysfs_emit(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
0130 be16_to_cpu(raw[0]),
0131 be16_to_cpu(raw[1]),
0132 be16_to_cpu(raw[2]),
0133 be16_to_cpu(raw[3]),
0134 be16_to_cpu(raw[4]),
0135 be16_to_cpu(raw[5]),
0136 be16_to_cpu(raw[6]),
0137 be16_to_cpu(raw[7]));
0138 }
0139
0140 static ssize_t show_phys_port_pkey(struct device *dev,
0141 struct device_attribute *attr,
0142 char *buf)
0143 {
0144 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
0145 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
0146 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
0147 struct mlx4_ib_dev *mdev = port->dev;
0148 u16 pkey;
0149 ssize_t ret;
0150
0151 ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num,
0152 mlx4_ib_iov_dentry->entry_num, &pkey, 1);
0153 if (ret)
0154 return ret;
0155
0156 return sysfs_emit(buf, "0x%04x\n", pkey);
0157 }
0158
0159 #define DENTRY_REMOVE(_dentry) \
0160 do { \
0161 sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr); \
0162 } while (0);
0163
0164 static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry,
0165 char *_name, struct kobject *_kobj,
0166 ssize_t (*show)(struct device *dev,
0167 struct device_attribute *attr,
0168 char *buf),
0169 ssize_t (*store)(struct device *dev,
0170 struct device_attribute *attr,
0171 const char *buf, size_t count)
0172 )
0173 {
0174 int ret = 0;
0175 struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry;
0176
0177 vdentry->ctx = _ctx;
0178 vdentry->dentry.show = show;
0179 vdentry->dentry.store = store;
0180 sysfs_attr_init(&vdentry->dentry.attr);
0181 vdentry->dentry.attr.name = vdentry->name;
0182 vdentry->dentry.attr.mode = 0;
0183 vdentry->kobj = _kobj;
0184 snprintf(vdentry->name, 15, "%s", _name);
0185
0186 if (vdentry->dentry.store)
0187 vdentry->dentry.attr.mode |= S_IWUSR;
0188
0189 if (vdentry->dentry.show)
0190 vdentry->dentry.attr.mode |= S_IRUGO;
0191
0192 ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr);
0193 if (ret) {
0194 pr_err("failed to create %s\n", vdentry->dentry.attr.name);
0195 vdentry->ctx = NULL;
0196 return ret;
0197 }
0198
0199 return ret;
0200 }
0201
0202 int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
0203 struct attribute *attr)
0204 {
0205 struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
0206 int ret;
0207
0208 ret = sysfs_create_file(port->mcgs_parent, attr);
0209 if (ret)
0210 pr_err("failed to create %s\n", attr->name);
0211
0212 return ret;
0213 }
0214
0215 void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
0216 struct attribute *attr)
0217 {
0218 struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
0219
0220 sysfs_remove_file(port->mcgs_parent, attr);
0221 }
0222
0223 static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
0224 {
0225 int i;
0226 char buff[11];
0227 struct mlx4_ib_iov_port *port = NULL;
0228 int ret = 0 ;
0229 struct ib_port_attr attr;
0230
0231 memset(&attr, 0, sizeof(attr));
0232
0233 ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1);
0234 if (ret)
0235 goto err;
0236
0237 port = &device->iov_ports[port_num - 1];
0238 port->dev = device;
0239 port->num = port_num;
0240
0241
0242
0243
0244
0245
0246
0247 port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar),
0248 GFP_KERNEL);
0249 if (!port->dentr_ar) {
0250 ret = -ENOMEM;
0251 goto err;
0252 }
0253 sprintf(buff, "%d", port_num);
0254 port->cur_port = kobject_create_and_add(buff,
0255 kobject_get(device->ports_parent));
0256 if (!port->cur_port) {
0257 ret = -ENOMEM;
0258 goto kobj_create_err;
0259 }
0260
0261 port->admin_alias_parent = kobject_create_and_add("admin_guids",
0262 kobject_get(port->cur_port));
0263 if (!port->admin_alias_parent) {
0264 ret = -ENOMEM;
0265 goto err_admin_guids;
0266 }
0267 for (i = 0 ; i < attr.gid_tbl_len; i++) {
0268 sprintf(buff, "%d", i);
0269 port->dentr_ar->dentries[i].entry_num = i;
0270 ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i],
0271 buff, port->admin_alias_parent,
0272 show_admin_alias_guid, store_admin_alias_guid);
0273 if (ret)
0274 goto err_admin_alias_parent;
0275 }
0276
0277
0278 port->gids_parent = kobject_create_and_add("gids",
0279 kobject_get(port->cur_port));
0280 if (!port->gids_parent) {
0281 ret = -ENOMEM;
0282 goto err_gids;
0283 }
0284
0285 for (i = 0 ; i < attr.gid_tbl_len; i++) {
0286 sprintf(buff, "%d", i);
0287 port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i;
0288 ret = create_sysfs_entry(port,
0289 &port->dentr_ar->dentries[attr.gid_tbl_len + i],
0290 buff,
0291 port->gids_parent, show_port_gid, NULL);
0292 if (ret)
0293 goto err_gids_parent;
0294 }
0295
0296
0297 port->pkeys_parent =
0298 kobject_create_and_add("pkeys", kobject_get(port->cur_port));
0299 if (!port->pkeys_parent) {
0300 ret = -ENOMEM;
0301 goto err_pkeys;
0302 }
0303
0304 for (i = 0 ; i < attr.pkey_tbl_len; i++) {
0305 sprintf(buff, "%d", i);
0306 port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i;
0307 ret = create_sysfs_entry(port,
0308 &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i],
0309 buff, port->pkeys_parent,
0310 show_phys_port_pkey, NULL);
0311 if (ret)
0312 goto err_pkeys_parent;
0313 }
0314
0315
0316 port->mcgs_parent =
0317 kobject_create_and_add("mcgs", kobject_get(port->cur_port));
0318 if (!port->mcgs_parent) {
0319 ret = -ENOMEM;
0320 goto err_mcgs;
0321 }
0322 return 0;
0323
0324 err_mcgs:
0325 kobject_put(port->cur_port);
0326
0327 err_pkeys_parent:
0328 kobject_put(port->pkeys_parent);
0329
0330 err_pkeys:
0331 kobject_put(port->cur_port);
0332
0333 err_gids_parent:
0334 kobject_put(port->gids_parent);
0335
0336 err_gids:
0337 kobject_put(port->cur_port);
0338
0339 err_admin_alias_parent:
0340 kobject_put(port->admin_alias_parent);
0341
0342 err_admin_guids:
0343 kobject_put(port->cur_port);
0344 kobject_put(port->cur_port);
0345
0346 kobj_create_err:
0347 kobject_put(device->ports_parent);
0348 kfree(port->dentr_ar);
0349
0350 err:
0351 pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
0352 port_num, ret);
0353 return ret;
0354 }
0355
0356 static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max)
0357 {
0358
0359
0360
0361
0362 snprintf(name, max, "%.8s%.2d.%d", pci_name(dev->dev->persist->pdev),
0363 i / 8, i % 8);
0364 }
0365
0366 struct mlx4_port {
0367 struct kobject kobj;
0368 struct mlx4_ib_dev *dev;
0369 struct attribute_group pkey_group;
0370 struct attribute_group gid_group;
0371 struct device_attribute enable_smi_admin;
0372 struct device_attribute smi_enabled;
0373 int slave;
0374 u8 port_num;
0375 };
0376
0377
0378 static void mlx4_port_release(struct kobject *kobj)
0379 {
0380 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
0381 struct attribute *a;
0382 int i;
0383
0384 for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
0385 kfree(a);
0386 kfree(p->pkey_group.attrs);
0387 for (i = 0; (a = p->gid_group.attrs[i]); ++i)
0388 kfree(a);
0389 kfree(p->gid_group.attrs);
0390 kfree(p);
0391 }
0392
0393 struct port_attribute {
0394 struct attribute attr;
0395 ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf);
0396 ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
0397 const char *buf, size_t count);
0398 };
0399
0400 static ssize_t port_attr_show(struct kobject *kobj,
0401 struct attribute *attr, char *buf)
0402 {
0403 struct port_attribute *port_attr =
0404 container_of(attr, struct port_attribute, attr);
0405 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
0406
0407 if (!port_attr->show)
0408 return -EIO;
0409 return port_attr->show(p, port_attr, buf);
0410 }
0411
0412 static ssize_t port_attr_store(struct kobject *kobj,
0413 struct attribute *attr,
0414 const char *buf, size_t size)
0415 {
0416 struct port_attribute *port_attr =
0417 container_of(attr, struct port_attribute, attr);
0418 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
0419
0420 if (!port_attr->store)
0421 return -EIO;
0422 return port_attr->store(p, port_attr, buf, size);
0423 }
0424
0425 static const struct sysfs_ops port_sysfs_ops = {
0426 .show = port_attr_show,
0427 .store = port_attr_store,
0428 };
0429
0430 static struct kobj_type port_type = {
0431 .release = mlx4_port_release,
0432 .sysfs_ops = &port_sysfs_ops,
0433 };
0434
0435 struct port_table_attribute {
0436 struct port_attribute attr;
0437 char name[8];
0438 int index;
0439 };
0440
0441 static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
0442 char *buf)
0443 {
0444 struct port_table_attribute *tab_attr =
0445 container_of(attr, struct port_table_attribute, attr);
0446 struct pkey_mgt *m = &p->dev->pkeys;
0447 u8 key = m->virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index];
0448
0449 if (key >= p->dev->dev->caps.pkey_table_len[p->port_num])
0450 return sysfs_emit(buf, "none\n");
0451 return sysfs_emit(buf, "%d\n", key);
0452 }
0453
0454 static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
0455 const char *buf, size_t count)
0456 {
0457 struct port_table_attribute *tab_attr =
0458 container_of(attr, struct port_table_attribute, attr);
0459 int idx;
0460 int err;
0461
0462
0463 if (p->slave == mlx4_master_func_num(p->dev->dev))
0464 return -EINVAL;
0465
0466 if (!strncasecmp(buf, "no", 2))
0467 idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1;
0468 else if (sscanf(buf, "%i", &idx) != 1 ||
0469 idx >= p->dev->dev->caps.pkey_table_len[p->port_num] ||
0470 idx < 0)
0471 return -EINVAL;
0472
0473 p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1]
0474 [tab_attr->index] = idx;
0475 mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num,
0476 tab_attr->index, idx);
0477 err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num);
0478 if (err) {
0479 pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
0480 " port %d, index %d\n", p->slave, p->port_num, idx);
0481 return err;
0482 }
0483 return count;
0484 }
0485
0486 static ssize_t show_port_gid_idx(struct mlx4_port *p,
0487 struct port_attribute *attr, char *buf)
0488 {
0489 return sysfs_emit(buf, "%d\n", p->slave);
0490 }
0491
0492 static struct attribute **
0493 alloc_group_attrs(ssize_t (*show)(struct mlx4_port *,
0494 struct port_attribute *, char *buf),
0495 ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
0496 const char *buf, size_t count),
0497 int len)
0498 {
0499 struct attribute **tab_attr;
0500 struct port_table_attribute *element;
0501 int i;
0502
0503 tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL);
0504 if (!tab_attr)
0505 return NULL;
0506
0507 for (i = 0; i < len; i++) {
0508 element = kzalloc(sizeof (struct port_table_attribute),
0509 GFP_KERNEL);
0510 if (!element)
0511 goto err;
0512 if (snprintf(element->name, sizeof (element->name),
0513 "%d", i) >= sizeof (element->name)) {
0514 kfree(element);
0515 goto err;
0516 }
0517 sysfs_attr_init(&element->attr.attr);
0518 element->attr.attr.name = element->name;
0519 if (store) {
0520 element->attr.attr.mode = S_IWUSR | S_IRUGO;
0521 element->attr.store = store;
0522 } else
0523 element->attr.attr.mode = S_IRUGO;
0524
0525 element->attr.show = show;
0526 element->index = i;
0527 tab_attr[i] = &element->attr.attr;
0528 }
0529 return tab_attr;
0530
0531 err:
0532 while (--i >= 0)
0533 kfree(tab_attr[i]);
0534 kfree(tab_attr);
0535 return NULL;
0536 }
0537
0538 static ssize_t sysfs_show_smi_enabled(struct device *dev,
0539 struct device_attribute *attr, char *buf)
0540 {
0541 struct mlx4_port *p =
0542 container_of(attr, struct mlx4_port, smi_enabled);
0543
0544 return sysfs_emit(buf, "%d\n",
0545 !!mlx4_vf_smi_enabled(p->dev->dev, p->slave,
0546 p->port_num));
0547 }
0548
0549 static ssize_t sysfs_show_enable_smi_admin(struct device *dev,
0550 struct device_attribute *attr,
0551 char *buf)
0552 {
0553 struct mlx4_port *p =
0554 container_of(attr, struct mlx4_port, enable_smi_admin);
0555
0556 return sysfs_emit(buf, "%d\n",
0557 !!mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave,
0558 p->port_num));
0559 }
0560
0561 static ssize_t sysfs_store_enable_smi_admin(struct device *dev,
0562 struct device_attribute *attr,
0563 const char *buf, size_t count)
0564 {
0565 struct mlx4_port *p =
0566 container_of(attr, struct mlx4_port, enable_smi_admin);
0567 int enable;
0568
0569 if (sscanf(buf, "%i", &enable) != 1 ||
0570 enable < 0 || enable > 1)
0571 return -EINVAL;
0572
0573 if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable))
0574 return -EINVAL;
0575 return count;
0576 }
0577
0578 static int add_vf_smi_entries(struct mlx4_port *p)
0579 {
0580 int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
0581 IB_LINK_LAYER_ETHERNET;
0582 int ret;
0583
0584
0585 if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
0586 return 0;
0587
0588 sysfs_attr_init(&p->smi_enabled.attr);
0589 p->smi_enabled.show = sysfs_show_smi_enabled;
0590 p->smi_enabled.store = NULL;
0591 p->smi_enabled.attr.name = "smi_enabled";
0592 p->smi_enabled.attr.mode = 0444;
0593 ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr);
0594 if (ret) {
0595 pr_err("failed to create smi_enabled\n");
0596 return ret;
0597 }
0598
0599 sysfs_attr_init(&p->enable_smi_admin.attr);
0600 p->enable_smi_admin.show = sysfs_show_enable_smi_admin;
0601 p->enable_smi_admin.store = sysfs_store_enable_smi_admin;
0602 p->enable_smi_admin.attr.name = "enable_smi_admin";
0603 p->enable_smi_admin.attr.mode = 0644;
0604 ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr);
0605 if (ret) {
0606 pr_err("failed to create enable_smi_admin\n");
0607 sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
0608 return ret;
0609 }
0610 return 0;
0611 }
0612
0613 static void remove_vf_smi_entries(struct mlx4_port *p)
0614 {
0615 int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
0616 IB_LINK_LAYER_ETHERNET;
0617
0618 if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
0619 return;
0620
0621 sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
0622 sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr);
0623 }
0624
0625 static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
0626 {
0627 struct mlx4_port *p;
0628 int i;
0629 int ret;
0630 int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) ==
0631 IB_LINK_LAYER_ETHERNET;
0632
0633 p = kzalloc(sizeof *p, GFP_KERNEL);
0634 if (!p)
0635 return -ENOMEM;
0636
0637 p->dev = dev;
0638 p->port_num = port_num;
0639 p->slave = slave;
0640
0641 ret = kobject_init_and_add(&p->kobj, &port_type,
0642 kobject_get(dev->dev_ports_parent[slave]),
0643 "%d", port_num);
0644 if (ret)
0645 goto err_alloc;
0646
0647 p->pkey_group.name = "pkey_idx";
0648 p->pkey_group.attrs =
0649 alloc_group_attrs(show_port_pkey,
0650 is_eth ? NULL : store_port_pkey,
0651 dev->dev->caps.pkey_table_len[port_num]);
0652 if (!p->pkey_group.attrs) {
0653 ret = -ENOMEM;
0654 goto err_alloc;
0655 }
0656
0657 ret = sysfs_create_group(&p->kobj, &p->pkey_group);
0658 if (ret)
0659 goto err_free_pkey;
0660
0661 p->gid_group.name = "gid_idx";
0662 p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
0663 if (!p->gid_group.attrs) {
0664 ret = -ENOMEM;
0665 goto err_free_pkey;
0666 }
0667
0668 ret = sysfs_create_group(&p->kobj, &p->gid_group);
0669 if (ret)
0670 goto err_free_gid;
0671
0672 ret = add_vf_smi_entries(p);
0673 if (ret)
0674 goto err_free_gid;
0675
0676 list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
0677 return 0;
0678
0679 err_free_gid:
0680 kfree(p->gid_group.attrs[0]);
0681 kfree(p->gid_group.attrs);
0682
0683 err_free_pkey:
0684 for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
0685 kfree(p->pkey_group.attrs[i]);
0686 kfree(p->pkey_group.attrs);
0687
0688 err_alloc:
0689 kobject_put(dev->dev_ports_parent[slave]);
0690 kfree(p);
0691 return ret;
0692 }
0693
0694 static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
0695 {
0696 char name[32];
0697 int err;
0698 int port;
0699 struct kobject *p, *t;
0700 struct mlx4_port *mport;
0701 struct mlx4_active_ports actv_ports;
0702
0703 get_name(dev, name, slave, sizeof name);
0704
0705 dev->pkeys.device_parent[slave] =
0706 kobject_create_and_add(name, kobject_get(dev->iov_parent));
0707
0708 if (!dev->pkeys.device_parent[slave]) {
0709 err = -ENOMEM;
0710 goto fail_dev;
0711 }
0712
0713 INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]);
0714
0715 dev->dev_ports_parent[slave] =
0716 kobject_create_and_add("ports",
0717 kobject_get(dev->pkeys.device_parent[slave]));
0718
0719 if (!dev->dev_ports_parent[slave]) {
0720 err = -ENOMEM;
0721 goto err_ports;
0722 }
0723
0724 actv_ports = mlx4_get_active_ports(dev->dev, slave);
0725
0726 for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
0727 if (!test_bit(port - 1, actv_ports.ports))
0728 continue;
0729 err = add_port(dev, port, slave);
0730 if (err)
0731 goto err_add;
0732 }
0733 return 0;
0734
0735 err_add:
0736 list_for_each_entry_safe(p, t,
0737 &dev->pkeys.pkey_port_list[slave],
0738 entry) {
0739 list_del(&p->entry);
0740 mport = container_of(p, struct mlx4_port, kobj);
0741 sysfs_remove_group(p, &mport->pkey_group);
0742 sysfs_remove_group(p, &mport->gid_group);
0743 remove_vf_smi_entries(mport);
0744 kobject_put(p);
0745 }
0746 kobject_put(dev->dev_ports_parent[slave]);
0747
0748 err_ports:
0749 kobject_put(dev->pkeys.device_parent[slave]);
0750
0751 kobject_put(dev->pkeys.device_parent[slave]);
0752
0753 fail_dev:
0754 kobject_put(dev->iov_parent);
0755 return err;
0756 }
0757
0758 static int register_pkey_tree(struct mlx4_ib_dev *device)
0759 {
0760 int i;
0761
0762 if (!mlx4_is_master(device->dev))
0763 return 0;
0764
0765 for (i = 0; i <= device->dev->persist->num_vfs; ++i)
0766 register_one_pkey_tree(device, i);
0767
0768 return 0;
0769 }
0770
0771 static void unregister_pkey_tree(struct mlx4_ib_dev *device)
0772 {
0773 int slave;
0774 struct kobject *p, *t;
0775 struct mlx4_port *port;
0776
0777 if (!mlx4_is_master(device->dev))
0778 return;
0779
0780 for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
0781 list_for_each_entry_safe(p, t,
0782 &device->pkeys.pkey_port_list[slave],
0783 entry) {
0784 list_del(&p->entry);
0785 port = container_of(p, struct mlx4_port, kobj);
0786 sysfs_remove_group(p, &port->pkey_group);
0787 sysfs_remove_group(p, &port->gid_group);
0788 remove_vf_smi_entries(port);
0789 kobject_put(p);
0790 kobject_put(device->dev_ports_parent[slave]);
0791 }
0792 kobject_put(device->dev_ports_parent[slave]);
0793 kobject_put(device->pkeys.device_parent[slave]);
0794 kobject_put(device->pkeys.device_parent[slave]);
0795 kobject_put(device->iov_parent);
0796 }
0797 }
0798
0799 int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *dev)
0800 {
0801 unsigned int i;
0802 int ret = 0;
0803
0804 if (!mlx4_is_master(dev->dev))
0805 return 0;
0806
0807 dev->iov_parent = kobject_create_and_add("iov", &dev->ib_dev.dev.kobj);
0808 if (!dev->iov_parent) {
0809 ret = -ENOMEM;
0810 goto err;
0811 }
0812 dev->ports_parent =
0813 kobject_create_and_add("ports",
0814 kobject_get(dev->iov_parent));
0815 if (!dev->ports_parent) {
0816 ret = -ENOMEM;
0817 goto err_ports;
0818 }
0819
0820 rdma_for_each_port(&dev->ib_dev, i) {
0821 ret = add_port_entries(dev, i);
0822 if (ret)
0823 goto err_add_entries;
0824 }
0825
0826 ret = register_pkey_tree(dev);
0827 if (ret)
0828 goto err_add_entries;
0829 return 0;
0830
0831 err_add_entries:
0832 kobject_put(dev->ports_parent);
0833
0834 err_ports:
0835 kobject_put(dev->iov_parent);
0836 err:
0837 pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret);
0838 return ret;
0839 }
0840
0841 static void unregister_alias_guid_tree(struct mlx4_ib_dev *device)
0842 {
0843 struct mlx4_ib_iov_port *p;
0844 int i;
0845
0846 if (!mlx4_is_master(device->dev))
0847 return;
0848
0849 for (i = 0; i < device->dev->caps.num_ports; i++) {
0850 p = &device->iov_ports[i];
0851 kobject_put(p->admin_alias_parent);
0852 kobject_put(p->gids_parent);
0853 kobject_put(p->pkeys_parent);
0854 kobject_put(p->mcgs_parent);
0855 kobject_put(p->cur_port);
0856 kobject_put(p->cur_port);
0857 kobject_put(p->cur_port);
0858 kobject_put(p->cur_port);
0859 kobject_put(p->cur_port);
0860 kobject_put(p->dev->ports_parent);
0861 kfree(p->dentr_ar);
0862 }
0863 }
0864
0865 void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device)
0866 {
0867 unregister_alias_guid_tree(device);
0868 unregister_pkey_tree(device);
0869 kobject_put(device->ports_parent);
0870 kobject_put(device->iov_parent);
0871 kobject_put(device->iov_parent);
0872 }