2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include "core_priv.h"
37 #include <linux/slab.h>
38 #include <linux/stat.h>
39 #include <linux/string.h>
40 #include <linux/netdevice.h>
41 #include <linux/ethtool.h>
43 #include <rdma/ib_mad.h>
44 #include <rdma/ib_pma.h>
45 #include <rdma/ib_cache.h>
46 #include <rdma/rdma_counter.h>
47 #include <rdma/ib_sysfs.h>
49 struct port_table_attribute
{
50 struct ib_port_attribute attr
;
56 struct gid_attr_group
{
59 struct attribute_group groups
[2];
60 const struct attribute_group
*groups_list
[3];
61 struct port_table_attribute attrs_list
[];
66 struct ib_device
*ibdev
;
67 struct gid_attr_group
*gid_attr_group
;
68 struct hw_stats_port_data
*hw_stats_data
;
70 struct attribute_group groups
[3];
71 const struct attribute_group
*groups_list
[5];
73 struct port_table_attribute attrs_list
[];
76 struct hw_stats_device_attribute
{
77 struct device_attribute attr
;
78 ssize_t (*show
)(struct ib_device
*ibdev
, struct rdma_hw_stats
*stats
,
79 unsigned int index
, unsigned int port_num
, char *buf
);
80 ssize_t (*store
)(struct ib_device
*ibdev
, struct rdma_hw_stats
*stats
,
81 unsigned int index
, unsigned int port_num
,
82 const char *buf
, size_t count
);
85 struct hw_stats_port_attribute
{
86 struct ib_port_attribute attr
;
87 ssize_t (*show
)(struct ib_device
*ibdev
, struct rdma_hw_stats
*stats
,
88 unsigned int index
, unsigned int port_num
, char *buf
);
89 ssize_t (*store
)(struct ib_device
*ibdev
, struct rdma_hw_stats
*stats
,
90 unsigned int index
, unsigned int port_num
,
91 const char *buf
, size_t count
);
94 struct hw_stats_device_data
{
95 struct attribute_group group
;
96 struct rdma_hw_stats
*stats
;
97 struct hw_stats_device_attribute attrs
[];
100 struct hw_stats_port_data
{
101 struct rdma_hw_stats
*stats
;
102 struct hw_stats_port_attribute attrs
[];
105 static ssize_t
port_attr_show(struct kobject
*kobj
,
106 struct attribute
*attr
, char *buf
)
108 struct ib_port_attribute
*port_attr
=
109 container_of(attr
, struct ib_port_attribute
, attr
);
110 struct ib_port
*p
= container_of(kobj
, struct ib_port
, kobj
);
112 if (!port_attr
->show
)
115 return port_attr
->show(p
->ibdev
, p
->port_num
, port_attr
, buf
);
118 static ssize_t
port_attr_store(struct kobject
*kobj
,
119 struct attribute
*attr
,
120 const char *buf
, size_t count
)
122 struct ib_port_attribute
*port_attr
=
123 container_of(attr
, struct ib_port_attribute
, attr
);
124 struct ib_port
*p
= container_of(kobj
, struct ib_port
, kobj
);
126 if (!port_attr
->store
)
128 return port_attr
->store(p
->ibdev
, p
->port_num
, port_attr
, buf
, count
);
131 struct ib_device
*ib_port_sysfs_get_ibdev_kobj(struct kobject
*kobj
,
134 struct ib_port
*port
= container_of(kobj
, struct ib_port
, kobj
);
136 *port_num
= port
->port_num
;
139 EXPORT_SYMBOL(ib_port_sysfs_get_ibdev_kobj
);
141 static const struct sysfs_ops port_sysfs_ops
= {
142 .show
= port_attr_show
,
143 .store
= port_attr_store
146 static ssize_t
hw_stat_device_show(struct device
*dev
,
147 struct device_attribute
*attr
, char *buf
)
149 struct hw_stats_device_attribute
*stat_attr
=
150 container_of(attr
, struct hw_stats_device_attribute
, attr
);
151 struct ib_device
*ibdev
= container_of(dev
, struct ib_device
, dev
);
153 return stat_attr
->show(ibdev
, ibdev
->hw_stats_data
->stats
,
154 stat_attr
- ibdev
->hw_stats_data
->attrs
, 0, buf
);
157 static ssize_t
hw_stat_device_store(struct device
*dev
,
158 struct device_attribute
*attr
,
159 const char *buf
, size_t count
)
161 struct hw_stats_device_attribute
*stat_attr
=
162 container_of(attr
, struct hw_stats_device_attribute
, attr
);
163 struct ib_device
*ibdev
= container_of(dev
, struct ib_device
, dev
);
165 return stat_attr
->store(ibdev
, ibdev
->hw_stats_data
->stats
,
166 stat_attr
- ibdev
->hw_stats_data
->attrs
, 0, buf
,
170 static ssize_t
hw_stat_port_show(struct ib_device
*ibdev
, u32 port_num
,
171 struct ib_port_attribute
*attr
, char *buf
)
173 struct hw_stats_port_attribute
*stat_attr
=
174 container_of(attr
, struct hw_stats_port_attribute
, attr
);
175 struct ib_port
*port
= ibdev
->port_data
[port_num
].sysfs
;
177 return stat_attr
->show(ibdev
, port
->hw_stats_data
->stats
,
178 stat_attr
- port
->hw_stats_data
->attrs
,
179 port
->port_num
, buf
);
182 static ssize_t
hw_stat_port_store(struct ib_device
*ibdev
, u32 port_num
,
183 struct ib_port_attribute
*attr
,
184 const char *buf
, size_t count
)
186 struct hw_stats_port_attribute
*stat_attr
=
187 container_of(attr
, struct hw_stats_port_attribute
, attr
);
188 struct ib_port
*port
= ibdev
->port_data
[port_num
].sysfs
;
190 return stat_attr
->store(ibdev
, port
->hw_stats_data
->stats
,
191 stat_attr
- port
->hw_stats_data
->attrs
,
192 port
->port_num
, buf
, count
);
195 static ssize_t
gid_attr_show(struct kobject
*kobj
,
196 struct attribute
*attr
, char *buf
)
198 struct ib_port_attribute
*port_attr
=
199 container_of(attr
, struct ib_port_attribute
, attr
);
200 struct ib_port
*p
= container_of(kobj
, struct gid_attr_group
,
203 if (!port_attr
->show
)
206 return port_attr
->show(p
->ibdev
, p
->port_num
, port_attr
, buf
);
209 static const struct sysfs_ops gid_attr_sysfs_ops
= {
210 .show
= gid_attr_show
213 static ssize_t
state_show(struct ib_device
*ibdev
, u32 port_num
,
214 struct ib_port_attribute
*unused
, char *buf
)
216 struct ib_port_attr attr
;
219 static const char *state_name
[] = {
220 [IB_PORT_NOP
] = "NOP",
221 [IB_PORT_DOWN
] = "DOWN",
222 [IB_PORT_INIT
] = "INIT",
223 [IB_PORT_ARMED
] = "ARMED",
224 [IB_PORT_ACTIVE
] = "ACTIVE",
225 [IB_PORT_ACTIVE_DEFER
] = "ACTIVE_DEFER"
228 ret
= ib_query_port(ibdev
, port_num
, &attr
);
232 return sysfs_emit(buf
, "%d: %s\n", attr
.state
,
234 attr
.state
< ARRAY_SIZE(state_name
) ?
235 state_name
[attr
.state
] :
239 static ssize_t
lid_show(struct ib_device
*ibdev
, u32 port_num
,
240 struct ib_port_attribute
*unused
, char *buf
)
242 struct ib_port_attr attr
;
245 ret
= ib_query_port(ibdev
, port_num
, &attr
);
249 return sysfs_emit(buf
, "0x%x\n", attr
.lid
);
252 static ssize_t
lid_mask_count_show(struct ib_device
*ibdev
, u32 port_num
,
253 struct ib_port_attribute
*unused
, char *buf
)
255 struct ib_port_attr attr
;
258 ret
= ib_query_port(ibdev
, port_num
, &attr
);
262 return sysfs_emit(buf
, "%u\n", attr
.lmc
);
265 static ssize_t
sm_lid_show(struct ib_device
*ibdev
, u32 port_num
,
266 struct ib_port_attribute
*unused
, char *buf
)
268 struct ib_port_attr attr
;
271 ret
= ib_query_port(ibdev
, port_num
, &attr
);
275 return sysfs_emit(buf
, "0x%x\n", attr
.sm_lid
);
278 static ssize_t
sm_sl_show(struct ib_device
*ibdev
, u32 port_num
,
279 struct ib_port_attribute
*unused
, char *buf
)
281 struct ib_port_attr attr
;
284 ret
= ib_query_port(ibdev
, port_num
, &attr
);
288 return sysfs_emit(buf
, "%u\n", attr
.sm_sl
);
291 static ssize_t
cap_mask_show(struct ib_device
*ibdev
, u32 port_num
,
292 struct ib_port_attribute
*unused
, char *buf
)
294 struct ib_port_attr attr
;
297 ret
= ib_query_port(ibdev
, port_num
, &attr
);
301 return sysfs_emit(buf
, "0x%08x\n", attr
.port_cap_flags
);
304 static ssize_t
rate_show(struct ib_device
*ibdev
, u32 port_num
,
305 struct ib_port_attribute
*unused
, char *buf
)
307 struct ib_port_attr attr
;
309 int rate
; /* in deci-Gb/sec */
312 ret
= ib_query_port(ibdev
, port_num
, &attr
);
316 switch (attr
.active_speed
) {
350 default: /* default to SDR for invalid rates */
356 rate
*= ib_width_enum_to_int(attr
.active_width
);
360 return sysfs_emit(buf
, "%d%s Gb/sec (%dX%s)\n", rate
/ 10,
361 rate
% 10 ? ".5" : "",
362 ib_width_enum_to_int(attr
.active_width
), speed
);
365 static const char *phys_state_to_str(enum ib_port_phys_state phys_state
)
367 static const char *phys_state_str
[] = {
372 "PortConfigurationTraining",
378 if (phys_state
< ARRAY_SIZE(phys_state_str
))
379 return phys_state_str
[phys_state
];
383 static ssize_t
phys_state_show(struct ib_device
*ibdev
, u32 port_num
,
384 struct ib_port_attribute
*unused
, char *buf
)
386 struct ib_port_attr attr
;
390 ret
= ib_query_port(ibdev
, port_num
, &attr
);
394 return sysfs_emit(buf
, "%u: %s\n", attr
.phys_state
,
395 phys_state_to_str(attr
.phys_state
));
398 static ssize_t
link_layer_show(struct ib_device
*ibdev
, u32 port_num
,
399 struct ib_port_attribute
*unused
, char *buf
)
403 switch (rdma_port_get_link_layer(ibdev
, port_num
)) {
404 case IB_LINK_LAYER_INFINIBAND
:
405 output
= "InfiniBand";
407 case IB_LINK_LAYER_ETHERNET
:
415 return sysfs_emit(buf
, "%s\n", output
);
418 static IB_PORT_ATTR_RO(state
);
419 static IB_PORT_ATTR_RO(lid
);
420 static IB_PORT_ATTR_RO(lid_mask_count
);
421 static IB_PORT_ATTR_RO(sm_lid
);
422 static IB_PORT_ATTR_RO(sm_sl
);
423 static IB_PORT_ATTR_RO(cap_mask
);
424 static IB_PORT_ATTR_RO(rate
);
425 static IB_PORT_ATTR_RO(phys_state
);
426 static IB_PORT_ATTR_RO(link_layer
);
428 static struct attribute
*port_default_attrs
[] = {
429 &ib_port_attr_state
.attr
,
430 &ib_port_attr_lid
.attr
,
431 &ib_port_attr_lid_mask_count
.attr
,
432 &ib_port_attr_sm_lid
.attr
,
433 &ib_port_attr_sm_sl
.attr
,
434 &ib_port_attr_cap_mask
.attr
,
435 &ib_port_attr_rate
.attr
,
436 &ib_port_attr_phys_state
.attr
,
437 &ib_port_attr_link_layer
.attr
,
440 ATTRIBUTE_GROUPS(port_default
);
442 static ssize_t
print_ndev(const struct ib_gid_attr
*gid_attr
, char *buf
)
444 struct net_device
*ndev
;
448 ndev
= rcu_dereference(gid_attr
->ndev
);
450 ret
= sysfs_emit(buf
, "%s\n", ndev
->name
);
455 static ssize_t
print_gid_type(const struct ib_gid_attr
*gid_attr
, char *buf
)
457 return sysfs_emit(buf
, "%s\n",
458 ib_cache_gid_type_str(gid_attr
->gid_type
));
461 static ssize_t
_show_port_gid_attr(
462 struct ib_device
*ibdev
, u32 port_num
, struct ib_port_attribute
*attr
,
464 ssize_t (*print
)(const struct ib_gid_attr
*gid_attr
, char *buf
))
466 struct port_table_attribute
*tab_attr
=
467 container_of(attr
, struct port_table_attribute
, attr
);
468 const struct ib_gid_attr
*gid_attr
;
471 gid_attr
= rdma_get_gid_attr(ibdev
, port_num
, tab_attr
->index
);
472 if (IS_ERR(gid_attr
))
473 /* -EINVAL is returned for user space compatibility reasons. */
476 ret
= print(gid_attr
, buf
);
477 rdma_put_gid_attr(gid_attr
);
481 static ssize_t
show_port_gid(struct ib_device
*ibdev
, u32 port_num
,
482 struct ib_port_attribute
*attr
, char *buf
)
484 struct port_table_attribute
*tab_attr
=
485 container_of(attr
, struct port_table_attribute
, attr
);
486 const struct ib_gid_attr
*gid_attr
;
489 gid_attr
= rdma_get_gid_attr(ibdev
, port_num
, tab_attr
->index
);
490 if (IS_ERR(gid_attr
)) {
491 const union ib_gid zgid
= {};
493 /* If reading GID fails, it is likely due to GID entry being
494 * empty (invalid) or reserved GID in the table. User space
495 * expects to read GID table entries as long as it given index
496 * is within GID table size. Administrative/debugging tool
497 * fails to query rest of the GID entries if it hits error
498 * while querying a GID of the given index. To avoid user
499 * space throwing such error on fail to read gid, return zero
500 * GID as before. This maintains backward compatibility.
502 return sysfs_emit(buf
, "%pI6\n", zgid
.raw
);
505 len
= sysfs_emit(buf
, "%pI6\n", gid_attr
->gid
.raw
);
506 rdma_put_gid_attr(gid_attr
);
510 static ssize_t
show_port_gid_attr_ndev(struct ib_device
*ibdev
, u32 port_num
,
511 struct ib_port_attribute
*attr
,
514 return _show_port_gid_attr(ibdev
, port_num
, attr
, buf
, print_ndev
);
517 static ssize_t
show_port_gid_attr_gid_type(struct ib_device
*ibdev
,
519 struct ib_port_attribute
*attr
,
522 return _show_port_gid_attr(ibdev
, port_num
, attr
, buf
, print_gid_type
);
525 static ssize_t
show_port_pkey(struct ib_device
*ibdev
, u32 port_num
,
526 struct ib_port_attribute
*attr
, char *buf
)
528 struct port_table_attribute
*tab_attr
=
529 container_of(attr
, struct port_table_attribute
, attr
);
533 ret
= ib_query_pkey(ibdev
, port_num
, tab_attr
->index
, &pkey
);
537 return sysfs_emit(buf
, "0x%04x\n", pkey
);
540 #define PORT_PMA_ATTR(_name, _counter, _width, _offset) \
541 struct port_table_attribute port_pma_attr_##_name = { \
542 .attr = __ATTR(_name, S_IRUGO, show_pma_counter, NULL), \
543 .index = (_offset) | ((_width) << 16) | ((_counter) << 24), \
544 .attr_id = IB_PMA_PORT_COUNTERS, \
547 #define PORT_PMA_ATTR_EXT(_name, _width, _offset) \
548 struct port_table_attribute port_pma_attr_ext_##_name = { \
549 .attr = __ATTR(_name, S_IRUGO, show_pma_counter, NULL), \
550 .index = (_offset) | ((_width) << 16), \
551 .attr_id = IB_PMA_PORT_COUNTERS_EXT, \
555 * Get a Perfmgmt MAD block of data.
556 * Returns error code or the number of bytes retrieved.
558 static int get_perf_mad(struct ib_device
*dev
, int port_num
, __be16 attr
,
559 void *data
, int offset
, size_t size
)
561 struct ib_mad
*in_mad
;
562 struct ib_mad
*out_mad
;
563 size_t mad_size
= sizeof(*out_mad
);
564 u16 out_mad_pkey_index
= 0;
567 if (!dev
->ops
.process_mad
)
570 in_mad
= kzalloc(sizeof(*in_mad
), GFP_KERNEL
);
571 out_mad
= kzalloc(sizeof(*out_mad
), GFP_KERNEL
);
572 if (!in_mad
|| !out_mad
) {
577 in_mad
->mad_hdr
.base_version
= 1;
578 in_mad
->mad_hdr
.mgmt_class
= IB_MGMT_CLASS_PERF_MGMT
;
579 in_mad
->mad_hdr
.class_version
= 1;
580 in_mad
->mad_hdr
.method
= IB_MGMT_METHOD_GET
;
581 in_mad
->mad_hdr
.attr_id
= attr
;
583 if (attr
!= IB_PMA_CLASS_PORT_INFO
)
584 in_mad
->data
[41] = port_num
; /* PortSelect field */
586 if ((dev
->ops
.process_mad(dev
, IB_MAD_IGNORE_MKEY
, port_num
, NULL
, NULL
,
587 in_mad
, out_mad
, &mad_size
,
588 &out_mad_pkey_index
) &
589 (IB_MAD_RESULT_SUCCESS
| IB_MAD_RESULT_REPLY
)) !=
590 (IB_MAD_RESULT_SUCCESS
| IB_MAD_RESULT_REPLY
)) {
594 memcpy(data
, out_mad
->data
+ offset
, size
);
602 static ssize_t
show_pma_counter(struct ib_device
*ibdev
, u32 port_num
,
603 struct ib_port_attribute
*attr
, char *buf
)
605 struct port_table_attribute
*tab_attr
=
606 container_of(attr
, struct port_table_attribute
, attr
);
607 int offset
= tab_attr
->index
& 0xffff;
608 int width
= (tab_attr
->index
>> 16) & 0xff;
613 ret
= get_perf_mad(ibdev
, port_num
, tab_attr
->attr_id
, &data
,
614 40 + offset
/ 8, sizeof(data
));
620 len
= sysfs_emit(buf
, "%d\n",
621 (*data
>> (4 - (offset
% 8))) & 0xf);
624 len
= sysfs_emit(buf
, "%u\n", *data
);
627 len
= sysfs_emit(buf
, "%u\n", be16_to_cpup((__be16
*)data
));
630 len
= sysfs_emit(buf
, "%u\n", be32_to_cpup((__be32
*)data
));
633 len
= sysfs_emit(buf
, "%llu\n", be64_to_cpup((__be64
*)data
));
643 static PORT_PMA_ATTR(symbol_error
, 0, 16, 32);
644 static PORT_PMA_ATTR(link_error_recovery
, 1, 8, 48);
645 static PORT_PMA_ATTR(link_downed
, 2, 8, 56);
646 static PORT_PMA_ATTR(port_rcv_errors
, 3, 16, 64);
647 static PORT_PMA_ATTR(port_rcv_remote_physical_errors
, 4, 16, 80);
648 static PORT_PMA_ATTR(port_rcv_switch_relay_errors
, 5, 16, 96);
649 static PORT_PMA_ATTR(port_xmit_discards
, 6, 16, 112);
650 static PORT_PMA_ATTR(port_xmit_constraint_errors
, 7, 8, 128);
651 static PORT_PMA_ATTR(port_rcv_constraint_errors
, 8, 8, 136);
652 static PORT_PMA_ATTR(local_link_integrity_errors
, 9, 4, 152);
653 static PORT_PMA_ATTR(excessive_buffer_overrun_errors
, 10, 4, 156);
654 static PORT_PMA_ATTR(VL15_dropped
, 11, 16, 176);
655 static PORT_PMA_ATTR(port_xmit_data
, 12, 32, 192);
656 static PORT_PMA_ATTR(port_rcv_data
, 13, 32, 224);
657 static PORT_PMA_ATTR(port_xmit_packets
, 14, 32, 256);
658 static PORT_PMA_ATTR(port_rcv_packets
, 15, 32, 288);
659 static PORT_PMA_ATTR(port_xmit_wait
, 0, 32, 320);
662 * Counters added by extended set
664 static PORT_PMA_ATTR_EXT(port_xmit_data
, 64, 64);
665 static PORT_PMA_ATTR_EXT(port_rcv_data
, 64, 128);
666 static PORT_PMA_ATTR_EXT(port_xmit_packets
, 64, 192);
667 static PORT_PMA_ATTR_EXT(port_rcv_packets
, 64, 256);
668 static PORT_PMA_ATTR_EXT(unicast_xmit_packets
, 64, 320);
669 static PORT_PMA_ATTR_EXT(unicast_rcv_packets
, 64, 384);
670 static PORT_PMA_ATTR_EXT(multicast_xmit_packets
, 64, 448);
671 static PORT_PMA_ATTR_EXT(multicast_rcv_packets
, 64, 512);
673 static struct attribute
*pma_attrs
[] = {
674 &port_pma_attr_symbol_error
.attr
.attr
,
675 &port_pma_attr_link_error_recovery
.attr
.attr
,
676 &port_pma_attr_link_downed
.attr
.attr
,
677 &port_pma_attr_port_rcv_errors
.attr
.attr
,
678 &port_pma_attr_port_rcv_remote_physical_errors
.attr
.attr
,
679 &port_pma_attr_port_rcv_switch_relay_errors
.attr
.attr
,
680 &port_pma_attr_port_xmit_discards
.attr
.attr
,
681 &port_pma_attr_port_xmit_constraint_errors
.attr
.attr
,
682 &port_pma_attr_port_rcv_constraint_errors
.attr
.attr
,
683 &port_pma_attr_local_link_integrity_errors
.attr
.attr
,
684 &port_pma_attr_excessive_buffer_overrun_errors
.attr
.attr
,
685 &port_pma_attr_VL15_dropped
.attr
.attr
,
686 &port_pma_attr_port_xmit_data
.attr
.attr
,
687 &port_pma_attr_port_rcv_data
.attr
.attr
,
688 &port_pma_attr_port_xmit_packets
.attr
.attr
,
689 &port_pma_attr_port_rcv_packets
.attr
.attr
,
690 &port_pma_attr_port_xmit_wait
.attr
.attr
,
694 static struct attribute
*pma_attrs_ext
[] = {
695 &port_pma_attr_symbol_error
.attr
.attr
,
696 &port_pma_attr_link_error_recovery
.attr
.attr
,
697 &port_pma_attr_link_downed
.attr
.attr
,
698 &port_pma_attr_port_rcv_errors
.attr
.attr
,
699 &port_pma_attr_port_rcv_remote_physical_errors
.attr
.attr
,
700 &port_pma_attr_port_rcv_switch_relay_errors
.attr
.attr
,
701 &port_pma_attr_port_xmit_discards
.attr
.attr
,
702 &port_pma_attr_port_xmit_constraint_errors
.attr
.attr
,
703 &port_pma_attr_port_rcv_constraint_errors
.attr
.attr
,
704 &port_pma_attr_local_link_integrity_errors
.attr
.attr
,
705 &port_pma_attr_excessive_buffer_overrun_errors
.attr
.attr
,
706 &port_pma_attr_VL15_dropped
.attr
.attr
,
707 &port_pma_attr_ext_port_xmit_data
.attr
.attr
,
708 &port_pma_attr_ext_port_rcv_data
.attr
.attr
,
709 &port_pma_attr_ext_port_xmit_packets
.attr
.attr
,
710 &port_pma_attr_port_xmit_wait
.attr
.attr
,
711 &port_pma_attr_ext_port_rcv_packets
.attr
.attr
,
712 &port_pma_attr_ext_unicast_rcv_packets
.attr
.attr
,
713 &port_pma_attr_ext_unicast_xmit_packets
.attr
.attr
,
714 &port_pma_attr_ext_multicast_rcv_packets
.attr
.attr
,
715 &port_pma_attr_ext_multicast_xmit_packets
.attr
.attr
,
719 static struct attribute
*pma_attrs_noietf
[] = {
720 &port_pma_attr_symbol_error
.attr
.attr
,
721 &port_pma_attr_link_error_recovery
.attr
.attr
,
722 &port_pma_attr_link_downed
.attr
.attr
,
723 &port_pma_attr_port_rcv_errors
.attr
.attr
,
724 &port_pma_attr_port_rcv_remote_physical_errors
.attr
.attr
,
725 &port_pma_attr_port_rcv_switch_relay_errors
.attr
.attr
,
726 &port_pma_attr_port_xmit_discards
.attr
.attr
,
727 &port_pma_attr_port_xmit_constraint_errors
.attr
.attr
,
728 &port_pma_attr_port_rcv_constraint_errors
.attr
.attr
,
729 &port_pma_attr_local_link_integrity_errors
.attr
.attr
,
730 &port_pma_attr_excessive_buffer_overrun_errors
.attr
.attr
,
731 &port_pma_attr_VL15_dropped
.attr
.attr
,
732 &port_pma_attr_ext_port_xmit_data
.attr
.attr
,
733 &port_pma_attr_ext_port_rcv_data
.attr
.attr
,
734 &port_pma_attr_ext_port_xmit_packets
.attr
.attr
,
735 &port_pma_attr_ext_port_rcv_packets
.attr
.attr
,
736 &port_pma_attr_port_xmit_wait
.attr
.attr
,
740 static const struct attribute_group pma_group
= {
745 static const struct attribute_group pma_group_ext
= {
747 .attrs
= pma_attrs_ext
750 static const struct attribute_group pma_group_noietf
= {
752 .attrs
= pma_attrs_noietf
755 static void ib_port_release(struct kobject
*kobj
)
757 struct ib_port
*port
= container_of(kobj
, struct ib_port
, kobj
);
760 for (i
= 0; i
!= ARRAY_SIZE(port
->groups
); i
++)
761 kfree(port
->groups
[i
].attrs
);
762 if (port
->hw_stats_data
)
763 rdma_free_hw_stats_struct(port
->hw_stats_data
->stats
);
764 kfree(port
->hw_stats_data
);
768 static void ib_port_gid_attr_release(struct kobject
*kobj
)
770 struct gid_attr_group
*gid_attr_group
=
771 container_of(kobj
, struct gid_attr_group
, kobj
);
774 for (i
= 0; i
!= ARRAY_SIZE(gid_attr_group
->groups
); i
++)
775 kfree(gid_attr_group
->groups
[i
].attrs
);
776 kfree(gid_attr_group
);
779 static struct kobj_type port_type
= {
780 .release
= ib_port_release
,
781 .sysfs_ops
= &port_sysfs_ops
,
782 .default_groups
= port_default_groups
,
785 static struct kobj_type gid_attr_type
= {
786 .sysfs_ops
= &gid_attr_sysfs_ops
,
787 .release
= ib_port_gid_attr_release
791 * Figure out which counter table to use depending on
792 * the device capabilities.
794 static const struct attribute_group
*get_counter_table(struct ib_device
*dev
,
797 struct ib_class_port_info cpi
;
799 if (get_perf_mad(dev
, port_num
, IB_PMA_CLASS_PORT_INFO
,
800 &cpi
, 40, sizeof(cpi
)) >= 0) {
801 if (cpi
.capability_mask
& IB_PMA_CLASS_CAP_EXT_WIDTH
)
802 /* We have extended counters */
803 return &pma_group_ext
;
805 if (cpi
.capability_mask
& IB_PMA_CLASS_CAP_EXT_WIDTH_NOIETF
)
806 /* But not the IETF ones */
807 return &pma_group_noietf
;
810 /* Fall back to normal counters */
814 static int update_hw_stats(struct ib_device
*dev
, struct rdma_hw_stats
*stats
,
815 u32 port_num
, int index
)
819 if (time_is_after_eq_jiffies(stats
->timestamp
+ stats
->lifespan
))
821 ret
= dev
->ops
.get_hw_stats(dev
, stats
, port_num
, index
);
824 if (ret
== stats
->num_counters
)
825 stats
->timestamp
= jiffies
;
830 static int print_hw_stat(struct ib_device
*dev
, int port_num
,
831 struct rdma_hw_stats
*stats
, int index
, char *buf
)
833 u64 v
= rdma_counter_get_hwstat_value(dev
, port_num
, index
);
835 return sysfs_emit(buf
, "%llu\n", stats
->value
[index
] + v
);
838 static ssize_t
show_hw_stats(struct ib_device
*ibdev
,
839 struct rdma_hw_stats
*stats
, unsigned int index
,
840 unsigned int port_num
, char *buf
)
844 mutex_lock(&stats
->lock
);
845 ret
= update_hw_stats(ibdev
, stats
, port_num
, index
);
848 ret
= print_hw_stat(ibdev
, port_num
, stats
, index
, buf
);
850 mutex_unlock(&stats
->lock
);
855 static ssize_t
show_stats_lifespan(struct ib_device
*ibdev
,
856 struct rdma_hw_stats
*stats
,
857 unsigned int index
, unsigned int port_num
,
862 mutex_lock(&stats
->lock
);
863 msecs
= jiffies_to_msecs(stats
->lifespan
);
864 mutex_unlock(&stats
->lock
);
866 return sysfs_emit(buf
, "%d\n", msecs
);
869 static ssize_t
set_stats_lifespan(struct ib_device
*ibdev
,
870 struct rdma_hw_stats
*stats
,
871 unsigned int index
, unsigned int port_num
,
872 const char *buf
, size_t count
)
878 ret
= kstrtoint(buf
, 10, &msecs
);
881 if (msecs
< 0 || msecs
> 10000)
883 jiffies
= msecs_to_jiffies(msecs
);
885 mutex_lock(&stats
->lock
);
886 stats
->lifespan
= jiffies
;
887 mutex_unlock(&stats
->lock
);
892 static struct hw_stats_device_data
*
893 alloc_hw_stats_device(struct ib_device
*ibdev
)
895 struct hw_stats_device_data
*data
;
896 struct rdma_hw_stats
*stats
;
898 if (!ibdev
->ops
.alloc_hw_device_stats
)
899 return ERR_PTR(-EOPNOTSUPP
);
900 stats
= ibdev
->ops
.alloc_hw_device_stats(ibdev
);
902 return ERR_PTR(-ENOMEM
);
903 if (!stats
->descs
|| stats
->num_counters
<= 0)
907 * Two extra attribue elements here, one for the lifespan entry and
908 * one to NULL terminate the list for the sysfs core code
910 data
= kzalloc(struct_size(data
, attrs
, size_add(stats
->num_counters
, 1)),
914 data
->group
.attrs
= kcalloc(stats
->num_counters
+ 2,
915 sizeof(*data
->group
.attrs
), GFP_KERNEL
);
916 if (!data
->group
.attrs
)
919 data
->group
.name
= "hw_counters";
926 rdma_free_hw_stats_struct(stats
);
927 return ERR_PTR(-ENOMEM
);
930 void ib_device_release_hw_stats(struct hw_stats_device_data
*data
)
932 kfree(data
->group
.attrs
);
933 rdma_free_hw_stats_struct(data
->stats
);
937 int ib_setup_device_attrs(struct ib_device
*ibdev
)
939 struct hw_stats_device_attribute
*attr
;
940 struct hw_stats_device_data
*data
;
941 bool opstat_skipped
= false;
944 data
= alloc_hw_stats_device(ibdev
);
946 if (PTR_ERR(data
) == -EOPNOTSUPP
)
948 return PTR_ERR(data
);
950 ibdev
->hw_stats_data
= data
;
952 ret
= ibdev
->ops
.get_hw_stats(ibdev
, data
->stats
, 0,
953 data
->stats
->num_counters
);
954 if (ret
!= data
->stats
->num_counters
) {
955 if (WARN_ON(ret
>= 0))
960 data
->stats
->timestamp
= jiffies
;
962 for (i
= 0; i
< data
->stats
->num_counters
; i
++) {
963 if (data
->stats
->descs
[i
].flags
& IB_STAT_FLAG_OPTIONAL
) {
964 opstat_skipped
= true;
968 WARN_ON(opstat_skipped
);
969 attr
= &data
->attrs
[pos
];
970 sysfs_attr_init(&attr
->attr
.attr
);
971 attr
->attr
.attr
.name
= data
->stats
->descs
[i
].name
;
972 attr
->attr
.attr
.mode
= 0444;
973 attr
->attr
.show
= hw_stat_device_show
;
974 attr
->show
= show_hw_stats
;
975 data
->group
.attrs
[pos
] = &attr
->attr
.attr
;
979 attr
= &data
->attrs
[pos
];
980 sysfs_attr_init(&attr
->attr
.attr
);
981 attr
->attr
.attr
.name
= "lifespan";
982 attr
->attr
.attr
.mode
= 0644;
983 attr
->attr
.show
= hw_stat_device_show
;
984 attr
->show
= show_stats_lifespan
;
985 attr
->attr
.store
= hw_stat_device_store
;
986 attr
->store
= set_stats_lifespan
;
987 data
->group
.attrs
[pos
] = &attr
->attr
.attr
;
988 for (i
= 0; i
!= ARRAY_SIZE(ibdev
->groups
); i
++)
989 if (!ibdev
->groups
[i
]) {
990 ibdev
->groups
[i
] = &data
->group
;
993 WARN(true, "struct ib_device->groups is too small");
997 static struct hw_stats_port_data
*
998 alloc_hw_stats_port(struct ib_port
*port
, struct attribute_group
*group
)
1000 struct ib_device
*ibdev
= port
->ibdev
;
1001 struct hw_stats_port_data
*data
;
1002 struct rdma_hw_stats
*stats
;
1004 if (!ibdev
->ops
.alloc_hw_port_stats
)
1005 return ERR_PTR(-EOPNOTSUPP
);
1006 stats
= ibdev
->ops
.alloc_hw_port_stats(port
->ibdev
, port
->port_num
);
1008 return ERR_PTR(-ENOMEM
);
1009 if (!stats
->descs
|| stats
->num_counters
<= 0)
1010 goto err_free_stats
;
1013 * Two extra attribue elements here, one for the lifespan entry and
1014 * one to NULL terminate the list for the sysfs core code
1016 data
= kzalloc(struct_size(data
, attrs
, size_add(stats
->num_counters
, 1)),
1019 goto err_free_stats
;
1020 group
->attrs
= kcalloc(stats
->num_counters
+ 2,
1021 sizeof(*group
->attrs
), GFP_KERNEL
);
1025 group
->name
= "hw_counters";
1026 data
->stats
= stats
;
1032 rdma_free_hw_stats_struct(stats
);
1033 return ERR_PTR(-ENOMEM
);
1036 static int setup_hw_port_stats(struct ib_port
*port
,
1037 struct attribute_group
*group
)
1039 struct hw_stats_port_attribute
*attr
;
1040 struct hw_stats_port_data
*data
;
1041 bool opstat_skipped
= false;
1042 int i
, ret
, pos
= 0;
1044 data
= alloc_hw_stats_port(port
, group
);
1046 return PTR_ERR(data
);
1048 ret
= port
->ibdev
->ops
.get_hw_stats(port
->ibdev
, data
->stats
,
1050 data
->stats
->num_counters
);
1051 if (ret
!= data
->stats
->num_counters
) {
1052 if (WARN_ON(ret
>= 0))
1057 data
->stats
->timestamp
= jiffies
;
1059 for (i
= 0; i
< data
->stats
->num_counters
; i
++) {
1060 if (data
->stats
->descs
[i
].flags
& IB_STAT_FLAG_OPTIONAL
) {
1061 opstat_skipped
= true;
1065 WARN_ON(opstat_skipped
);
1066 attr
= &data
->attrs
[pos
];
1067 sysfs_attr_init(&attr
->attr
.attr
);
1068 attr
->attr
.attr
.name
= data
->stats
->descs
[i
].name
;
1069 attr
->attr
.attr
.mode
= 0444;
1070 attr
->attr
.show
= hw_stat_port_show
;
1071 attr
->show
= show_hw_stats
;
1072 group
->attrs
[pos
] = &attr
->attr
.attr
;
1076 attr
= &data
->attrs
[pos
];
1077 sysfs_attr_init(&attr
->attr
.attr
);
1078 attr
->attr
.attr
.name
= "lifespan";
1079 attr
->attr
.attr
.mode
= 0644;
1080 attr
->attr
.show
= hw_stat_port_show
;
1081 attr
->show
= show_stats_lifespan
;
1082 attr
->attr
.store
= hw_stat_port_store
;
1083 attr
->store
= set_stats_lifespan
;
1084 group
->attrs
[pos
] = &attr
->attr
.attr
;
1086 port
->hw_stats_data
= data
;
1090 struct rdma_hw_stats
*ib_get_hw_stats_port(struct ib_device
*ibdev
,
1093 if (!ibdev
->port_data
|| !rdma_is_port_valid(ibdev
, port_num
) ||
1094 !ibdev
->port_data
[port_num
].sysfs
->hw_stats_data
)
1096 return ibdev
->port_data
[port_num
].sysfs
->hw_stats_data
->stats
;
1100 alloc_port_table_group(const char *name
, struct attribute_group
*group
,
1101 struct port_table_attribute
*attrs
, size_t num
,
1102 ssize_t (*show
)(struct ib_device
*ibdev
, u32 port_num
,
1103 struct ib_port_attribute
*, char *buf
))
1105 struct attribute
**attr_list
;
1108 attr_list
= kcalloc(num
+ 1, sizeof(*attr_list
), GFP_KERNEL
);
1112 for (i
= 0; i
< num
; i
++) {
1113 struct port_table_attribute
*element
= &attrs
[i
];
1115 if (snprintf(element
->name
, sizeof(element
->name
), "%d", i
) >=
1116 sizeof(element
->name
))
1119 sysfs_attr_init(&element
->attr
.attr
);
1120 element
->attr
.attr
.name
= element
->name
;
1121 element
->attr
.attr
.mode
= 0444;
1122 element
->attr
.show
= show
;
1125 attr_list
[i
] = &element
->attr
.attr
;
1128 group
->attrs
= attr_list
;
1137 * ibp0s9/ports/XX/gid_attrs/{ndevs,types}/YYY
1138 * YYY is the gid table index in decimal
1140 static int setup_gid_attrs(struct ib_port
*port
,
1141 const struct ib_port_attr
*attr
)
1143 struct gid_attr_group
*gid_attr_group
;
1146 gid_attr_group
= kzalloc(struct_size(gid_attr_group
, attrs_list
,
1147 size_mul(attr
->gid_tbl_len
, 2)),
1149 if (!gid_attr_group
)
1151 gid_attr_group
->port
= port
;
1152 kobject_init(&gid_attr_group
->kobj
, &gid_attr_type
);
1154 ret
= alloc_port_table_group("ndevs", &gid_attr_group
->groups
[0],
1155 gid_attr_group
->attrs_list
,
1157 show_port_gid_attr_ndev
);
1160 gid_attr_group
->groups_list
[0] = &gid_attr_group
->groups
[0];
1162 ret
= alloc_port_table_group(
1163 "types", &gid_attr_group
->groups
[1],
1164 gid_attr_group
->attrs_list
+ attr
->gid_tbl_len
,
1165 attr
->gid_tbl_len
, show_port_gid_attr_gid_type
);
1168 gid_attr_group
->groups_list
[1] = &gid_attr_group
->groups
[1];
1170 ret
= kobject_add(&gid_attr_group
->kobj
, &port
->kobj
, "gid_attrs");
1173 ret
= sysfs_create_groups(&gid_attr_group
->kobj
,
1174 gid_attr_group
->groups_list
);
1177 port
->gid_attr_group
= gid_attr_group
;
1181 kobject_del(&gid_attr_group
->kobj
);
1183 kobject_put(&gid_attr_group
->kobj
);
1187 static void destroy_gid_attrs(struct ib_port
*port
)
1189 struct gid_attr_group
*gid_attr_group
= port
->gid_attr_group
;
1191 if (!gid_attr_group
)
1193 sysfs_remove_groups(&gid_attr_group
->kobj
, gid_attr_group
->groups_list
);
1194 kobject_del(&gid_attr_group
->kobj
);
1195 kobject_put(&gid_attr_group
->kobj
);
1200 * ibp0s9/ports/XX/{gids,pkeys,counters}/YYY
1202 static struct ib_port
*setup_port(struct ib_core_device
*coredev
, int port_num
,
1203 const struct ib_port_attr
*attr
)
1205 struct ib_device
*device
= rdma_device_to_ibdev(&coredev
->dev
);
1206 bool is_full_dev
= &device
->coredev
== coredev
;
1207 const struct attribute_group
**cur_group
;
1211 p
= kvzalloc(struct_size(p
, attrs_list
,
1212 size_add(attr
->gid_tbl_len
, attr
->pkey_tbl_len
)),
1215 return ERR_PTR(-ENOMEM
);
1217 p
->port_num
= port_num
;
1218 kobject_init(&p
->kobj
, &port_type
);
1220 if (device
->port_data
&& is_full_dev
)
1221 device
->port_data
[port_num
].sysfs
= p
;
1223 cur_group
= p
->groups_list
;
1224 ret
= alloc_port_table_group("gids", &p
->groups
[0], p
->attrs_list
,
1225 attr
->gid_tbl_len
, show_port_gid
);
1228 *cur_group
++ = &p
->groups
[0];
1230 if (attr
->pkey_tbl_len
) {
1231 ret
= alloc_port_table_group("pkeys", &p
->groups
[1],
1232 p
->attrs_list
+ attr
->gid_tbl_len
,
1233 attr
->pkey_tbl_len
, show_port_pkey
);
1236 *cur_group
++ = &p
->groups
[1];
1240 * If port == 0, it means hw_counters are per device and not per
1241 * port, so holder should be device. Therefore skip per port
1242 * counter initialization.
1244 if (port_num
&& is_full_dev
) {
1245 ret
= setup_hw_port_stats(p
, &p
->groups
[2]);
1246 if (ret
&& ret
!= -EOPNOTSUPP
)
1249 *cur_group
++ = &p
->groups
[2];
1252 if (device
->ops
.process_mad
&& is_full_dev
)
1253 *cur_group
++ = get_counter_table(device
, port_num
);
1255 ret
= kobject_add(&p
->kobj
, coredev
->ports_kobj
, "%d", port_num
);
1258 ret
= sysfs_create_groups(&p
->kobj
, p
->groups_list
);
1262 ret
= sysfs_create_groups(&p
->kobj
, device
->ops
.port_groups
);
1267 list_add_tail(&p
->kobj
.entry
, &coredev
->port_list
);
1271 sysfs_remove_groups(&p
->kobj
, p
->groups_list
);
1273 kobject_del(&p
->kobj
);
1275 if (device
->port_data
&& is_full_dev
)
1276 device
->port_data
[port_num
].sysfs
= NULL
;
1277 kobject_put(&p
->kobj
);
1278 return ERR_PTR(ret
);
1281 static void destroy_port(struct ib_core_device
*coredev
, struct ib_port
*port
)
1283 bool is_full_dev
= &port
->ibdev
->coredev
== coredev
;
1285 list_del(&port
->kobj
.entry
);
1287 sysfs_remove_groups(&port
->kobj
, port
->ibdev
->ops
.port_groups
);
1289 sysfs_remove_groups(&port
->kobj
, port
->groups_list
);
1290 kobject_del(&port
->kobj
);
1292 if (port
->ibdev
->port_data
&&
1293 port
->ibdev
->port_data
[port
->port_num
].sysfs
== port
)
1294 port
->ibdev
->port_data
[port
->port_num
].sysfs
= NULL
;
1296 kobject_put(&port
->kobj
);
1299 static const char *node_type_string(int node_type
)
1301 switch (node_type
) {
1302 case RDMA_NODE_IB_CA
:
1304 case RDMA_NODE_IB_SWITCH
:
1306 case RDMA_NODE_IB_ROUTER
:
1308 case RDMA_NODE_RNIC
:
1310 case RDMA_NODE_USNIC
:
1312 case RDMA_NODE_USNIC_UDP
:
1314 case RDMA_NODE_UNSPECIFIED
:
1315 return "unspecified";
1320 static ssize_t
node_type_show(struct device
*device
,
1321 struct device_attribute
*attr
, char *buf
)
1323 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1325 return sysfs_emit(buf
, "%u: %s\n", dev
->node_type
,
1326 node_type_string(dev
->node_type
));
1328 static DEVICE_ATTR_RO(node_type
);
1330 static ssize_t
sys_image_guid_show(struct device
*device
,
1331 struct device_attribute
*dev_attr
, char *buf
)
1333 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1334 __be16
*guid
= (__be16
*)&dev
->attrs
.sys_image_guid
;
1336 return sysfs_emit(buf
, "%04x:%04x:%04x:%04x\n",
1337 be16_to_cpu(guid
[0]),
1338 be16_to_cpu(guid
[1]),
1339 be16_to_cpu(guid
[2]),
1340 be16_to_cpu(guid
[3]));
1342 static DEVICE_ATTR_RO(sys_image_guid
);
1344 static ssize_t
node_guid_show(struct device
*device
,
1345 struct device_attribute
*attr
, char *buf
)
1347 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1348 __be16
*node_guid
= (__be16
*)&dev
->node_guid
;
1350 return sysfs_emit(buf
, "%04x:%04x:%04x:%04x\n",
1351 be16_to_cpu(node_guid
[0]),
1352 be16_to_cpu(node_guid
[1]),
1353 be16_to_cpu(node_guid
[2]),
1354 be16_to_cpu(node_guid
[3]));
1356 static DEVICE_ATTR_RO(node_guid
);
1358 static ssize_t
node_desc_show(struct device
*device
,
1359 struct device_attribute
*attr
, char *buf
)
1361 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1363 return sysfs_emit(buf
, "%.64s\n", dev
->node_desc
);
1366 static ssize_t
node_desc_store(struct device
*device
,
1367 struct device_attribute
*attr
,
1368 const char *buf
, size_t count
)
1370 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1371 struct ib_device_modify desc
= {};
1374 if (!dev
->ops
.modify_device
)
1377 memcpy(desc
.node_desc
, buf
, min_t(int, count
, IB_DEVICE_NODE_DESC_MAX
));
1378 ret
= ib_modify_device(dev
, IB_DEVICE_MODIFY_NODE_DESC
, &desc
);
1384 static DEVICE_ATTR_RW(node_desc
);
1386 static ssize_t
fw_ver_show(struct device
*device
, struct device_attribute
*attr
,
1389 struct ib_device
*dev
= rdma_device_to_ibdev(device
);
1390 char version
[IB_FW_VERSION_NAME_MAX
] = {};
1392 ib_get_device_fw_str(dev
, version
);
1394 return sysfs_emit(buf
, "%s\n", version
);
1396 static DEVICE_ATTR_RO(fw_ver
);
1398 static struct attribute
*ib_dev_attrs
[] = {
1399 &dev_attr_node_type
.attr
,
1400 &dev_attr_node_guid
.attr
,
1401 &dev_attr_sys_image_guid
.attr
,
1402 &dev_attr_fw_ver
.attr
,
1403 &dev_attr_node_desc
.attr
,
1407 const struct attribute_group ib_dev_attr_group
= {
1408 .attrs
= ib_dev_attrs
,
1411 void ib_free_port_attrs(struct ib_core_device
*coredev
)
1413 struct kobject
*p
, *t
;
1415 list_for_each_entry_safe(p
, t
, &coredev
->port_list
, entry
) {
1416 struct ib_port
*port
= container_of(p
, struct ib_port
, kobj
);
1418 destroy_gid_attrs(port
);
1419 destroy_port(coredev
, port
);
1422 kobject_put(coredev
->ports_kobj
);
1425 int ib_setup_port_attrs(struct ib_core_device
*coredev
)
1427 struct ib_device
*device
= rdma_device_to_ibdev(&coredev
->dev
);
1431 coredev
->ports_kobj
= kobject_create_and_add("ports",
1432 &coredev
->dev
.kobj
);
1433 if (!coredev
->ports_kobj
)
1436 rdma_for_each_port (device
, port_num
) {
1437 struct ib_port_attr attr
;
1438 struct ib_port
*port
;
1440 ret
= ib_query_port(device
, port_num
, &attr
);
1444 port
= setup_port(coredev
, port_num
, &attr
);
1446 ret
= PTR_ERR(port
);
1450 ret
= setup_gid_attrs(port
, &attr
);
1457 ib_free_port_attrs(coredev
);
1462 * ib_port_register_client_groups - Add an ib_client's attributes to the port
1464 * @ibdev: IB device to add counters
1465 * @port_num: valid port number
1466 * @groups: Group list of attributes
1468 * Do not use. Only for legacy sysfs compatibility.
1470 int ib_port_register_client_groups(struct ib_device
*ibdev
, u32 port_num
,
1471 const struct attribute_group
**groups
)
1473 return sysfs_create_groups(&ibdev
->port_data
[port_num
].sysfs
->kobj
,
1476 EXPORT_SYMBOL(ib_port_register_client_groups
);
1478 void ib_port_unregister_client_groups(struct ib_device
*ibdev
, u32 port_num
,
1479 const struct attribute_group
**groups
)
1481 return sysfs_remove_groups(&ibdev
->port_data
[port_num
].sysfs
->kobj
,
1484 EXPORT_SYMBOL(ib_port_unregister_client_groups
);