2 * Copyright (c) 2012 Mellanox Technologies. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 /*#include "core_priv.h"*/
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
39 #include <rdma/ib_mad.h>
40 /*show_admin_alias_guid returns the administratively assigned value of that GUID.
41 * Values returned in buf parameter string:
42 * 0 - requests opensm to assign a value.
43 * ffffffffffffffff - delete this entry.
44 * other - value assigned by administrator.
46 static ssize_t
show_admin_alias_guid(struct device
*dev
,
47 struct device_attribute
*attr
, char *buf
)
49 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
50 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
51 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
52 struct mlx4_ib_dev
*mdev
= port
->dev
;
53 __be64 sysadmin_ag_val
;
55 sysadmin_ag_val
= mlx4_get_admin_guid(mdev
->dev
,
56 mlx4_ib_iov_dentry
->entry_num
,
59 return sysfs_emit(buf
, "%llx\n", be64_to_cpu(sysadmin_ag_val
));
62 /* store_admin_alias_guid stores the (new) administratively assigned value of that GUID.
63 * Values in buf parameter string:
64 * 0 - requests opensm to assign a value.
65 * 0xffffffffffffffff - delete this entry.
66 * other - guid value assigned by the administrator.
68 static ssize_t
store_admin_alias_guid(struct device
*dev
,
69 struct device_attribute
*attr
,
70 const char *buf
, size_t count
)
72 int record_num
;/*0-15*/
73 int guid_index_in_rec
; /*0 - 7*/
74 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
75 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
76 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
77 struct mlx4_ib_dev
*mdev
= port
->dev
;
81 record_num
= mlx4_ib_iov_dentry
->entry_num
/ 8;
82 guid_index_in_rec
= mlx4_ib_iov_dentry
->entry_num
% 8;
83 if (0 == record_num
&& 0 == guid_index_in_rec
) {
84 pr_err("GUID 0 block 0 is RO\n");
87 spin_lock_irqsave(&mdev
->sriov
.alias_guid
.ag_work_lock
, flags
);
88 sscanf(buf
, "%llx", &sysadmin_ag_val
);
89 *(__be64
*)&mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].
90 all_rec_per_port
[record_num
].
91 all_recs
[GUID_REC_SIZE
* guid_index_in_rec
] =
92 cpu_to_be64(sysadmin_ag_val
);
94 /* Change the state to be pending for update */
95 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].status
96 = MLX4_GUID_INFO_STATUS_IDLE
;
97 mlx4_set_admin_guid(mdev
->dev
, cpu_to_be64(sysadmin_ag_val
),
98 mlx4_ib_iov_dentry
->entry_num
,
101 /* set the record index */
102 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].guid_indexes
103 |= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec
);
105 spin_unlock_irqrestore(&mdev
->sriov
.alias_guid
.ag_work_lock
, flags
);
106 mlx4_ib_init_alias_guid_work(mdev
, port
->num
- 1);
111 static ssize_t
show_port_gid(struct device
*dev
,
112 struct device_attribute
*attr
,
115 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
116 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
117 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
118 struct mlx4_ib_dev
*mdev
= port
->dev
;
123 ret
= __mlx4_ib_query_gid(&mdev
->ib_dev
, port
->num
,
124 mlx4_ib_iov_dentry
->entry_num
, &gid
, 1);
128 raw
= (__be16
*)gid
.raw
;
129 return sysfs_emit(buf
, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
137 be16_to_cpu(raw
[7]));
140 static ssize_t
show_phys_port_pkey(struct device
*dev
,
141 struct device_attribute
*attr
,
144 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
145 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
146 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
147 struct mlx4_ib_dev
*mdev
= port
->dev
;
151 ret
= __mlx4_ib_query_pkey(&mdev
->ib_dev
, port
->num
,
152 mlx4_ib_iov_dentry
->entry_num
, &pkey
, 1);
156 return sysfs_emit(buf
, "0x%04x\n", pkey
);
159 #define DENTRY_REMOVE(_dentry) \
161 sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr); \
164 static int create_sysfs_entry(void *_ctx
, struct mlx4_ib_iov_sysfs_attr
*_dentry
,
165 char *_name
, struct kobject
*_kobj
,
166 ssize_t (*show
)(struct device
*dev
,
167 struct device_attribute
*attr
,
169 ssize_t (*store
)(struct device
*dev
,
170 struct device_attribute
*attr
,
171 const char *buf
, size_t count
)
175 struct mlx4_ib_iov_sysfs_attr
*vdentry
= _dentry
;
178 vdentry
->dentry
.show
= show
;
179 vdentry
->dentry
.store
= store
;
180 sysfs_attr_init(&vdentry
->dentry
.attr
);
181 vdentry
->dentry
.attr
.name
= vdentry
->name
;
182 vdentry
->dentry
.attr
.mode
= 0;
183 vdentry
->kobj
= _kobj
;
184 snprintf(vdentry
->name
, 15, "%s", _name
);
186 if (vdentry
->dentry
.store
)
187 vdentry
->dentry
.attr
.mode
|= S_IWUSR
;
189 if (vdentry
->dentry
.show
)
190 vdentry
->dentry
.attr
.mode
|= S_IRUGO
;
192 ret
= sysfs_create_file(vdentry
->kobj
, &vdentry
->dentry
.attr
);
194 pr_err("failed to create %s\n", vdentry
->dentry
.attr
.name
);
202 int add_sysfs_port_mcg_attr(struct mlx4_ib_dev
*device
, int port_num
,
203 struct attribute
*attr
)
205 struct mlx4_ib_iov_port
*port
= &device
->iov_ports
[port_num
- 1];
208 ret
= sysfs_create_file(port
->mcgs_parent
, attr
);
210 pr_err("failed to create %s\n", attr
->name
);
215 void del_sysfs_port_mcg_attr(struct mlx4_ib_dev
*device
, int port_num
,
216 struct attribute
*attr
)
218 struct mlx4_ib_iov_port
*port
= &device
->iov_ports
[port_num
- 1];
220 sysfs_remove_file(port
->mcgs_parent
, attr
);
223 static int add_port_entries(struct mlx4_ib_dev
*device
, int port_num
)
227 struct mlx4_ib_iov_port
*port
= NULL
;
229 struct ib_port_attr attr
;
231 memset(&attr
, 0, sizeof(attr
));
232 /* get the physical gid and pkey table sizes.*/
233 ret
= __mlx4_ib_query_port(&device
->ib_dev
, port_num
, &attr
, 1);
237 port
= &device
->iov_ports
[port_num
- 1];
239 port
->num
= port_num
;
240 /* Directory structure:
247 port
->dentr_ar
= kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar
),
249 if (!port
->dentr_ar
) {
253 sprintf(buff
, "%d", port_num
);
254 port
->cur_port
= kobject_create_and_add(buff
,
255 kobject_get(device
->ports_parent
));
256 if (!port
->cur_port
) {
258 goto kobj_create_err
;
261 port
->admin_alias_parent
= kobject_create_and_add("admin_guids",
262 kobject_get(port
->cur_port
));
263 if (!port
->admin_alias_parent
) {
265 goto err_admin_guids
;
267 for (i
= 0 ; i
< attr
.gid_tbl_len
; i
++) {
268 sprintf(buff
, "%d", i
);
269 port
->dentr_ar
->dentries
[i
].entry_num
= i
;
270 ret
= create_sysfs_entry(port
, &port
->dentr_ar
->dentries
[i
],
271 buff
, port
->admin_alias_parent
,
272 show_admin_alias_guid
, store_admin_alias_guid
);
274 goto err_admin_alias_parent
;
277 /* gids subdirectory (operational gids) */
278 port
->gids_parent
= kobject_create_and_add("gids",
279 kobject_get(port
->cur_port
));
280 if (!port
->gids_parent
) {
285 for (i
= 0 ; i
< attr
.gid_tbl_len
; i
++) {
286 sprintf(buff
, "%d", i
);
287 port
->dentr_ar
->dentries
[attr
.gid_tbl_len
+ i
].entry_num
= i
;
288 ret
= create_sysfs_entry(port
,
289 &port
->dentr_ar
->dentries
[attr
.gid_tbl_len
+ i
],
291 port
->gids_parent
, show_port_gid
, NULL
);
293 goto err_gids_parent
;
296 /* physical port pkey table */
298 kobject_create_and_add("pkeys", kobject_get(port
->cur_port
));
299 if (!port
->pkeys_parent
) {
304 for (i
= 0 ; i
< attr
.pkey_tbl_len
; i
++) {
305 sprintf(buff
, "%d", i
);
306 port
->dentr_ar
->dentries
[2 * attr
.gid_tbl_len
+ i
].entry_num
= i
;
307 ret
= create_sysfs_entry(port
,
308 &port
->dentr_ar
->dentries
[2 * attr
.gid_tbl_len
+ i
],
309 buff
, port
->pkeys_parent
,
310 show_phys_port_pkey
, NULL
);
312 goto err_pkeys_parent
;
317 kobject_create_and_add("mcgs", kobject_get(port
->cur_port
));
318 if (!port
->mcgs_parent
) {
325 kobject_put(port
->cur_port
);
328 kobject_put(port
->pkeys_parent
);
331 kobject_put(port
->cur_port
);
334 kobject_put(port
->gids_parent
);
337 kobject_put(port
->cur_port
);
339 err_admin_alias_parent
:
340 kobject_put(port
->admin_alias_parent
);
343 kobject_put(port
->cur_port
);
344 kobject_put(port
->cur_port
); /* once more for create_and_add buff */
347 kobject_put(device
->ports_parent
);
348 kfree(port
->dentr_ar
);
351 pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
356 static void get_name(struct mlx4_ib_dev
*dev
, char *name
, int i
, int max
)
358 /* pci_name format is: bus:dev:func -> xxxx:yy:zz.n
359 * with no ARI only 3 last bits are used so when the fn is higher than 8
360 * need to add it to the dev num, so count in the last number will be
362 snprintf(name
, max
, "%.8s%.2d.%d", pci_name(dev
->dev
->persist
->pdev
),
368 struct mlx4_ib_dev
*dev
;
369 struct attribute_group pkey_group
;
370 struct attribute_group gid_group
;
371 struct device_attribute enable_smi_admin
;
372 struct device_attribute smi_enabled
;
378 static void mlx4_port_release(struct kobject
*kobj
)
380 struct mlx4_port
*p
= container_of(kobj
, struct mlx4_port
, kobj
);
384 for (i
= 0; (a
= p
->pkey_group
.attrs
[i
]); ++i
)
386 kfree(p
->pkey_group
.attrs
);
387 for (i
= 0; (a
= p
->gid_group
.attrs
[i
]); ++i
)
389 kfree(p
->gid_group
.attrs
);
393 struct port_attribute
{
394 struct attribute attr
;
395 ssize_t (*show
)(struct mlx4_port
*, struct port_attribute
*, char *buf
);
396 ssize_t (*store
)(struct mlx4_port
*, struct port_attribute
*,
397 const char *buf
, size_t count
);
400 static ssize_t
port_attr_show(struct kobject
*kobj
,
401 struct attribute
*attr
, char *buf
)
403 struct port_attribute
*port_attr
=
404 container_of(attr
, struct port_attribute
, attr
);
405 struct mlx4_port
*p
= container_of(kobj
, struct mlx4_port
, kobj
);
407 if (!port_attr
->show
)
409 return port_attr
->show(p
, port_attr
, buf
);
412 static ssize_t
port_attr_store(struct kobject
*kobj
,
413 struct attribute
*attr
,
414 const char *buf
, size_t size
)
416 struct port_attribute
*port_attr
=
417 container_of(attr
, struct port_attribute
, attr
);
418 struct mlx4_port
*p
= container_of(kobj
, struct mlx4_port
, kobj
);
420 if (!port_attr
->store
)
422 return port_attr
->store(p
, port_attr
, buf
, size
);
425 static const struct sysfs_ops port_sysfs_ops
= {
426 .show
= port_attr_show
,
427 .store
= port_attr_store
,
430 static struct kobj_type port_type
= {
431 .release
= mlx4_port_release
,
432 .sysfs_ops
= &port_sysfs_ops
,
435 struct port_table_attribute
{
436 struct port_attribute attr
;
441 static ssize_t
show_port_pkey(struct mlx4_port
*p
, struct port_attribute
*attr
,
444 struct port_table_attribute
*tab_attr
=
445 container_of(attr
, struct port_table_attribute
, attr
);
446 struct pkey_mgt
*m
= &p
->dev
->pkeys
;
447 u8 key
= m
->virt2phys_pkey
[p
->slave
][p
->port_num
- 1][tab_attr
->index
];
449 if (key
>= p
->dev
->dev
->caps
.pkey_table_len
[p
->port_num
])
450 return sysfs_emit(buf
, "none\n");
451 return sysfs_emit(buf
, "%d\n", key
);
454 static ssize_t
store_port_pkey(struct mlx4_port
*p
, struct port_attribute
*attr
,
455 const char *buf
, size_t count
)
457 struct port_table_attribute
*tab_attr
=
458 container_of(attr
, struct port_table_attribute
, attr
);
462 /* do not allow remapping Dom0 virtual pkey table */
463 if (p
->slave
== mlx4_master_func_num(p
->dev
->dev
))
466 if (!strncasecmp(buf
, "no", 2))
467 idx
= p
->dev
->dev
->phys_caps
.pkey_phys_table_len
[p
->port_num
] - 1;
468 else if (sscanf(buf
, "%i", &idx
) != 1 ||
469 idx
>= p
->dev
->dev
->caps
.pkey_table_len
[p
->port_num
] ||
473 p
->dev
->pkeys
.virt2phys_pkey
[p
->slave
][p
->port_num
- 1]
474 [tab_attr
->index
] = idx
;
475 mlx4_sync_pkey_table(p
->dev
->dev
, p
->slave
, p
->port_num
,
476 tab_attr
->index
, idx
);
477 err
= mlx4_gen_pkey_eqe(p
->dev
->dev
, p
->slave
, p
->port_num
);
479 pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
480 " port %d, index %d\n", p
->slave
, p
->port_num
, idx
);
486 static ssize_t
show_port_gid_idx(struct mlx4_port
*p
,
487 struct port_attribute
*attr
, char *buf
)
489 return sysfs_emit(buf
, "%d\n", p
->slave
);
492 static struct attribute
**
493 alloc_group_attrs(ssize_t (*show
)(struct mlx4_port
*,
494 struct port_attribute
*, char *buf
),
495 ssize_t (*store
)(struct mlx4_port
*, struct port_attribute
*,
496 const char *buf
, size_t count
),
499 struct attribute
**tab_attr
;
500 struct port_table_attribute
*element
;
503 tab_attr
= kcalloc(1 + len
, sizeof (struct attribute
*), GFP_KERNEL
);
507 for (i
= 0; i
< len
; i
++) {
508 element
= kzalloc(sizeof (struct port_table_attribute
),
512 if (snprintf(element
->name
, sizeof (element
->name
),
513 "%d", i
) >= sizeof (element
->name
)) {
517 sysfs_attr_init(&element
->attr
.attr
);
518 element
->attr
.attr
.name
= element
->name
;
520 element
->attr
.attr
.mode
= S_IWUSR
| S_IRUGO
;
521 element
->attr
.store
= store
;
523 element
->attr
.attr
.mode
= S_IRUGO
;
525 element
->attr
.show
= show
;
527 tab_attr
[i
] = &element
->attr
.attr
;
538 static ssize_t
sysfs_show_smi_enabled(struct device
*dev
,
539 struct device_attribute
*attr
, char *buf
)
541 struct mlx4_port
*p
=
542 container_of(attr
, struct mlx4_port
, smi_enabled
);
544 return sysfs_emit(buf
, "%d\n",
545 !!mlx4_vf_smi_enabled(p
->dev
->dev
, p
->slave
,
549 static ssize_t
sysfs_show_enable_smi_admin(struct device
*dev
,
550 struct device_attribute
*attr
,
553 struct mlx4_port
*p
=
554 container_of(attr
, struct mlx4_port
, enable_smi_admin
);
556 return sysfs_emit(buf
, "%d\n",
557 !!mlx4_vf_get_enable_smi_admin(p
->dev
->dev
, p
->slave
,
561 static ssize_t
sysfs_store_enable_smi_admin(struct device
*dev
,
562 struct device_attribute
*attr
,
563 const char *buf
, size_t count
)
565 struct mlx4_port
*p
=
566 container_of(attr
, struct mlx4_port
, enable_smi_admin
);
569 if (sscanf(buf
, "%i", &enable
) != 1 ||
570 enable
< 0 || enable
> 1)
573 if (mlx4_vf_set_enable_smi_admin(p
->dev
->dev
, p
->slave
, p
->port_num
, enable
))
578 static int add_vf_smi_entries(struct mlx4_port
*p
)
580 int is_eth
= rdma_port_get_link_layer(&p
->dev
->ib_dev
, p
->port_num
) ==
581 IB_LINK_LAYER_ETHERNET
;
584 /* do not display entries if eth transport, or if master */
585 if (is_eth
|| p
->slave
== mlx4_master_func_num(p
->dev
->dev
))
588 sysfs_attr_init(&p
->smi_enabled
.attr
);
589 p
->smi_enabled
.show
= sysfs_show_smi_enabled
;
590 p
->smi_enabled
.store
= NULL
;
591 p
->smi_enabled
.attr
.name
= "smi_enabled";
592 p
->smi_enabled
.attr
.mode
= 0444;
593 ret
= sysfs_create_file(&p
->kobj
, &p
->smi_enabled
.attr
);
595 pr_err("failed to create smi_enabled\n");
599 sysfs_attr_init(&p
->enable_smi_admin
.attr
);
600 p
->enable_smi_admin
.show
= sysfs_show_enable_smi_admin
;
601 p
->enable_smi_admin
.store
= sysfs_store_enable_smi_admin
;
602 p
->enable_smi_admin
.attr
.name
= "enable_smi_admin";
603 p
->enable_smi_admin
.attr
.mode
= 0644;
604 ret
= sysfs_create_file(&p
->kobj
, &p
->enable_smi_admin
.attr
);
606 pr_err("failed to create enable_smi_admin\n");
607 sysfs_remove_file(&p
->kobj
, &p
->smi_enabled
.attr
);
613 static void remove_vf_smi_entries(struct mlx4_port
*p
)
615 int is_eth
= rdma_port_get_link_layer(&p
->dev
->ib_dev
, p
->port_num
) ==
616 IB_LINK_LAYER_ETHERNET
;
618 if (is_eth
|| p
->slave
== mlx4_master_func_num(p
->dev
->dev
))
621 sysfs_remove_file(&p
->kobj
, &p
->smi_enabled
.attr
);
622 sysfs_remove_file(&p
->kobj
, &p
->enable_smi_admin
.attr
);
625 static int add_port(struct mlx4_ib_dev
*dev
, int port_num
, int slave
)
630 int is_eth
= rdma_port_get_link_layer(&dev
->ib_dev
, port_num
) ==
631 IB_LINK_LAYER_ETHERNET
;
633 p
= kzalloc(sizeof *p
, GFP_KERNEL
);
638 p
->port_num
= port_num
;
641 ret
= kobject_init_and_add(&p
->kobj
, &port_type
,
642 kobject_get(dev
->dev_ports_parent
[slave
]),
647 p
->pkey_group
.name
= "pkey_idx";
648 p
->pkey_group
.attrs
=
649 alloc_group_attrs(show_port_pkey
,
650 is_eth
? NULL
: store_port_pkey
,
651 dev
->dev
->caps
.pkey_table_len
[port_num
]);
652 if (!p
->pkey_group
.attrs
) {
657 ret
= sysfs_create_group(&p
->kobj
, &p
->pkey_group
);
661 p
->gid_group
.name
= "gid_idx";
662 p
->gid_group
.attrs
= alloc_group_attrs(show_port_gid_idx
, NULL
, 1);
663 if (!p
->gid_group
.attrs
) {
668 ret
= sysfs_create_group(&p
->kobj
, &p
->gid_group
);
672 ret
= add_vf_smi_entries(p
);
676 list_add_tail(&p
->kobj
.entry
, &dev
->pkeys
.pkey_port_list
[slave
]);
680 kfree(p
->gid_group
.attrs
[0]);
681 kfree(p
->gid_group
.attrs
);
684 for (i
= 0; i
< dev
->dev
->caps
.pkey_table_len
[port_num
]; ++i
)
685 kfree(p
->pkey_group
.attrs
[i
]);
686 kfree(p
->pkey_group
.attrs
);
689 kobject_put(dev
->dev_ports_parent
[slave
]);
694 static int register_one_pkey_tree(struct mlx4_ib_dev
*dev
, int slave
)
699 struct kobject
*p
, *t
;
700 struct mlx4_port
*mport
;
701 struct mlx4_active_ports actv_ports
;
703 get_name(dev
, name
, slave
, sizeof name
);
705 dev
->pkeys
.device_parent
[slave
] =
706 kobject_create_and_add(name
, kobject_get(dev
->iov_parent
));
708 if (!dev
->pkeys
.device_parent
[slave
]) {
713 INIT_LIST_HEAD(&dev
->pkeys
.pkey_port_list
[slave
]);
715 dev
->dev_ports_parent
[slave
] =
716 kobject_create_and_add("ports",
717 kobject_get(dev
->pkeys
.device_parent
[slave
]));
719 if (!dev
->dev_ports_parent
[slave
]) {
724 actv_ports
= mlx4_get_active_ports(dev
->dev
, slave
);
726 for (port
= 1; port
<= dev
->dev
->caps
.num_ports
; ++port
) {
727 if (!test_bit(port
- 1, actv_ports
.ports
))
729 err
= add_port(dev
, port
, slave
);
736 list_for_each_entry_safe(p
, t
,
737 &dev
->pkeys
.pkey_port_list
[slave
],
740 mport
= container_of(p
, struct mlx4_port
, kobj
);
741 sysfs_remove_group(p
, &mport
->pkey_group
);
742 sysfs_remove_group(p
, &mport
->gid_group
);
743 remove_vf_smi_entries(mport
);
746 kobject_put(dev
->dev_ports_parent
[slave
]);
749 kobject_put(dev
->pkeys
.device_parent
[slave
]);
750 /* extra put for the device_parent create_and_add */
751 kobject_put(dev
->pkeys
.device_parent
[slave
]);
754 kobject_put(dev
->iov_parent
);
758 static int register_pkey_tree(struct mlx4_ib_dev
*device
)
762 if (!mlx4_is_master(device
->dev
))
765 for (i
= 0; i
<= device
->dev
->persist
->num_vfs
; ++i
)
766 register_one_pkey_tree(device
, i
);
771 static void unregister_pkey_tree(struct mlx4_ib_dev
*device
)
774 struct kobject
*p
, *t
;
775 struct mlx4_port
*port
;
777 if (!mlx4_is_master(device
->dev
))
780 for (slave
= device
->dev
->persist
->num_vfs
; slave
>= 0; --slave
) {
781 list_for_each_entry_safe(p
, t
,
782 &device
->pkeys
.pkey_port_list
[slave
],
785 port
= container_of(p
, struct mlx4_port
, kobj
);
786 sysfs_remove_group(p
, &port
->pkey_group
);
787 sysfs_remove_group(p
, &port
->gid_group
);
788 remove_vf_smi_entries(port
);
790 kobject_put(device
->dev_ports_parent
[slave
]);
792 kobject_put(device
->dev_ports_parent
[slave
]);
793 kobject_put(device
->pkeys
.device_parent
[slave
]);
794 kobject_put(device
->pkeys
.device_parent
[slave
]);
795 kobject_put(device
->iov_parent
);
799 int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev
*dev
)
804 if (!mlx4_is_master(dev
->dev
))
807 dev
->iov_parent
= kobject_create_and_add("iov", &dev
->ib_dev
.dev
.kobj
);
808 if (!dev
->iov_parent
) {
813 kobject_create_and_add("ports",
814 kobject_get(dev
->iov_parent
));
815 if (!dev
->ports_parent
) {
820 rdma_for_each_port(&dev
->ib_dev
, i
) {
821 ret
= add_port_entries(dev
, i
);
823 goto err_add_entries
;
826 ret
= register_pkey_tree(dev
);
828 goto err_add_entries
;
832 kobject_put(dev
->ports_parent
);
835 kobject_put(dev
->iov_parent
);
837 pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret
);
841 static void unregister_alias_guid_tree(struct mlx4_ib_dev
*device
)
843 struct mlx4_ib_iov_port
*p
;
846 if (!mlx4_is_master(device
->dev
))
849 for (i
= 0; i
< device
->dev
->caps
.num_ports
; i
++) {
850 p
= &device
->iov_ports
[i
];
851 kobject_put(p
->admin_alias_parent
);
852 kobject_put(p
->gids_parent
);
853 kobject_put(p
->pkeys_parent
);
854 kobject_put(p
->mcgs_parent
);
855 kobject_put(p
->cur_port
);
856 kobject_put(p
->cur_port
);
857 kobject_put(p
->cur_port
);
858 kobject_put(p
->cur_port
);
859 kobject_put(p
->cur_port
);
860 kobject_put(p
->dev
->ports_parent
);
865 void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev
*device
)
867 unregister_alias_guid_tree(device
);
868 unregister_pkey_tree(device
);
869 kobject_put(device
->ports_parent
);
870 kobject_put(device
->iov_parent
);
871 kobject_put(device
->iov_parent
);