.. | .. |
---|
43 | 43 | #include <rdma/ib_mad.h> |
---|
44 | 44 | #include <rdma/ib_pma.h> |
---|
45 | 45 | #include <rdma/ib_cache.h> |
---|
| 46 | +#include <rdma/rdma_counter.h> |
---|
46 | 47 | |
---|
47 | 48 | struct ib_port; |
---|
48 | 49 | |
---|
.. | .. |
---|
57 | 58 | struct ib_device *ibdev; |
---|
58 | 59 | struct gid_attr_group *gid_attr_group; |
---|
59 | 60 | struct attribute_group gid_group; |
---|
60 | | - struct attribute_group pkey_group; |
---|
61 | | - struct attribute_group *pma_table; |
---|
| 61 | + struct attribute_group *pkey_group; |
---|
| 62 | + const struct attribute_group *pma_table; |
---|
62 | 63 | struct attribute_group *hw_stats_ag; |
---|
63 | 64 | struct rdma_hw_stats *hw_stats; |
---|
64 | 65 | u8 port_num; |
---|
.. | .. |
---|
288 | 289 | ib_width_enum_to_int(attr.active_width), speed); |
---|
289 | 290 | } |
---|
290 | 291 | |
---|
| 292 | +static const char *phys_state_to_str(enum ib_port_phys_state phys_state) |
---|
| 293 | +{ |
---|
| 294 | + static const char * phys_state_str[] = { |
---|
| 295 | + "<unknown>", |
---|
| 296 | + "Sleep", |
---|
| 297 | + "Polling", |
---|
| 298 | + "Disabled", |
---|
| 299 | + "PortConfigurationTraining", |
---|
| 300 | + "LinkUp", |
---|
| 301 | + "LinkErrorRecovery", |
---|
| 302 | + "Phy Test", |
---|
| 303 | + }; |
---|
| 304 | + |
---|
| 305 | + if (phys_state < ARRAY_SIZE(phys_state_str)) |
---|
| 306 | + return phys_state_str[phys_state]; |
---|
| 307 | + return "<unknown>"; |
---|
| 308 | +} |
---|
| 309 | + |
---|
291 | 310 | static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused, |
---|
292 | 311 | char *buf) |
---|
293 | 312 | { |
---|
.. | .. |
---|
299 | 318 | if (ret) |
---|
300 | 319 | return ret; |
---|
301 | 320 | |
---|
302 | | - switch (attr.phys_state) { |
---|
303 | | - case 1: return sprintf(buf, "1: Sleep\n"); |
---|
304 | | - case 2: return sprintf(buf, "2: Polling\n"); |
---|
305 | | - case 3: return sprintf(buf, "3: Disabled\n"); |
---|
306 | | - case 4: return sprintf(buf, "4: PortConfigurationTraining\n"); |
---|
307 | | - case 5: return sprintf(buf, "5: LinkUp\n"); |
---|
308 | | - case 6: return sprintf(buf, "6: LinkErrorRecovery\n"); |
---|
309 | | - case 7: return sprintf(buf, "7: Phy Test\n"); |
---|
310 | | - default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state); |
---|
311 | | - } |
---|
| 321 | + return sprintf(buf, "%d: %s\n", attr.phys_state, |
---|
| 322 | + phys_state_to_str(attr.phys_state)); |
---|
312 | 323 | } |
---|
313 | 324 | |
---|
314 | 325 | static ssize_t link_layer_show(struct ib_port *p, struct port_attribute *unused, |
---|
.. | .. |
---|
349 | 360 | |
---|
350 | 361 | static size_t print_ndev(const struct ib_gid_attr *gid_attr, char *buf) |
---|
351 | 362 | { |
---|
352 | | - if (!gid_attr->ndev) |
---|
353 | | - return -EINVAL; |
---|
| 363 | + struct net_device *ndev; |
---|
| 364 | + size_t ret = -EINVAL; |
---|
354 | 365 | |
---|
355 | | - return sprintf(buf, "%s\n", gid_attr->ndev->name); |
---|
| 366 | + rcu_read_lock(); |
---|
| 367 | + ndev = rcu_dereference(gid_attr->ndev); |
---|
| 368 | + if (ndev) |
---|
| 369 | + ret = sprintf(buf, "%s\n", ndev->name); |
---|
| 370 | + rcu_read_unlock(); |
---|
| 371 | + return ret; |
---|
356 | 372 | } |
---|
357 | 373 | |
---|
358 | 374 | static size_t print_gid_type(const struct ib_gid_attr *gid_attr, char *buf) |
---|
.. | .. |
---|
371 | 387 | |
---|
372 | 388 | gid_attr = rdma_get_gid_attr(p->ibdev, p->port_num, tab_attr->index); |
---|
373 | 389 | if (IS_ERR(gid_attr)) |
---|
374 | | - return PTR_ERR(gid_attr); |
---|
| 390 | + /* -EINVAL is returned for user space compatibility reasons. */ |
---|
| 391 | + return -EINVAL; |
---|
375 | 392 | |
---|
376 | 393 | ret = print(gid_attr, buf); |
---|
377 | 394 | rdma_put_gid_attr(gid_attr); |
---|
.. | .. |
---|
462 | 479 | u16 out_mad_pkey_index = 0; |
---|
463 | 480 | ssize_t ret; |
---|
464 | 481 | |
---|
465 | | - if (!dev->process_mad) |
---|
| 482 | + if (!dev->ops.process_mad) |
---|
466 | 483 | return -ENOSYS; |
---|
467 | 484 | |
---|
468 | | - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); |
---|
469 | | - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); |
---|
| 485 | + in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); |
---|
| 486 | + out_mad = kzalloc(sizeof(*out_mad), GFP_KERNEL); |
---|
470 | 487 | if (!in_mad || !out_mad) { |
---|
471 | 488 | ret = -ENOMEM; |
---|
472 | 489 | goto out; |
---|
.. | .. |
---|
481 | 498 | if (attr != IB_PMA_CLASS_PORT_INFO) |
---|
482 | 499 | in_mad->data[41] = port_num; /* PortSelect field */ |
---|
483 | 500 | |
---|
484 | | - if ((dev->process_mad(dev, IB_MAD_IGNORE_MKEY, |
---|
485 | | - port_num, NULL, NULL, |
---|
486 | | - (const struct ib_mad_hdr *)in_mad, mad_size, |
---|
487 | | - (struct ib_mad_hdr *)out_mad, &mad_size, |
---|
488 | | - &out_mad_pkey_index) & |
---|
| 501 | + if ((dev->ops.process_mad(dev, IB_MAD_IGNORE_MKEY, port_num, NULL, NULL, |
---|
| 502 | + in_mad, out_mad, &mad_size, |
---|
| 503 | + &out_mad_pkey_index) & |
---|
489 | 504 | (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) != |
---|
490 | 505 | (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) { |
---|
491 | 506 | ret = -EINVAL; |
---|
.. | .. |
---|
639 | 654 | NULL |
---|
640 | 655 | }; |
---|
641 | 656 | |
---|
642 | | -static struct attribute_group pma_group = { |
---|
| 657 | +static const struct attribute_group pma_group = { |
---|
643 | 658 | .name = "counters", |
---|
644 | 659 | .attrs = pma_attrs |
---|
645 | 660 | }; |
---|
646 | 661 | |
---|
647 | | -static struct attribute_group pma_group_ext = { |
---|
| 662 | +static const struct attribute_group pma_group_ext = { |
---|
648 | 663 | .name = "counters", |
---|
649 | 664 | .attrs = pma_attrs_ext |
---|
650 | 665 | }; |
---|
651 | 666 | |
---|
652 | | -static struct attribute_group pma_group_noietf = { |
---|
| 667 | +static const struct attribute_group pma_group_noietf = { |
---|
653 | 668 | .name = "counters", |
---|
654 | 669 | .attrs = pma_attrs_noietf |
---|
655 | 670 | }; |
---|
.. | .. |
---|
667 | 682 | kfree(p->gid_group.attrs); |
---|
668 | 683 | } |
---|
669 | 684 | |
---|
670 | | - if (p->pkey_group.attrs) { |
---|
671 | | - for (i = 0; (a = p->pkey_group.attrs[i]); ++i) |
---|
672 | | - kfree(a); |
---|
| 685 | + if (p->pkey_group) { |
---|
| 686 | + if (p->pkey_group->attrs) { |
---|
| 687 | + for (i = 0; (a = p->pkey_group->attrs[i]); ++i) |
---|
| 688 | + kfree(a); |
---|
673 | 689 | |
---|
674 | | - kfree(p->pkey_group.attrs); |
---|
| 690 | + kfree(p->pkey_group->attrs); |
---|
| 691 | + } |
---|
| 692 | + |
---|
| 693 | + kfree(p->pkey_group); |
---|
| 694 | + p->pkey_group = NULL; |
---|
675 | 695 | } |
---|
676 | 696 | |
---|
677 | 697 | kfree(p); |
---|
.. | .. |
---|
759 | 779 | * Figure out which counter table to use depending on |
---|
760 | 780 | * the device capabilities. |
---|
761 | 781 | */ |
---|
762 | | -static struct attribute_group *get_counter_table(struct ib_device *dev, |
---|
763 | | - int port_num) |
---|
| 782 | +static const struct attribute_group *get_counter_table(struct ib_device *dev, |
---|
| 783 | + int port_num) |
---|
764 | 784 | { |
---|
765 | 785 | struct ib_class_port_info cpi; |
---|
766 | 786 | |
---|
.. | .. |
---|
786 | 806 | |
---|
787 | 807 | if (time_is_after_eq_jiffies(stats->timestamp + stats->lifespan)) |
---|
788 | 808 | return 0; |
---|
789 | | - ret = dev->get_hw_stats(dev, stats, port_num, index); |
---|
| 809 | + ret = dev->ops.get_hw_stats(dev, stats, port_num, index); |
---|
790 | 810 | if (ret < 0) |
---|
791 | 811 | return ret; |
---|
792 | 812 | if (ret == stats->num_counters) |
---|
.. | .. |
---|
795 | 815 | return 0; |
---|
796 | 816 | } |
---|
797 | 817 | |
---|
798 | | -static ssize_t print_hw_stat(struct rdma_hw_stats *stats, int index, char *buf) |
---|
| 818 | +static ssize_t print_hw_stat(struct ib_device *dev, int port_num, |
---|
| 819 | + struct rdma_hw_stats *stats, int index, char *buf) |
---|
799 | 820 | { |
---|
800 | | - return sprintf(buf, "%llu\n", stats->value[index]); |
---|
| 821 | + u64 v = rdma_counter_get_hwstat_value(dev, port_num, index); |
---|
| 822 | + |
---|
| 823 | + return sprintf(buf, "%llu\n", stats->value[index] + v); |
---|
801 | 824 | } |
---|
802 | 825 | |
---|
803 | 826 | static ssize_t show_hw_stats(struct kobject *kobj, struct attribute *attr, |
---|
.. | .. |
---|
823 | 846 | ret = update_hw_stats(dev, stats, hsa->port_num, hsa->index); |
---|
824 | 847 | if (ret) |
---|
825 | 848 | goto unlock; |
---|
826 | | - ret = print_hw_stat(stats, hsa->index, buf); |
---|
| 849 | + ret = print_hw_stat(dev, hsa->port_num, stats, hsa->index, buf); |
---|
827 | 850 | unlock: |
---|
828 | 851 | mutex_unlock(&stats->lock); |
---|
829 | 852 | |
---|
.. | .. |
---|
946 | 969 | struct rdma_hw_stats *stats; |
---|
947 | 970 | int i, ret; |
---|
948 | 971 | |
---|
949 | | - stats = device->alloc_hw_stats(device, port_num); |
---|
| 972 | + stats = device->ops.alloc_hw_stats(device, port_num); |
---|
950 | 973 | |
---|
951 | 974 | if (!stats) |
---|
952 | 975 | return; |
---|
.. | .. |
---|
964 | 987 | if (!hsag) |
---|
965 | 988 | goto err_free_stats; |
---|
966 | 989 | |
---|
967 | | - ret = device->get_hw_stats(device, stats, port_num, |
---|
968 | | - stats->num_counters); |
---|
| 990 | + ret = device->ops.get_hw_stats(device, stats, port_num, |
---|
| 991 | + stats->num_counters); |
---|
969 | 992 | if (ret != stats->num_counters) |
---|
970 | 993 | goto err_free_hsag; |
---|
971 | 994 | |
---|
.. | .. |
---|
994 | 1017 | goto err; |
---|
995 | 1018 | port->hw_stats_ag = hsag; |
---|
996 | 1019 | port->hw_stats = stats; |
---|
| 1020 | + if (device->port_data) |
---|
| 1021 | + device->port_data[port_num].hw_stats = stats; |
---|
997 | 1022 | } else { |
---|
998 | 1023 | struct kobject *kobj = &device->dev.kobj; |
---|
999 | 1024 | ret = sysfs_create_group(kobj, hsag); |
---|
.. | .. |
---|
1015 | 1040 | return; |
---|
1016 | 1041 | } |
---|
1017 | 1042 | |
---|
1018 | | -static int add_port(struct ib_device *device, int port_num, |
---|
1019 | | - int (*port_callback)(struct ib_device *, |
---|
1020 | | - u8, struct kobject *)) |
---|
| 1043 | +static int add_port(struct ib_core_device *coredev, int port_num) |
---|
1021 | 1044 | { |
---|
| 1045 | + struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); |
---|
| 1046 | + bool is_full_dev = &device->coredev == coredev; |
---|
1022 | 1047 | struct ib_port *p; |
---|
1023 | 1048 | struct ib_port_attr attr; |
---|
1024 | 1049 | int i; |
---|
.. | .. |
---|
1036 | 1061 | p->port_num = port_num; |
---|
1037 | 1062 | |
---|
1038 | 1063 | ret = kobject_init_and_add(&p->kobj, &port_type, |
---|
1039 | | - device->ports_parent, |
---|
| 1064 | + coredev->ports_kobj, |
---|
1040 | 1065 | "%d", port_num); |
---|
1041 | 1066 | if (ret) { |
---|
1042 | | - kfree(p); |
---|
1043 | | - return ret; |
---|
| 1067 | + goto err_put; |
---|
1044 | 1068 | } |
---|
1045 | 1069 | |
---|
1046 | 1070 | p->gid_attr_group = kzalloc(sizeof(*p->gid_attr_group), GFP_KERNEL); |
---|
.. | .. |
---|
1053 | 1077 | ret = kobject_init_and_add(&p->gid_attr_group->kobj, &gid_attr_type, |
---|
1054 | 1078 | &p->kobj, "gid_attrs"); |
---|
1055 | 1079 | if (ret) { |
---|
1056 | | - kfree(p->gid_attr_group); |
---|
1057 | | - goto err_put; |
---|
| 1080 | + goto err_put_gid_attrs; |
---|
1058 | 1081 | } |
---|
1059 | 1082 | |
---|
1060 | | - if (device->process_mad) { |
---|
| 1083 | + if (device->ops.process_mad && is_full_dev) { |
---|
1061 | 1084 | p->pma_table = get_counter_table(device, port_num); |
---|
1062 | 1085 | ret = sysfs_create_group(&p->kobj, p->pma_table); |
---|
1063 | 1086 | if (ret) |
---|
.. | .. |
---|
1101 | 1124 | if (ret) |
---|
1102 | 1125 | goto err_free_gid_type; |
---|
1103 | 1126 | |
---|
1104 | | - p->pkey_group.name = "pkeys"; |
---|
1105 | | - p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, |
---|
1106 | | - attr.pkey_tbl_len); |
---|
1107 | | - if (!p->pkey_group.attrs) { |
---|
1108 | | - ret = -ENOMEM; |
---|
1109 | | - goto err_remove_gid_type; |
---|
| 1127 | + if (attr.pkey_tbl_len) { |
---|
| 1128 | + p->pkey_group = kzalloc(sizeof(*p->pkey_group), GFP_KERNEL); |
---|
| 1129 | + if (!p->pkey_group) { |
---|
| 1130 | + ret = -ENOMEM; |
---|
| 1131 | + goto err_remove_gid_type; |
---|
| 1132 | + } |
---|
| 1133 | + |
---|
| 1134 | + p->pkey_group->name = "pkeys"; |
---|
| 1135 | + p->pkey_group->attrs = alloc_group_attrs(show_port_pkey, |
---|
| 1136 | + attr.pkey_tbl_len); |
---|
| 1137 | + if (!p->pkey_group->attrs) { |
---|
| 1138 | + ret = -ENOMEM; |
---|
| 1139 | + goto err_free_pkey_group; |
---|
| 1140 | + } |
---|
| 1141 | + |
---|
| 1142 | + ret = sysfs_create_group(&p->kobj, p->pkey_group); |
---|
| 1143 | + if (ret) |
---|
| 1144 | + goto err_free_pkey; |
---|
1110 | 1145 | } |
---|
1111 | 1146 | |
---|
1112 | | - ret = sysfs_create_group(&p->kobj, &p->pkey_group); |
---|
1113 | | - if (ret) |
---|
1114 | | - goto err_free_pkey; |
---|
1115 | 1147 | |
---|
1116 | | - if (port_callback) { |
---|
1117 | | - ret = port_callback(device, port_num, &p->kobj); |
---|
| 1148 | + if (device->ops.init_port && is_full_dev) { |
---|
| 1149 | + ret = device->ops.init_port(device, port_num, &p->kobj); |
---|
1118 | 1150 | if (ret) |
---|
1119 | 1151 | goto err_remove_pkey; |
---|
1120 | 1152 | } |
---|
1121 | 1153 | |
---|
1122 | 1154 | /* |
---|
1123 | | - * If port == 0, it means we have only one port and the parent |
---|
1124 | | - * device, not this port device, should be the holder of the |
---|
1125 | | - * hw_counters |
---|
| 1155 | + * If port == 0, it means hw_counters are per device and not per |
---|
| 1156 | + * port, so holder should be device. Therefore skip per port conunter |
---|
| 1157 | + * initialization. |
---|
1126 | 1158 | */ |
---|
1127 | | - if (device->alloc_hw_stats && port_num) |
---|
| 1159 | + if (device->ops.alloc_hw_stats && port_num && is_full_dev) |
---|
1128 | 1160 | setup_hw_stats(device, p, port_num); |
---|
1129 | 1161 | |
---|
1130 | | - list_add_tail(&p->kobj.entry, &device->port_list); |
---|
| 1162 | + list_add_tail(&p->kobj.entry, &coredev->port_list); |
---|
1131 | 1163 | |
---|
1132 | 1164 | kobject_uevent(&p->kobj, KOBJ_ADD); |
---|
1133 | 1165 | return 0; |
---|
1134 | 1166 | |
---|
1135 | 1167 | err_remove_pkey: |
---|
1136 | | - sysfs_remove_group(&p->kobj, &p->pkey_group); |
---|
| 1168 | + if (p->pkey_group) |
---|
| 1169 | + sysfs_remove_group(&p->kobj, p->pkey_group); |
---|
1137 | 1170 | |
---|
1138 | 1171 | err_free_pkey: |
---|
1139 | | - for (i = 0; i < attr.pkey_tbl_len; ++i) |
---|
1140 | | - kfree(p->pkey_group.attrs[i]); |
---|
| 1172 | + if (p->pkey_group) { |
---|
| 1173 | + for (i = 0; i < attr.pkey_tbl_len; ++i) |
---|
| 1174 | + kfree(p->pkey_group->attrs[i]); |
---|
1141 | 1175 | |
---|
1142 | | - kfree(p->pkey_group.attrs); |
---|
1143 | | - p->pkey_group.attrs = NULL; |
---|
| 1176 | + kfree(p->pkey_group->attrs); |
---|
| 1177 | + p->pkey_group->attrs = NULL; |
---|
| 1178 | + } |
---|
| 1179 | + |
---|
| 1180 | +err_free_pkey_group: |
---|
| 1181 | + kfree(p->pkey_group); |
---|
1144 | 1182 | |
---|
1145 | 1183 | err_remove_gid_type: |
---|
1146 | 1184 | sysfs_remove_group(&p->gid_attr_group->kobj, |
---|
.. | .. |
---|
1186 | 1224 | return ret; |
---|
1187 | 1225 | } |
---|
1188 | 1226 | |
---|
1189 | | -static ssize_t show_node_type(struct device *device, |
---|
| 1227 | +static ssize_t node_type_show(struct device *device, |
---|
1190 | 1228 | struct device_attribute *attr, char *buf) |
---|
1191 | 1229 | { |
---|
1192 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1230 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1193 | 1231 | |
---|
1194 | 1232 | switch (dev->node_type) { |
---|
1195 | 1233 | case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type); |
---|
1196 | 1234 | case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type); |
---|
1197 | 1235 | case RDMA_NODE_USNIC: return sprintf(buf, "%d: usNIC\n", dev->node_type); |
---|
1198 | 1236 | case RDMA_NODE_USNIC_UDP: return sprintf(buf, "%d: usNIC UDP\n", dev->node_type); |
---|
| 1237 | + case RDMA_NODE_UNSPECIFIED: return sprintf(buf, "%d: unspecified\n", dev->node_type); |
---|
1199 | 1238 | case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type); |
---|
1200 | 1239 | case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type); |
---|
1201 | 1240 | default: return sprintf(buf, "%d: <unknown>\n", dev->node_type); |
---|
1202 | 1241 | } |
---|
1203 | 1242 | } |
---|
| 1243 | +static DEVICE_ATTR_RO(node_type); |
---|
1204 | 1244 | |
---|
1205 | | -static ssize_t show_sys_image_guid(struct device *device, |
---|
| 1245 | +static ssize_t sys_image_guid_show(struct device *device, |
---|
1206 | 1246 | struct device_attribute *dev_attr, char *buf) |
---|
1207 | 1247 | { |
---|
1208 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1248 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1209 | 1249 | |
---|
1210 | 1250 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", |
---|
1211 | 1251 | be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[0]), |
---|
.. | .. |
---|
1213 | 1253 | be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[2]), |
---|
1214 | 1254 | be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[3])); |
---|
1215 | 1255 | } |
---|
| 1256 | +static DEVICE_ATTR_RO(sys_image_guid); |
---|
1216 | 1257 | |
---|
1217 | | -static ssize_t show_node_guid(struct device *device, |
---|
| 1258 | +static ssize_t node_guid_show(struct device *device, |
---|
1218 | 1259 | struct device_attribute *attr, char *buf) |
---|
1219 | 1260 | { |
---|
1220 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1261 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1221 | 1262 | |
---|
1222 | 1263 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", |
---|
1223 | 1264 | be16_to_cpu(((__be16 *) &dev->node_guid)[0]), |
---|
.. | .. |
---|
1225 | 1266 | be16_to_cpu(((__be16 *) &dev->node_guid)[2]), |
---|
1226 | 1267 | be16_to_cpu(((__be16 *) &dev->node_guid)[3])); |
---|
1227 | 1268 | } |
---|
| 1269 | +static DEVICE_ATTR_RO(node_guid); |
---|
1228 | 1270 | |
---|
1229 | | -static ssize_t show_node_desc(struct device *device, |
---|
| 1271 | +static ssize_t node_desc_show(struct device *device, |
---|
1230 | 1272 | struct device_attribute *attr, char *buf) |
---|
1231 | 1273 | { |
---|
1232 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1274 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1233 | 1275 | |
---|
1234 | 1276 | return sprintf(buf, "%.64s\n", dev->node_desc); |
---|
1235 | 1277 | } |
---|
1236 | 1278 | |
---|
1237 | | -static ssize_t set_node_desc(struct device *device, |
---|
1238 | | - struct device_attribute *attr, |
---|
1239 | | - const char *buf, size_t count) |
---|
| 1279 | +static ssize_t node_desc_store(struct device *device, |
---|
| 1280 | + struct device_attribute *attr, |
---|
| 1281 | + const char *buf, size_t count) |
---|
1240 | 1282 | { |
---|
1241 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1283 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1242 | 1284 | struct ib_device_modify desc = {}; |
---|
1243 | 1285 | int ret; |
---|
1244 | 1286 | |
---|
1245 | | - if (!dev->modify_device) |
---|
1246 | | - return -EIO; |
---|
| 1287 | + if (!dev->ops.modify_device) |
---|
| 1288 | + return -EOPNOTSUPP; |
---|
1247 | 1289 | |
---|
1248 | 1290 | memcpy(desc.node_desc, buf, min_t(int, count, IB_DEVICE_NODE_DESC_MAX)); |
---|
1249 | 1291 | ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc); |
---|
.. | .. |
---|
1252 | 1294 | |
---|
1253 | 1295 | return count; |
---|
1254 | 1296 | } |
---|
| 1297 | +static DEVICE_ATTR_RW(node_desc); |
---|
1255 | 1298 | |
---|
1256 | | -static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr, |
---|
| 1299 | +static ssize_t fw_ver_show(struct device *device, struct device_attribute *attr, |
---|
1257 | 1300 | char *buf) |
---|
1258 | 1301 | { |
---|
1259 | | - struct ib_device *dev = container_of(device, struct ib_device, dev); |
---|
| 1302 | + struct ib_device *dev = rdma_device_to_ibdev(device); |
---|
1260 | 1303 | |
---|
1261 | 1304 | ib_get_device_fw_str(dev, buf); |
---|
1262 | 1305 | strlcat(buf, "\n", IB_FW_VERSION_NAME_MAX); |
---|
1263 | 1306 | return strlen(buf); |
---|
1264 | 1307 | } |
---|
| 1308 | +static DEVICE_ATTR_RO(fw_ver); |
---|
1265 | 1309 | |
---|
1266 | | -static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); |
---|
1267 | | -static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL); |
---|
1268 | | -static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL); |
---|
1269 | | -static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc); |
---|
1270 | | -static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); |
---|
1271 | | - |
---|
1272 | | -static struct device_attribute *ib_class_attributes[] = { |
---|
1273 | | - &dev_attr_node_type, |
---|
1274 | | - &dev_attr_sys_image_guid, |
---|
1275 | | - &dev_attr_node_guid, |
---|
1276 | | - &dev_attr_node_desc, |
---|
1277 | | - &dev_attr_fw_ver, |
---|
| 1310 | +static struct attribute *ib_dev_attrs[] = { |
---|
| 1311 | + &dev_attr_node_type.attr, |
---|
| 1312 | + &dev_attr_node_guid.attr, |
---|
| 1313 | + &dev_attr_sys_image_guid.attr, |
---|
| 1314 | + &dev_attr_fw_ver.attr, |
---|
| 1315 | + &dev_attr_node_desc.attr, |
---|
| 1316 | + NULL, |
---|
1278 | 1317 | }; |
---|
1279 | 1318 | |
---|
1280 | | -static void free_port_list_attributes(struct ib_device *device) |
---|
| 1319 | +const struct attribute_group ib_dev_attr_group = { |
---|
| 1320 | + .attrs = ib_dev_attrs, |
---|
| 1321 | +}; |
---|
| 1322 | + |
---|
| 1323 | +void ib_free_port_attrs(struct ib_core_device *coredev) |
---|
1281 | 1324 | { |
---|
| 1325 | + struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); |
---|
| 1326 | + bool is_full_dev = &device->coredev == coredev; |
---|
1282 | 1327 | struct kobject *p, *t; |
---|
1283 | 1328 | |
---|
1284 | | - list_for_each_entry_safe(p, t, &device->port_list, entry) { |
---|
| 1329 | + list_for_each_entry_safe(p, t, &coredev->port_list, entry) { |
---|
1285 | 1330 | struct ib_port *port = container_of(p, struct ib_port, kobj); |
---|
| 1331 | + |
---|
1286 | 1332 | list_del(&p->entry); |
---|
1287 | | - if (port->hw_stats) { |
---|
1288 | | - kfree(port->hw_stats); |
---|
| 1333 | + if (port->hw_stats_ag) |
---|
1289 | 1334 | free_hsag(&port->kobj, port->hw_stats_ag); |
---|
1290 | | - } |
---|
| 1335 | + kfree(port->hw_stats); |
---|
| 1336 | + if (device->port_data && is_full_dev) |
---|
| 1337 | + device->port_data[port->port_num].hw_stats = NULL; |
---|
1291 | 1338 | |
---|
1292 | 1339 | if (port->pma_table) |
---|
1293 | 1340 | sysfs_remove_group(p, port->pma_table); |
---|
1294 | | - sysfs_remove_group(p, &port->pkey_group); |
---|
| 1341 | + if (port->pkey_group) |
---|
| 1342 | + sysfs_remove_group(p, port->pkey_group); |
---|
1295 | 1343 | sysfs_remove_group(p, &port->gid_group); |
---|
1296 | 1344 | sysfs_remove_group(&port->gid_attr_group->kobj, |
---|
1297 | 1345 | &port->gid_attr_group->ndev); |
---|
.. | .. |
---|
1301 | 1349 | kobject_put(p); |
---|
1302 | 1350 | } |
---|
1303 | 1351 | |
---|
1304 | | - kobject_put(device->ports_parent); |
---|
| 1352 | + kobject_put(coredev->ports_kobj); |
---|
1305 | 1353 | } |
---|
1306 | 1354 | |
---|
1307 | | -int ib_device_register_sysfs(struct ib_device *device, |
---|
1308 | | - int (*port_callback)(struct ib_device *, |
---|
1309 | | - u8, struct kobject *)) |
---|
| 1355 | +int ib_setup_port_attrs(struct ib_core_device *coredev) |
---|
1310 | 1356 | { |
---|
1311 | | - struct device *class_dev = &device->dev; |
---|
| 1357 | + struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); |
---|
| 1358 | + unsigned int port; |
---|
1312 | 1359 | int ret; |
---|
1313 | | - int i; |
---|
1314 | 1360 | |
---|
1315 | | - ret = dev_set_name(class_dev, "%s", device->name); |
---|
1316 | | - if (ret) |
---|
1317 | | - return ret; |
---|
| 1361 | + coredev->ports_kobj = kobject_create_and_add("ports", |
---|
| 1362 | + &coredev->dev.kobj); |
---|
| 1363 | + if (!coredev->ports_kobj) |
---|
| 1364 | + return -ENOMEM; |
---|
1318 | 1365 | |
---|
1319 | | - ret = device_add(class_dev); |
---|
1320 | | - if (ret) |
---|
1321 | | - goto err; |
---|
1322 | | - |
---|
1323 | | - for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) { |
---|
1324 | | - ret = device_create_file(class_dev, ib_class_attributes[i]); |
---|
1325 | | - if (ret) |
---|
1326 | | - goto err_unregister; |
---|
1327 | | - } |
---|
1328 | | - |
---|
1329 | | - device->ports_parent = kobject_create_and_add("ports", |
---|
1330 | | - &class_dev->kobj); |
---|
1331 | | - if (!device->ports_parent) { |
---|
1332 | | - ret = -ENOMEM; |
---|
1333 | | - goto err_put; |
---|
1334 | | - } |
---|
1335 | | - |
---|
1336 | | - if (rdma_cap_ib_switch(device)) { |
---|
1337 | | - ret = add_port(device, 0, port_callback); |
---|
| 1366 | + rdma_for_each_port (device, port) { |
---|
| 1367 | + ret = add_port(coredev, port); |
---|
1338 | 1368 | if (ret) |
---|
1339 | 1369 | goto err_put; |
---|
1340 | | - } else { |
---|
1341 | | - for (i = 1; i <= device->phys_port_cnt; ++i) { |
---|
1342 | | - ret = add_port(device, i, port_callback); |
---|
1343 | | - if (ret) |
---|
1344 | | - goto err_put; |
---|
1345 | | - } |
---|
1346 | 1370 | } |
---|
1347 | | - |
---|
1348 | | - if (device->alloc_hw_stats) |
---|
1349 | | - setup_hw_stats(device, NULL, 0); |
---|
1350 | 1371 | |
---|
1351 | 1372 | return 0; |
---|
1352 | 1373 | |
---|
1353 | 1374 | err_put: |
---|
1354 | | - free_port_list_attributes(device); |
---|
1355 | | - |
---|
1356 | | -err_unregister: |
---|
1357 | | - device_del(class_dev); |
---|
1358 | | - |
---|
1359 | | -err: |
---|
| 1375 | + ib_free_port_attrs(coredev); |
---|
1360 | 1376 | return ret; |
---|
| 1377 | +} |
---|
| 1378 | + |
---|
| 1379 | +int ib_device_register_sysfs(struct ib_device *device) |
---|
| 1380 | +{ |
---|
| 1381 | + int ret; |
---|
| 1382 | + |
---|
| 1383 | + ret = ib_setup_port_attrs(&device->coredev); |
---|
| 1384 | + if (ret) |
---|
| 1385 | + return ret; |
---|
| 1386 | + |
---|
| 1387 | + if (device->ops.alloc_hw_stats) |
---|
| 1388 | + setup_hw_stats(device, NULL, 0); |
---|
| 1389 | + |
---|
| 1390 | + return 0; |
---|
1361 | 1391 | } |
---|
1362 | 1392 | |
---|
1363 | 1393 | void ib_device_unregister_sysfs(struct ib_device *device) |
---|
1364 | 1394 | { |
---|
1365 | | - int i; |
---|
1366 | | - |
---|
1367 | | - /* Hold kobject until ib_dealloc_device() */ |
---|
1368 | | - kobject_get(&device->dev.kobj); |
---|
1369 | | - |
---|
1370 | | - free_port_list_attributes(device); |
---|
1371 | | - |
---|
1372 | | - if (device->hw_stats) { |
---|
1373 | | - kfree(device->hw_stats); |
---|
| 1395 | + if (device->hw_stats_ag) |
---|
1374 | 1396 | free_hsag(&device->dev.kobj, device->hw_stats_ag); |
---|
| 1397 | + kfree(device->hw_stats); |
---|
| 1398 | + |
---|
| 1399 | + ib_free_port_attrs(&device->coredev); |
---|
| 1400 | +} |
---|
| 1401 | + |
---|
| 1402 | +/** |
---|
| 1403 | + * ib_port_register_module_stat - add module counters under relevant port |
---|
| 1404 | + * of IB device. |
---|
| 1405 | + * |
---|
| 1406 | + * @device: IB device to add counters |
---|
| 1407 | + * @port_num: valid port number |
---|
| 1408 | + * @kobj: pointer to the kobject to initialize |
---|
| 1409 | + * @ktype: pointer to the ktype for this kobject. |
---|
| 1410 | + * @name: the name of the kobject |
---|
| 1411 | + */ |
---|
| 1412 | +int ib_port_register_module_stat(struct ib_device *device, u8 port_num, |
---|
| 1413 | + struct kobject *kobj, struct kobj_type *ktype, |
---|
| 1414 | + const char *name) |
---|
| 1415 | +{ |
---|
| 1416 | + struct kobject *p, *t; |
---|
| 1417 | + int ret; |
---|
| 1418 | + |
---|
| 1419 | + list_for_each_entry_safe(p, t, &device->coredev.port_list, entry) { |
---|
| 1420 | + struct ib_port *port = container_of(p, struct ib_port, kobj); |
---|
| 1421 | + |
---|
| 1422 | + if (port->port_num != port_num) |
---|
| 1423 | + continue; |
---|
| 1424 | + |
---|
| 1425 | + ret = kobject_init_and_add(kobj, ktype, &port->kobj, "%s", |
---|
| 1426 | + name); |
---|
| 1427 | + if (ret) { |
---|
| 1428 | + kobject_put(kobj); |
---|
| 1429 | + return ret; |
---|
| 1430 | + } |
---|
1375 | 1431 | } |
---|
1376 | 1432 | |
---|
1377 | | - for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) |
---|
1378 | | - device_remove_file(&device->dev, ib_class_attributes[i]); |
---|
1379 | | - |
---|
1380 | | - device_unregister(&device->dev); |
---|
| 1433 | + return 0; |
---|
1381 | 1434 | } |
---|
| 1435 | +EXPORT_SYMBOL(ib_port_register_module_stat); |
---|
| 1436 | + |
---|
| 1437 | +/** |
---|
| 1438 | + * ib_port_unregister_module_stat - release module counters |
---|
| 1439 | + * @kobj: pointer to the kobject to release |
---|
| 1440 | + */ |
---|
| 1441 | +void ib_port_unregister_module_stat(struct kobject *kobj) |
---|
| 1442 | +{ |
---|
| 1443 | + kobject_put(kobj); |
---|
| 1444 | +} |
---|
| 1445 | +EXPORT_SYMBOL(ib_port_unregister_module_stat); |
---|