Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
0003  * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
0004  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005  *
0006  * This software is available to you under a choice of one of two
0007  * licenses.  You may choose to be licensed under the terms of the GNU
0008  * General Public License (GPL) Version 2, available from the file
0009  * COPYING in the main directory of this source tree, or the
0010  * OpenIB.org BSD license below:
0011  *
0012  *     Redistribution and use in source and binary forms, with or
0013  *     without modification, are permitted provided that the following
0014  *     conditions are met:
0015  *
0016  *      - Redistributions of source code must retain the above
0017  *        copyright notice, this list of conditions and the following
0018  *        disclaimer.
0019  *
0020  *      - Redistributions in binary form must reproduce the above
0021  *        copyright notice, this list of conditions and the following
0022  *        disclaimer in the documentation and/or other materials
0023  *        provided with the distribution.
0024  *
0025  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0026  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0027  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0028  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0029  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0030  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0031  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0032  * SOFTWARE.
0033  */
0034 
0035 #include "core_priv.h"
0036 
0037 #include <linux/slab.h>
0038 #include <linux/stat.h>
0039 #include <linux/string.h>
0040 #include <linux/netdevice.h>
0041 #include <linux/ethtool.h>
0042 
0043 #include <rdma/ib_mad.h>
0044 #include <rdma/ib_pma.h>
0045 #include <rdma/ib_cache.h>
0046 #include <rdma/rdma_counter.h>
0047 #include <rdma/ib_sysfs.h>
0048 
0049 struct port_table_attribute {
0050     struct ib_port_attribute attr;
0051     char            name[8];
0052     int         index;
0053     __be16          attr_id;
0054 };
0055 
0056 struct gid_attr_group {
0057     struct ib_port *port;
0058     struct kobject kobj;
0059     struct attribute_group groups[2];
0060     const struct attribute_group *groups_list[3];
0061     struct port_table_attribute attrs_list[];
0062 };
0063 
0064 struct ib_port {
0065     struct kobject kobj;
0066     struct ib_device *ibdev;
0067     struct gid_attr_group *gid_attr_group;
0068     struct hw_stats_port_data *hw_stats_data;
0069 
0070     struct attribute_group groups[3];
0071     const struct attribute_group *groups_list[5];
0072     u32 port_num;
0073     struct port_table_attribute attrs_list[];
0074 };
0075 
0076 struct hw_stats_device_attribute {
0077     struct device_attribute attr;
0078     ssize_t (*show)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
0079             unsigned int index, unsigned int port_num, char *buf);
0080     ssize_t (*store)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
0081              unsigned int index, unsigned int port_num,
0082              const char *buf, size_t count);
0083 };
0084 
0085 struct hw_stats_port_attribute {
0086     struct ib_port_attribute attr;
0087     ssize_t (*show)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
0088             unsigned int index, unsigned int port_num, char *buf);
0089     ssize_t (*store)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
0090              unsigned int index, unsigned int port_num,
0091              const char *buf, size_t count);
0092 };
0093 
0094 struct hw_stats_device_data {
0095     struct attribute_group group;
0096     struct rdma_hw_stats *stats;
0097     struct hw_stats_device_attribute attrs[];
0098 };
0099 
0100 struct hw_stats_port_data {
0101     struct rdma_hw_stats *stats;
0102     struct hw_stats_port_attribute attrs[];
0103 };
0104 
0105 static ssize_t port_attr_show(struct kobject *kobj,
0106                   struct attribute *attr, char *buf)
0107 {
0108     struct ib_port_attribute *port_attr =
0109         container_of(attr, struct ib_port_attribute, attr);
0110     struct ib_port *p = container_of(kobj, struct ib_port, kobj);
0111 
0112     if (!port_attr->show)
0113         return -EIO;
0114 
0115     return port_attr->show(p->ibdev, p->port_num, port_attr, buf);
0116 }
0117 
0118 static ssize_t port_attr_store(struct kobject *kobj,
0119                    struct attribute *attr,
0120                    const char *buf, size_t count)
0121 {
0122     struct ib_port_attribute *port_attr =
0123         container_of(attr, struct ib_port_attribute, attr);
0124     struct ib_port *p = container_of(kobj, struct ib_port, kobj);
0125 
0126     if (!port_attr->store)
0127         return -EIO;
0128     return port_attr->store(p->ibdev, p->port_num, port_attr, buf, count);
0129 }
0130 
0131 struct ib_device *ib_port_sysfs_get_ibdev_kobj(struct kobject *kobj,
0132                            u32 *port_num)
0133 {
0134     struct ib_port *port = container_of(kobj, struct ib_port, kobj);
0135 
0136     *port_num = port->port_num;
0137     return port->ibdev;
0138 }
0139 EXPORT_SYMBOL(ib_port_sysfs_get_ibdev_kobj);
0140 
0141 static const struct sysfs_ops port_sysfs_ops = {
0142     .show   = port_attr_show,
0143     .store  = port_attr_store
0144 };
0145 
0146 static ssize_t hw_stat_device_show(struct device *dev,
0147                    struct device_attribute *attr, char *buf)
0148 {
0149     struct hw_stats_device_attribute *stat_attr =
0150         container_of(attr, struct hw_stats_device_attribute, attr);
0151     struct ib_device *ibdev = container_of(dev, struct ib_device, dev);
0152 
0153     return stat_attr->show(ibdev, ibdev->hw_stats_data->stats,
0154                    stat_attr - ibdev->hw_stats_data->attrs, 0, buf);
0155 }
0156 
0157 static ssize_t hw_stat_device_store(struct device *dev,
0158                     struct device_attribute *attr,
0159                     const char *buf, size_t count)
0160 {
0161     struct hw_stats_device_attribute *stat_attr =
0162         container_of(attr, struct hw_stats_device_attribute, attr);
0163     struct ib_device *ibdev = container_of(dev, struct ib_device, dev);
0164 
0165     return stat_attr->store(ibdev, ibdev->hw_stats_data->stats,
0166                 stat_attr - ibdev->hw_stats_data->attrs, 0, buf,
0167                 count);
0168 }
0169 
0170 static ssize_t hw_stat_port_show(struct ib_device *ibdev, u32 port_num,
0171                  struct ib_port_attribute *attr, char *buf)
0172 {
0173     struct hw_stats_port_attribute *stat_attr =
0174         container_of(attr, struct hw_stats_port_attribute, attr);
0175     struct ib_port *port = ibdev->port_data[port_num].sysfs;
0176 
0177     return stat_attr->show(ibdev, port->hw_stats_data->stats,
0178                    stat_attr - port->hw_stats_data->attrs,
0179                    port->port_num, buf);
0180 }
0181 
0182 static ssize_t hw_stat_port_store(struct ib_device *ibdev, u32 port_num,
0183                   struct ib_port_attribute *attr,
0184                   const char *buf, size_t count)
0185 {
0186     struct hw_stats_port_attribute *stat_attr =
0187         container_of(attr, struct hw_stats_port_attribute, attr);
0188     struct ib_port *port = ibdev->port_data[port_num].sysfs;
0189 
0190     return stat_attr->store(ibdev, port->hw_stats_data->stats,
0191                 stat_attr - port->hw_stats_data->attrs,
0192                 port->port_num, buf, count);
0193 }
0194 
0195 static ssize_t gid_attr_show(struct kobject *kobj,
0196                  struct attribute *attr, char *buf)
0197 {
0198     struct ib_port_attribute *port_attr =
0199         container_of(attr, struct ib_port_attribute, attr);
0200     struct ib_port *p = container_of(kobj, struct gid_attr_group,
0201                      kobj)->port;
0202 
0203     if (!port_attr->show)
0204         return -EIO;
0205 
0206     return port_attr->show(p->ibdev, p->port_num, port_attr, buf);
0207 }
0208 
0209 static const struct sysfs_ops gid_attr_sysfs_ops = {
0210     .show = gid_attr_show
0211 };
0212 
0213 static ssize_t state_show(struct ib_device *ibdev, u32 port_num,
0214               struct ib_port_attribute *unused, char *buf)
0215 {
0216     struct ib_port_attr attr;
0217     ssize_t ret;
0218 
0219     static const char *state_name[] = {
0220         [IB_PORT_NOP]       = "NOP",
0221         [IB_PORT_DOWN]      = "DOWN",
0222         [IB_PORT_INIT]      = "INIT",
0223         [IB_PORT_ARMED]     = "ARMED",
0224         [IB_PORT_ACTIVE]    = "ACTIVE",
0225         [IB_PORT_ACTIVE_DEFER]  = "ACTIVE_DEFER"
0226     };
0227 
0228     ret = ib_query_port(ibdev, port_num, &attr);
0229     if (ret)
0230         return ret;
0231 
0232     return sysfs_emit(buf, "%d: %s\n", attr.state,
0233               attr.state >= 0 &&
0234                       attr.state < ARRAY_SIZE(state_name) ?
0235                   state_name[attr.state] :
0236                   "UNKNOWN");
0237 }
0238 
0239 static ssize_t lid_show(struct ib_device *ibdev, u32 port_num,
0240             struct ib_port_attribute *unused, char *buf)
0241 {
0242     struct ib_port_attr attr;
0243     ssize_t ret;
0244 
0245     ret = ib_query_port(ibdev, port_num, &attr);
0246     if (ret)
0247         return ret;
0248 
0249     return sysfs_emit(buf, "0x%x\n", attr.lid);
0250 }
0251 
0252 static ssize_t lid_mask_count_show(struct ib_device *ibdev, u32 port_num,
0253                    struct ib_port_attribute *unused, char *buf)
0254 {
0255     struct ib_port_attr attr;
0256     ssize_t ret;
0257 
0258     ret = ib_query_port(ibdev, port_num, &attr);
0259     if (ret)
0260         return ret;
0261 
0262     return sysfs_emit(buf, "%u\n", attr.lmc);
0263 }
0264 
0265 static ssize_t sm_lid_show(struct ib_device *ibdev, u32 port_num,
0266                struct ib_port_attribute *unused, char *buf)
0267 {
0268     struct ib_port_attr attr;
0269     ssize_t ret;
0270 
0271     ret = ib_query_port(ibdev, port_num, &attr);
0272     if (ret)
0273         return ret;
0274 
0275     return sysfs_emit(buf, "0x%x\n", attr.sm_lid);
0276 }
0277 
0278 static ssize_t sm_sl_show(struct ib_device *ibdev, u32 port_num,
0279               struct ib_port_attribute *unused, char *buf)
0280 {
0281     struct ib_port_attr attr;
0282     ssize_t ret;
0283 
0284     ret = ib_query_port(ibdev, port_num, &attr);
0285     if (ret)
0286         return ret;
0287 
0288     return sysfs_emit(buf, "%u\n", attr.sm_sl);
0289 }
0290 
0291 static ssize_t cap_mask_show(struct ib_device *ibdev, u32 port_num,
0292                  struct ib_port_attribute *unused, char *buf)
0293 {
0294     struct ib_port_attr attr;
0295     ssize_t ret;
0296 
0297     ret = ib_query_port(ibdev, port_num, &attr);
0298     if (ret)
0299         return ret;
0300 
0301     return sysfs_emit(buf, "0x%08x\n", attr.port_cap_flags);
0302 }
0303 
0304 static ssize_t rate_show(struct ib_device *ibdev, u32 port_num,
0305              struct ib_port_attribute *unused, char *buf)
0306 {
0307     struct ib_port_attr attr;
0308     char *speed = "";
0309     int rate;       /* in deci-Gb/sec */
0310     ssize_t ret;
0311 
0312     ret = ib_query_port(ibdev, port_num, &attr);
0313     if (ret)
0314         return ret;
0315 
0316     switch (attr.active_speed) {
0317     case IB_SPEED_DDR:
0318         speed = " DDR";
0319         rate = 50;
0320         break;
0321     case IB_SPEED_QDR:
0322         speed = " QDR";
0323         rate = 100;
0324         break;
0325     case IB_SPEED_FDR10:
0326         speed = " FDR10";
0327         rate = 100;
0328         break;
0329     case IB_SPEED_FDR:
0330         speed = " FDR";
0331         rate = 140;
0332         break;
0333     case IB_SPEED_EDR:
0334         speed = " EDR";
0335         rate = 250;
0336         break;
0337     case IB_SPEED_HDR:
0338         speed = " HDR";
0339         rate = 500;
0340         break;
0341     case IB_SPEED_NDR:
0342         speed = " NDR";
0343         rate = 1000;
0344         break;
0345     case IB_SPEED_SDR:
0346     default:        /* default to SDR for invalid rates */
0347         speed = " SDR";
0348         rate = 25;
0349         break;
0350     }
0351 
0352     rate *= ib_width_enum_to_int(attr.active_width);
0353     if (rate < 0)
0354         return -EINVAL;
0355 
0356     return sysfs_emit(buf, "%d%s Gb/sec (%dX%s)\n", rate / 10,
0357               rate % 10 ? ".5" : "",
0358               ib_width_enum_to_int(attr.active_width), speed);
0359 }
0360 
0361 static const char *phys_state_to_str(enum ib_port_phys_state phys_state)
0362 {
0363     static const char *phys_state_str[] = {
0364         "<unknown>",
0365         "Sleep",
0366         "Polling",
0367         "Disabled",
0368         "PortConfigurationTraining",
0369         "LinkUp",
0370         "LinkErrorRecovery",
0371         "Phy Test",
0372     };
0373 
0374     if (phys_state < ARRAY_SIZE(phys_state_str))
0375         return phys_state_str[phys_state];
0376     return "<unknown>";
0377 }
0378 
0379 static ssize_t phys_state_show(struct ib_device *ibdev, u32 port_num,
0380                    struct ib_port_attribute *unused, char *buf)
0381 {
0382     struct ib_port_attr attr;
0383 
0384     ssize_t ret;
0385 
0386     ret = ib_query_port(ibdev, port_num, &attr);
0387     if (ret)
0388         return ret;
0389 
0390     return sysfs_emit(buf, "%u: %s\n", attr.phys_state,
0391               phys_state_to_str(attr.phys_state));
0392 }
0393 
0394 static ssize_t link_layer_show(struct ib_device *ibdev, u32 port_num,
0395                    struct ib_port_attribute *unused, char *buf)
0396 {
0397     const char *output;
0398 
0399     switch (rdma_port_get_link_layer(ibdev, port_num)) {
0400     case IB_LINK_LAYER_INFINIBAND:
0401         output = "InfiniBand";
0402         break;
0403     case IB_LINK_LAYER_ETHERNET:
0404         output = "Ethernet";
0405         break;
0406     default:
0407         output = "Unknown";
0408         break;
0409     }
0410 
0411     return sysfs_emit(buf, "%s\n", output);
0412 }
0413 
0414 static IB_PORT_ATTR_RO(state);
0415 static IB_PORT_ATTR_RO(lid);
0416 static IB_PORT_ATTR_RO(lid_mask_count);
0417 static IB_PORT_ATTR_RO(sm_lid);
0418 static IB_PORT_ATTR_RO(sm_sl);
0419 static IB_PORT_ATTR_RO(cap_mask);
0420 static IB_PORT_ATTR_RO(rate);
0421 static IB_PORT_ATTR_RO(phys_state);
0422 static IB_PORT_ATTR_RO(link_layer);
0423 
0424 static struct attribute *port_default_attrs[] = {
0425     &ib_port_attr_state.attr,
0426     &ib_port_attr_lid.attr,
0427     &ib_port_attr_lid_mask_count.attr,
0428     &ib_port_attr_sm_lid.attr,
0429     &ib_port_attr_sm_sl.attr,
0430     &ib_port_attr_cap_mask.attr,
0431     &ib_port_attr_rate.attr,
0432     &ib_port_attr_phys_state.attr,
0433     &ib_port_attr_link_layer.attr,
0434     NULL
0435 };
0436 ATTRIBUTE_GROUPS(port_default);
0437 
0438 static ssize_t print_ndev(const struct ib_gid_attr *gid_attr, char *buf)
0439 {
0440     struct net_device *ndev;
0441     int ret = -EINVAL;
0442 
0443     rcu_read_lock();
0444     ndev = rcu_dereference(gid_attr->ndev);
0445     if (ndev)
0446         ret = sysfs_emit(buf, "%s\n", ndev->name);
0447     rcu_read_unlock();
0448     return ret;
0449 }
0450 
0451 static ssize_t print_gid_type(const struct ib_gid_attr *gid_attr, char *buf)
0452 {
0453     return sysfs_emit(buf, "%s\n",
0454               ib_cache_gid_type_str(gid_attr->gid_type));
0455 }
0456 
0457 static ssize_t _show_port_gid_attr(
0458     struct ib_device *ibdev, u32 port_num, struct ib_port_attribute *attr,
0459     char *buf,
0460     ssize_t (*print)(const struct ib_gid_attr *gid_attr, char *buf))
0461 {
0462     struct port_table_attribute *tab_attr =
0463         container_of(attr, struct port_table_attribute, attr);
0464     const struct ib_gid_attr *gid_attr;
0465     ssize_t ret;
0466 
0467     gid_attr = rdma_get_gid_attr(ibdev, port_num, tab_attr->index);
0468     if (IS_ERR(gid_attr))
0469         /* -EINVAL is returned for user space compatibility reasons. */
0470         return -EINVAL;
0471 
0472     ret = print(gid_attr, buf);
0473     rdma_put_gid_attr(gid_attr);
0474     return ret;
0475 }
0476 
0477 static ssize_t show_port_gid(struct ib_device *ibdev, u32 port_num,
0478                  struct ib_port_attribute *attr, char *buf)
0479 {
0480     struct port_table_attribute *tab_attr =
0481         container_of(attr, struct port_table_attribute, attr);
0482     const struct ib_gid_attr *gid_attr;
0483     int len;
0484 
0485     gid_attr = rdma_get_gid_attr(ibdev, port_num, tab_attr->index);
0486     if (IS_ERR(gid_attr)) {
0487         const union ib_gid zgid = {};
0488 
0489         /* If reading GID fails, it is likely due to GID entry being
0490          * empty (invalid) or reserved GID in the table.  User space
0491          * expects to read GID table entries as long as it given index
0492          * is within GID table size.  Administrative/debugging tool
0493          * fails to query rest of the GID entries if it hits error
0494          * while querying a GID of the given index.  To avoid user
0495          * space throwing such error on fail to read gid, return zero
0496          * GID as before. This maintains backward compatibility.
0497          */
0498         return sysfs_emit(buf, "%pI6\n", zgid.raw);
0499     }
0500 
0501     len = sysfs_emit(buf, "%pI6\n", gid_attr->gid.raw);
0502     rdma_put_gid_attr(gid_attr);
0503     return len;
0504 }
0505 
0506 static ssize_t show_port_gid_attr_ndev(struct ib_device *ibdev, u32 port_num,
0507                        struct ib_port_attribute *attr,
0508                        char *buf)
0509 {
0510     return _show_port_gid_attr(ibdev, port_num, attr, buf, print_ndev);
0511 }
0512 
0513 static ssize_t show_port_gid_attr_gid_type(struct ib_device *ibdev,
0514                        u32 port_num,
0515                        struct ib_port_attribute *attr,
0516                        char *buf)
0517 {
0518     return _show_port_gid_attr(ibdev, port_num, attr, buf, print_gid_type);
0519 }
0520 
0521 static ssize_t show_port_pkey(struct ib_device *ibdev, u32 port_num,
0522                   struct ib_port_attribute *attr, char *buf)
0523 {
0524     struct port_table_attribute *tab_attr =
0525         container_of(attr, struct port_table_attribute, attr);
0526     u16 pkey;
0527     int ret;
0528 
0529     ret = ib_query_pkey(ibdev, port_num, tab_attr->index, &pkey);
0530     if (ret)
0531         return ret;
0532 
0533     return sysfs_emit(buf, "0x%04x\n", pkey);
0534 }
0535 
0536 #define PORT_PMA_ATTR(_name, _counter, _width, _offset)         \
0537 struct port_table_attribute port_pma_attr_##_name = {           \
0538     .attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),    \
0539     .index = (_offset) | ((_width) << 16) | ((_counter) << 24), \
0540     .attr_id = IB_PMA_PORT_COUNTERS,                \
0541 }
0542 
0543 #define PORT_PMA_ATTR_EXT(_name, _width, _offset)           \
0544 struct port_table_attribute port_pma_attr_ext_##_name = {       \
0545     .attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),    \
0546     .index = (_offset) | ((_width) << 16),              \
0547     .attr_id = IB_PMA_PORT_COUNTERS_EXT,                \
0548 }
0549 
0550 /*
0551  * Get a Perfmgmt MAD block of data.
0552  * Returns error code or the number of bytes retrieved.
0553  */
0554 static int get_perf_mad(struct ib_device *dev, int port_num, __be16 attr,
0555         void *data, int offset, size_t size)
0556 {
0557     struct ib_mad *in_mad;
0558     struct ib_mad *out_mad;
0559     size_t mad_size = sizeof(*out_mad);
0560     u16 out_mad_pkey_index = 0;
0561     ssize_t ret;
0562 
0563     if (!dev->ops.process_mad)
0564         return -ENOSYS;
0565 
0566     in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
0567     out_mad = kzalloc(sizeof(*out_mad), GFP_KERNEL);
0568     if (!in_mad || !out_mad) {
0569         ret = -ENOMEM;
0570         goto out;
0571     }
0572 
0573     in_mad->mad_hdr.base_version  = 1;
0574     in_mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_PERF_MGMT;
0575     in_mad->mad_hdr.class_version = 1;
0576     in_mad->mad_hdr.method        = IB_MGMT_METHOD_GET;
0577     in_mad->mad_hdr.attr_id       = attr;
0578 
0579     if (attr != IB_PMA_CLASS_PORT_INFO)
0580         in_mad->data[41] = port_num;    /* PortSelect field */
0581 
0582     if ((dev->ops.process_mad(dev, IB_MAD_IGNORE_MKEY, port_num, NULL, NULL,
0583                   in_mad, out_mad, &mad_size,
0584                   &out_mad_pkey_index) &
0585          (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
0586         (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
0587         ret = -EINVAL;
0588         goto out;
0589     }
0590     memcpy(data, out_mad->data + offset, size);
0591     ret = size;
0592 out:
0593     kfree(in_mad);
0594     kfree(out_mad);
0595     return ret;
0596 }
0597 
0598 static ssize_t show_pma_counter(struct ib_device *ibdev, u32 port_num,
0599                 struct ib_port_attribute *attr, char *buf)
0600 {
0601     struct port_table_attribute *tab_attr =
0602         container_of(attr, struct port_table_attribute, attr);
0603     int offset = tab_attr->index & 0xffff;
0604     int width  = (tab_attr->index >> 16) & 0xff;
0605     int ret;
0606     u8 data[8];
0607     int len;
0608 
0609     ret = get_perf_mad(ibdev, port_num, tab_attr->attr_id, &data,
0610             40 + offset / 8, sizeof(data));
0611     if (ret < 0)
0612         return ret;
0613 
0614     switch (width) {
0615     case 4:
0616         len = sysfs_emit(buf, "%d\n",
0617                  (*data >> (4 - (offset % 8))) & 0xf);
0618         break;
0619     case 8:
0620         len = sysfs_emit(buf, "%u\n", *data);
0621         break;
0622     case 16:
0623         len = sysfs_emit(buf, "%u\n", be16_to_cpup((__be16 *)data));
0624         break;
0625     case 32:
0626         len = sysfs_emit(buf, "%u\n", be32_to_cpup((__be32 *)data));
0627         break;
0628     case 64:
0629         len = sysfs_emit(buf, "%llu\n", be64_to_cpup((__be64 *)data));
0630         break;
0631     default:
0632         len = 0;
0633         break;
0634     }
0635 
0636     return len;
0637 }
0638 
0639 static PORT_PMA_ATTR(symbol_error           ,  0, 16,  32);
0640 static PORT_PMA_ATTR(link_error_recovery        ,  1,  8,  48);
0641 static PORT_PMA_ATTR(link_downed            ,  2,  8,  56);
0642 static PORT_PMA_ATTR(port_rcv_errors            ,  3, 16,  64);
0643 static PORT_PMA_ATTR(port_rcv_remote_physical_errors,  4, 16,  80);
0644 static PORT_PMA_ATTR(port_rcv_switch_relay_errors   ,  5, 16,  96);
0645 static PORT_PMA_ATTR(port_xmit_discards         ,  6, 16, 112);
0646 static PORT_PMA_ATTR(port_xmit_constraint_errors    ,  7,  8, 128);
0647 static PORT_PMA_ATTR(port_rcv_constraint_errors     ,  8,  8, 136);
0648 static PORT_PMA_ATTR(local_link_integrity_errors    ,  9,  4, 152);
0649 static PORT_PMA_ATTR(excessive_buffer_overrun_errors, 10,  4, 156);
0650 static PORT_PMA_ATTR(VL15_dropped           , 11, 16, 176);
0651 static PORT_PMA_ATTR(port_xmit_data         , 12, 32, 192);
0652 static PORT_PMA_ATTR(port_rcv_data          , 13, 32, 224);
0653 static PORT_PMA_ATTR(port_xmit_packets          , 14, 32, 256);
0654 static PORT_PMA_ATTR(port_rcv_packets           , 15, 32, 288);
0655 static PORT_PMA_ATTR(port_xmit_wait         ,  0, 32, 320);
0656 
0657 /*
0658  * Counters added by extended set
0659  */
0660 static PORT_PMA_ATTR_EXT(port_xmit_data         , 64,  64);
0661 static PORT_PMA_ATTR_EXT(port_rcv_data          , 64, 128);
0662 static PORT_PMA_ATTR_EXT(port_xmit_packets      , 64, 192);
0663 static PORT_PMA_ATTR_EXT(port_rcv_packets       , 64, 256);
0664 static PORT_PMA_ATTR_EXT(unicast_xmit_packets       , 64, 320);
0665 static PORT_PMA_ATTR_EXT(unicast_rcv_packets        , 64, 384);
0666 static PORT_PMA_ATTR_EXT(multicast_xmit_packets     , 64, 448);
0667 static PORT_PMA_ATTR_EXT(multicast_rcv_packets      , 64, 512);
0668 
0669 static struct attribute *pma_attrs[] = {
0670     &port_pma_attr_symbol_error.attr.attr,
0671     &port_pma_attr_link_error_recovery.attr.attr,
0672     &port_pma_attr_link_downed.attr.attr,
0673     &port_pma_attr_port_rcv_errors.attr.attr,
0674     &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
0675     &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
0676     &port_pma_attr_port_xmit_discards.attr.attr,
0677     &port_pma_attr_port_xmit_constraint_errors.attr.attr,
0678     &port_pma_attr_port_rcv_constraint_errors.attr.attr,
0679     &port_pma_attr_local_link_integrity_errors.attr.attr,
0680     &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
0681     &port_pma_attr_VL15_dropped.attr.attr,
0682     &port_pma_attr_port_xmit_data.attr.attr,
0683     &port_pma_attr_port_rcv_data.attr.attr,
0684     &port_pma_attr_port_xmit_packets.attr.attr,
0685     &port_pma_attr_port_rcv_packets.attr.attr,
0686     &port_pma_attr_port_xmit_wait.attr.attr,
0687     NULL
0688 };
0689 
0690 static struct attribute *pma_attrs_ext[] = {
0691     &port_pma_attr_symbol_error.attr.attr,
0692     &port_pma_attr_link_error_recovery.attr.attr,
0693     &port_pma_attr_link_downed.attr.attr,
0694     &port_pma_attr_port_rcv_errors.attr.attr,
0695     &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
0696     &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
0697     &port_pma_attr_port_xmit_discards.attr.attr,
0698     &port_pma_attr_port_xmit_constraint_errors.attr.attr,
0699     &port_pma_attr_port_rcv_constraint_errors.attr.attr,
0700     &port_pma_attr_local_link_integrity_errors.attr.attr,
0701     &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
0702     &port_pma_attr_VL15_dropped.attr.attr,
0703     &port_pma_attr_ext_port_xmit_data.attr.attr,
0704     &port_pma_attr_ext_port_rcv_data.attr.attr,
0705     &port_pma_attr_ext_port_xmit_packets.attr.attr,
0706     &port_pma_attr_port_xmit_wait.attr.attr,
0707     &port_pma_attr_ext_port_rcv_packets.attr.attr,
0708     &port_pma_attr_ext_unicast_rcv_packets.attr.attr,
0709     &port_pma_attr_ext_unicast_xmit_packets.attr.attr,
0710     &port_pma_attr_ext_multicast_rcv_packets.attr.attr,
0711     &port_pma_attr_ext_multicast_xmit_packets.attr.attr,
0712     NULL
0713 };
0714 
0715 static struct attribute *pma_attrs_noietf[] = {
0716     &port_pma_attr_symbol_error.attr.attr,
0717     &port_pma_attr_link_error_recovery.attr.attr,
0718     &port_pma_attr_link_downed.attr.attr,
0719     &port_pma_attr_port_rcv_errors.attr.attr,
0720     &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
0721     &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
0722     &port_pma_attr_port_xmit_discards.attr.attr,
0723     &port_pma_attr_port_xmit_constraint_errors.attr.attr,
0724     &port_pma_attr_port_rcv_constraint_errors.attr.attr,
0725     &port_pma_attr_local_link_integrity_errors.attr.attr,
0726     &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
0727     &port_pma_attr_VL15_dropped.attr.attr,
0728     &port_pma_attr_ext_port_xmit_data.attr.attr,
0729     &port_pma_attr_ext_port_rcv_data.attr.attr,
0730     &port_pma_attr_ext_port_xmit_packets.attr.attr,
0731     &port_pma_attr_ext_port_rcv_packets.attr.attr,
0732     &port_pma_attr_port_xmit_wait.attr.attr,
0733     NULL
0734 };
0735 
0736 static const struct attribute_group pma_group = {
0737     .name  = "counters",
0738     .attrs  = pma_attrs
0739 };
0740 
0741 static const struct attribute_group pma_group_ext = {
0742     .name  = "counters",
0743     .attrs  = pma_attrs_ext
0744 };
0745 
0746 static const struct attribute_group pma_group_noietf = {
0747     .name  = "counters",
0748     .attrs  = pma_attrs_noietf
0749 };
0750 
0751 static void ib_port_release(struct kobject *kobj)
0752 {
0753     struct ib_port *port = container_of(kobj, struct ib_port, kobj);
0754     int i;
0755 
0756     for (i = 0; i != ARRAY_SIZE(port->groups); i++)
0757         kfree(port->groups[i].attrs);
0758     if (port->hw_stats_data)
0759         rdma_free_hw_stats_struct(port->hw_stats_data->stats);
0760     kfree(port->hw_stats_data);
0761     kvfree(port);
0762 }
0763 
0764 static void ib_port_gid_attr_release(struct kobject *kobj)
0765 {
0766     struct gid_attr_group *gid_attr_group =
0767         container_of(kobj, struct gid_attr_group, kobj);
0768     int i;
0769 
0770     for (i = 0; i != ARRAY_SIZE(gid_attr_group->groups); i++)
0771         kfree(gid_attr_group->groups[i].attrs);
0772     kfree(gid_attr_group);
0773 }
0774 
0775 static struct kobj_type port_type = {
0776     .release       = ib_port_release,
0777     .sysfs_ops     = &port_sysfs_ops,
0778     .default_groups = port_default_groups,
0779 };
0780 
0781 static struct kobj_type gid_attr_type = {
0782     .sysfs_ops      = &gid_attr_sysfs_ops,
0783     .release        = ib_port_gid_attr_release
0784 };
0785 
0786 /*
0787  * Figure out which counter table to use depending on
0788  * the device capabilities.
0789  */
0790 static const struct attribute_group *get_counter_table(struct ib_device *dev,
0791                                int port_num)
0792 {
0793     struct ib_class_port_info cpi;
0794 
0795     if (get_perf_mad(dev, port_num, IB_PMA_CLASS_PORT_INFO,
0796                 &cpi, 40, sizeof(cpi)) >= 0) {
0797         if (cpi.capability_mask & IB_PMA_CLASS_CAP_EXT_WIDTH)
0798             /* We have extended counters */
0799             return &pma_group_ext;
0800 
0801         if (cpi.capability_mask & IB_PMA_CLASS_CAP_EXT_WIDTH_NOIETF)
0802             /* But not the IETF ones */
0803             return &pma_group_noietf;
0804     }
0805 
0806     /* Fall back to normal counters */
0807     return &pma_group;
0808 }
0809 
0810 static int update_hw_stats(struct ib_device *dev, struct rdma_hw_stats *stats,
0811                u32 port_num, int index)
0812 {
0813     int ret;
0814 
0815     if (time_is_after_eq_jiffies(stats->timestamp + stats->lifespan))
0816         return 0;
0817     ret = dev->ops.get_hw_stats(dev, stats, port_num, index);
0818     if (ret < 0)
0819         return ret;
0820     if (ret == stats->num_counters)
0821         stats->timestamp = jiffies;
0822 
0823     return 0;
0824 }
0825 
0826 static int print_hw_stat(struct ib_device *dev, int port_num,
0827              struct rdma_hw_stats *stats, int index, char *buf)
0828 {
0829     u64 v = rdma_counter_get_hwstat_value(dev, port_num, index);
0830 
0831     return sysfs_emit(buf, "%llu\n", stats->value[index] + v);
0832 }
0833 
0834 static ssize_t show_hw_stats(struct ib_device *ibdev,
0835                  struct rdma_hw_stats *stats, unsigned int index,
0836                  unsigned int port_num, char *buf)
0837 {
0838     int ret;
0839 
0840     mutex_lock(&stats->lock);
0841     ret = update_hw_stats(ibdev, stats, port_num, index);
0842     if (ret)
0843         goto unlock;
0844     ret = print_hw_stat(ibdev, port_num, stats, index, buf);
0845 unlock:
0846     mutex_unlock(&stats->lock);
0847 
0848     return ret;
0849 }
0850 
0851 static ssize_t show_stats_lifespan(struct ib_device *ibdev,
0852                    struct rdma_hw_stats *stats,
0853                    unsigned int index, unsigned int port_num,
0854                    char *buf)
0855 {
0856     int msecs;
0857 
0858     mutex_lock(&stats->lock);
0859     msecs = jiffies_to_msecs(stats->lifespan);
0860     mutex_unlock(&stats->lock);
0861 
0862     return sysfs_emit(buf, "%d\n", msecs);
0863 }
0864 
0865 static ssize_t set_stats_lifespan(struct ib_device *ibdev,
0866                    struct rdma_hw_stats *stats,
0867                    unsigned int index, unsigned int port_num,
0868                    const char *buf, size_t count)
0869 {
0870     int msecs;
0871     int jiffies;
0872     int ret;
0873 
0874     ret = kstrtoint(buf, 10, &msecs);
0875     if (ret)
0876         return ret;
0877     if (msecs < 0 || msecs > 10000)
0878         return -EINVAL;
0879     jiffies = msecs_to_jiffies(msecs);
0880 
0881     mutex_lock(&stats->lock);
0882     stats->lifespan = jiffies;
0883     mutex_unlock(&stats->lock);
0884 
0885     return count;
0886 }
0887 
0888 static struct hw_stats_device_data *
0889 alloc_hw_stats_device(struct ib_device *ibdev)
0890 {
0891     struct hw_stats_device_data *data;
0892     struct rdma_hw_stats *stats;
0893 
0894     if (!ibdev->ops.alloc_hw_device_stats)
0895         return ERR_PTR(-EOPNOTSUPP);
0896     stats = ibdev->ops.alloc_hw_device_stats(ibdev);
0897     if (!stats)
0898         return ERR_PTR(-ENOMEM);
0899     if (!stats->descs || stats->num_counters <= 0)
0900         goto err_free_stats;
0901 
0902     /*
0903      * Two extra attribue elements here, one for the lifespan entry and
0904      * one to NULL terminate the list for the sysfs core code
0905      */
0906     data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
0907                GFP_KERNEL);
0908     if (!data)
0909         goto err_free_stats;
0910     data->group.attrs = kcalloc(stats->num_counters + 2,
0911                     sizeof(*data->group.attrs), GFP_KERNEL);
0912     if (!data->group.attrs)
0913         goto err_free_data;
0914 
0915     data->group.name = "hw_counters";
0916     data->stats = stats;
0917     return data;
0918 
0919 err_free_data:
0920     kfree(data);
0921 err_free_stats:
0922     rdma_free_hw_stats_struct(stats);
0923     return ERR_PTR(-ENOMEM);
0924 }
0925 
0926 void ib_device_release_hw_stats(struct hw_stats_device_data *data)
0927 {
0928     kfree(data->group.attrs);
0929     rdma_free_hw_stats_struct(data->stats);
0930     kfree(data);
0931 }
0932 
0933 int ib_setup_device_attrs(struct ib_device *ibdev)
0934 {
0935     struct hw_stats_device_attribute *attr;
0936     struct hw_stats_device_data *data;
0937     bool opstat_skipped = false;
0938     int i, ret, pos = 0;
0939 
0940     data = alloc_hw_stats_device(ibdev);
0941     if (IS_ERR(data)) {
0942         if (PTR_ERR(data) == -EOPNOTSUPP)
0943             return 0;
0944         return PTR_ERR(data);
0945     }
0946     ibdev->hw_stats_data = data;
0947 
0948     ret = ibdev->ops.get_hw_stats(ibdev, data->stats, 0,
0949                       data->stats->num_counters);
0950     if (ret != data->stats->num_counters) {
0951         if (WARN_ON(ret >= 0))
0952             return -EINVAL;
0953         return ret;
0954     }
0955 
0956     data->stats->timestamp = jiffies;
0957 
0958     for (i = 0; i < data->stats->num_counters; i++) {
0959         if (data->stats->descs[i].flags & IB_STAT_FLAG_OPTIONAL) {
0960             opstat_skipped = true;
0961             continue;
0962         }
0963 
0964         WARN_ON(opstat_skipped);
0965         attr = &data->attrs[pos];
0966         sysfs_attr_init(&attr->attr.attr);
0967         attr->attr.attr.name = data->stats->descs[i].name;
0968         attr->attr.attr.mode = 0444;
0969         attr->attr.show = hw_stat_device_show;
0970         attr->show = show_hw_stats;
0971         data->group.attrs[pos] = &attr->attr.attr;
0972         pos++;
0973     }
0974 
0975     attr = &data->attrs[pos];
0976     sysfs_attr_init(&attr->attr.attr);
0977     attr->attr.attr.name = "lifespan";
0978     attr->attr.attr.mode = 0644;
0979     attr->attr.show = hw_stat_device_show;
0980     attr->show = show_stats_lifespan;
0981     attr->attr.store = hw_stat_device_store;
0982     attr->store = set_stats_lifespan;
0983     data->group.attrs[pos] = &attr->attr.attr;
0984     for (i = 0; i != ARRAY_SIZE(ibdev->groups); i++)
0985         if (!ibdev->groups[i]) {
0986             ibdev->groups[i] = &data->group;
0987             return 0;
0988         }
0989     WARN(true, "struct ib_device->groups is too small");
0990     return -EINVAL;
0991 }
0992 
0993 static struct hw_stats_port_data *
0994 alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
0995 {
0996     struct ib_device *ibdev = port->ibdev;
0997     struct hw_stats_port_data *data;
0998     struct rdma_hw_stats *stats;
0999 
1000     if (!ibdev->ops.alloc_hw_port_stats)
1001         return ERR_PTR(-EOPNOTSUPP);
1002     stats = ibdev->ops.alloc_hw_port_stats(port->ibdev, port->port_num);
1003     if (!stats)
1004         return ERR_PTR(-ENOMEM);
1005     if (!stats->descs || stats->num_counters <= 0)
1006         goto err_free_stats;
1007 
1008     /*
1009      * Two extra attribue elements here, one for the lifespan entry and
1010      * one to NULL terminate the list for the sysfs core code
1011      */
1012     data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
1013                GFP_KERNEL);
1014     if (!data)
1015         goto err_free_stats;
1016     group->attrs = kcalloc(stats->num_counters + 2,
1017                     sizeof(*group->attrs), GFP_KERNEL);
1018     if (!group->attrs)
1019         goto err_free_data;
1020 
1021     group->name = "hw_counters";
1022     data->stats = stats;
1023     return data;
1024 
1025 err_free_data:
1026     kfree(data);
1027 err_free_stats:
1028     rdma_free_hw_stats_struct(stats);
1029     return ERR_PTR(-ENOMEM);
1030 }
1031 
1032 static int setup_hw_port_stats(struct ib_port *port,
1033                    struct attribute_group *group)
1034 {
1035     struct hw_stats_port_attribute *attr;
1036     struct hw_stats_port_data *data;
1037     bool opstat_skipped = false;
1038     int i, ret, pos = 0;
1039 
1040     data = alloc_hw_stats_port(port, group);
1041     if (IS_ERR(data))
1042         return PTR_ERR(data);
1043 
1044     ret = port->ibdev->ops.get_hw_stats(port->ibdev, data->stats,
1045                         port->port_num,
1046                         data->stats->num_counters);
1047     if (ret != data->stats->num_counters) {
1048         if (WARN_ON(ret >= 0))
1049             return -EINVAL;
1050         return ret;
1051     }
1052 
1053     data->stats->timestamp = jiffies;
1054 
1055     for (i = 0; i < data->stats->num_counters; i++) {
1056         if (data->stats->descs[i].flags & IB_STAT_FLAG_OPTIONAL) {
1057             opstat_skipped = true;
1058             continue;
1059         }
1060 
1061         WARN_ON(opstat_skipped);
1062         attr = &data->attrs[pos];
1063         sysfs_attr_init(&attr->attr.attr);
1064         attr->attr.attr.name = data->stats->descs[i].name;
1065         attr->attr.attr.mode = 0444;
1066         attr->attr.show = hw_stat_port_show;
1067         attr->show = show_hw_stats;
1068         group->attrs[pos] = &attr->attr.attr;
1069         pos++;
1070     }
1071 
1072     attr = &data->attrs[pos];
1073     sysfs_attr_init(&attr->attr.attr);
1074     attr->attr.attr.name = "lifespan";
1075     attr->attr.attr.mode = 0644;
1076     attr->attr.show = hw_stat_port_show;
1077     attr->show = show_stats_lifespan;
1078     attr->attr.store = hw_stat_port_store;
1079     attr->store = set_stats_lifespan;
1080     group->attrs[pos] = &attr->attr.attr;
1081 
1082     port->hw_stats_data = data;
1083     return 0;
1084 }
1085 
1086 struct rdma_hw_stats *ib_get_hw_stats_port(struct ib_device *ibdev,
1087                        u32 port_num)
1088 {
1089     if (!ibdev->port_data || !rdma_is_port_valid(ibdev, port_num) ||
1090         !ibdev->port_data[port_num].sysfs->hw_stats_data)
1091         return NULL;
1092     return ibdev->port_data[port_num].sysfs->hw_stats_data->stats;
1093 }
1094 
1095 static int
1096 alloc_port_table_group(const char *name, struct attribute_group *group,
1097                struct port_table_attribute *attrs, size_t num,
1098                ssize_t (*show)(struct ib_device *ibdev, u32 port_num,
1099                        struct ib_port_attribute *, char *buf))
1100 {
1101     struct attribute **attr_list;
1102     int i;
1103 
1104     attr_list = kcalloc(num + 1, sizeof(*attr_list), GFP_KERNEL);
1105     if (!attr_list)
1106         return -ENOMEM;
1107 
1108     for (i = 0; i < num; i++) {
1109         struct port_table_attribute *element = &attrs[i];
1110 
1111         if (snprintf(element->name, sizeof(element->name), "%d", i) >=
1112             sizeof(element->name))
1113             goto err;
1114 
1115         sysfs_attr_init(&element->attr.attr);
1116         element->attr.attr.name = element->name;
1117         element->attr.attr.mode = 0444;
1118         element->attr.show = show;
1119         element->index = i;
1120 
1121         attr_list[i] = &element->attr.attr;
1122     }
1123     group->name = name;
1124     group->attrs = attr_list;
1125     return 0;
1126 err:
1127     kfree(attr_list);
1128     return -EINVAL;
1129 }
1130 
1131 /*
1132  * Create the sysfs:
1133  *  ibp0s9/ports/XX/gid_attrs/{ndevs,types}/YYY
1134  * YYY is the gid table index in decimal
1135  */
1136 static int setup_gid_attrs(struct ib_port *port,
1137                const struct ib_port_attr *attr)
1138 {
1139     struct gid_attr_group *gid_attr_group;
1140     int ret;
1141 
1142     gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
1143                          attr->gid_tbl_len * 2),
1144                  GFP_KERNEL);
1145     if (!gid_attr_group)
1146         return -ENOMEM;
1147     gid_attr_group->port = port;
1148     kobject_init(&gid_attr_group->kobj, &gid_attr_type);
1149 
1150     ret = alloc_port_table_group("ndevs", &gid_attr_group->groups[0],
1151                      gid_attr_group->attrs_list,
1152                      attr->gid_tbl_len,
1153                      show_port_gid_attr_ndev);
1154     if (ret)
1155         goto err_put;
1156     gid_attr_group->groups_list[0] = &gid_attr_group->groups[0];
1157 
1158     ret = alloc_port_table_group(
1159         "types", &gid_attr_group->groups[1],
1160         gid_attr_group->attrs_list + attr->gid_tbl_len,
1161         attr->gid_tbl_len, show_port_gid_attr_gid_type);
1162     if (ret)
1163         goto err_put;
1164     gid_attr_group->groups_list[1] = &gid_attr_group->groups[1];
1165 
1166     ret = kobject_add(&gid_attr_group->kobj, &port->kobj, "gid_attrs");
1167     if (ret)
1168         goto err_put;
1169     ret = sysfs_create_groups(&gid_attr_group->kobj,
1170                   gid_attr_group->groups_list);
1171     if (ret)
1172         goto err_del;
1173     port->gid_attr_group = gid_attr_group;
1174     return 0;
1175 
1176 err_del:
1177     kobject_del(&gid_attr_group->kobj);
1178 err_put:
1179     kobject_put(&gid_attr_group->kobj);
1180     return ret;
1181 }
1182 
1183 static void destroy_gid_attrs(struct ib_port *port)
1184 {
1185     struct gid_attr_group *gid_attr_group = port->gid_attr_group;
1186 
1187     if (!gid_attr_group)
1188         return;
1189     sysfs_remove_groups(&gid_attr_group->kobj, gid_attr_group->groups_list);
1190     kobject_del(&gid_attr_group->kobj);
1191     kobject_put(&gid_attr_group->kobj);
1192 }
1193 
1194 /*
1195  * Create the sysfs:
1196  *  ibp0s9/ports/XX/{gids,pkeys,counters}/YYY
1197  */
1198 static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
1199                   const struct ib_port_attr *attr)
1200 {
1201     struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1202     bool is_full_dev = &device->coredev == coredev;
1203     const struct attribute_group **cur_group;
1204     struct ib_port *p;
1205     int ret;
1206 
1207     p = kvzalloc(struct_size(p, attrs_list,
1208                 attr->gid_tbl_len + attr->pkey_tbl_len),
1209             GFP_KERNEL);
1210     if (!p)
1211         return ERR_PTR(-ENOMEM);
1212     p->ibdev = device;
1213     p->port_num = port_num;
1214     kobject_init(&p->kobj, &port_type);
1215 
1216     cur_group = p->groups_list;
1217     ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list,
1218                      attr->gid_tbl_len, show_port_gid);
1219     if (ret)
1220         goto err_put;
1221     *cur_group++ = &p->groups[0];
1222 
1223     if (attr->pkey_tbl_len) {
1224         ret = alloc_port_table_group("pkeys", &p->groups[1],
1225                          p->attrs_list + attr->gid_tbl_len,
1226                          attr->pkey_tbl_len, show_port_pkey);
1227         if (ret)
1228             goto err_put;
1229         *cur_group++ = &p->groups[1];
1230     }
1231 
1232     /*
1233      * If port == 0, it means hw_counters are per device and not per
1234      * port, so holder should be device. Therefore skip per port
1235      * counter initialization.
1236      */
1237     if (port_num && is_full_dev) {
1238         ret = setup_hw_port_stats(p, &p->groups[2]);
1239         if (ret && ret != -EOPNOTSUPP)
1240             goto err_put;
1241         if (!ret)
1242             *cur_group++ = &p->groups[2];
1243     }
1244 
1245     if (device->ops.process_mad && is_full_dev)
1246         *cur_group++ = get_counter_table(device, port_num);
1247 
1248     ret = kobject_add(&p->kobj, coredev->ports_kobj, "%d", port_num);
1249     if (ret)
1250         goto err_put;
1251     ret = sysfs_create_groups(&p->kobj, p->groups_list);
1252     if (ret)
1253         goto err_del;
1254     if (is_full_dev) {
1255         ret = sysfs_create_groups(&p->kobj, device->ops.port_groups);
1256         if (ret)
1257             goto err_groups;
1258     }
1259 
1260     list_add_tail(&p->kobj.entry, &coredev->port_list);
1261     if (device->port_data && is_full_dev)
1262         device->port_data[port_num].sysfs = p;
1263 
1264     return p;
1265 
1266 err_groups:
1267     sysfs_remove_groups(&p->kobj, p->groups_list);
1268 err_del:
1269     kobject_del(&p->kobj);
1270 err_put:
1271     kobject_put(&p->kobj);
1272     return ERR_PTR(ret);
1273 }
1274 
1275 static void destroy_port(struct ib_core_device *coredev, struct ib_port *port)
1276 {
1277     bool is_full_dev = &port->ibdev->coredev == coredev;
1278 
1279     if (port->ibdev->port_data &&
1280         port->ibdev->port_data[port->port_num].sysfs == port)
1281         port->ibdev->port_data[port->port_num].sysfs = NULL;
1282     list_del(&port->kobj.entry);
1283     if (is_full_dev)
1284         sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups);
1285     sysfs_remove_groups(&port->kobj, port->groups_list);
1286     kobject_del(&port->kobj);
1287     kobject_put(&port->kobj);
1288 }
1289 
1290 static const char *node_type_string(int node_type)
1291 {
1292     switch (node_type) {
1293     case RDMA_NODE_IB_CA:
1294         return "CA";
1295     case RDMA_NODE_IB_SWITCH:
1296         return "switch";
1297     case RDMA_NODE_IB_ROUTER:
1298         return "router";
1299     case RDMA_NODE_RNIC:
1300         return "RNIC";
1301     case RDMA_NODE_USNIC:
1302         return "usNIC";
1303     case RDMA_NODE_USNIC_UDP:
1304         return "usNIC UDP";
1305     case RDMA_NODE_UNSPECIFIED:
1306         return "unspecified";
1307     }
1308     return "<unknown>";
1309 }
1310 
1311 static ssize_t node_type_show(struct device *device,
1312                   struct device_attribute *attr, char *buf)
1313 {
1314     struct ib_device *dev = rdma_device_to_ibdev(device);
1315 
1316     return sysfs_emit(buf, "%u: %s\n", dev->node_type,
1317               node_type_string(dev->node_type));
1318 }
1319 static DEVICE_ATTR_RO(node_type);
1320 
1321 static ssize_t sys_image_guid_show(struct device *device,
1322                    struct device_attribute *dev_attr, char *buf)
1323 {
1324     struct ib_device *dev = rdma_device_to_ibdev(device);
1325     __be16 *guid = (__be16 *)&dev->attrs.sys_image_guid;
1326 
1327     return sysfs_emit(buf, "%04x:%04x:%04x:%04x\n",
1328               be16_to_cpu(guid[0]),
1329               be16_to_cpu(guid[1]),
1330               be16_to_cpu(guid[2]),
1331               be16_to_cpu(guid[3]));
1332 }
1333 static DEVICE_ATTR_RO(sys_image_guid);
1334 
1335 static ssize_t node_guid_show(struct device *device,
1336                   struct device_attribute *attr, char *buf)
1337 {
1338     struct ib_device *dev = rdma_device_to_ibdev(device);
1339     __be16 *node_guid = (__be16 *)&dev->node_guid;
1340 
1341     return sysfs_emit(buf, "%04x:%04x:%04x:%04x\n",
1342               be16_to_cpu(node_guid[0]),
1343               be16_to_cpu(node_guid[1]),
1344               be16_to_cpu(node_guid[2]),
1345               be16_to_cpu(node_guid[3]));
1346 }
1347 static DEVICE_ATTR_RO(node_guid);
1348 
1349 static ssize_t node_desc_show(struct device *device,
1350                   struct device_attribute *attr, char *buf)
1351 {
1352     struct ib_device *dev = rdma_device_to_ibdev(device);
1353 
1354     return sysfs_emit(buf, "%.64s\n", dev->node_desc);
1355 }
1356 
1357 static ssize_t node_desc_store(struct device *device,
1358                    struct device_attribute *attr,
1359                    const char *buf, size_t count)
1360 {
1361     struct ib_device *dev = rdma_device_to_ibdev(device);
1362     struct ib_device_modify desc = {};
1363     int ret;
1364 
1365     if (!dev->ops.modify_device)
1366         return -EOPNOTSUPP;
1367 
1368     memcpy(desc.node_desc, buf, min_t(int, count, IB_DEVICE_NODE_DESC_MAX));
1369     ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
1370     if (ret)
1371         return ret;
1372 
1373     return count;
1374 }
1375 static DEVICE_ATTR_RW(node_desc);
1376 
1377 static ssize_t fw_ver_show(struct device *device, struct device_attribute *attr,
1378                char *buf)
1379 {
1380     struct ib_device *dev = rdma_device_to_ibdev(device);
1381     char version[IB_FW_VERSION_NAME_MAX] = {};
1382 
1383     ib_get_device_fw_str(dev, version);
1384 
1385     return sysfs_emit(buf, "%s\n", version);
1386 }
1387 static DEVICE_ATTR_RO(fw_ver);
1388 
1389 static struct attribute *ib_dev_attrs[] = {
1390     &dev_attr_node_type.attr,
1391     &dev_attr_node_guid.attr,
1392     &dev_attr_sys_image_guid.attr,
1393     &dev_attr_fw_ver.attr,
1394     &dev_attr_node_desc.attr,
1395     NULL,
1396 };
1397 
1398 const struct attribute_group ib_dev_attr_group = {
1399     .attrs = ib_dev_attrs,
1400 };
1401 
1402 void ib_free_port_attrs(struct ib_core_device *coredev)
1403 {
1404     struct kobject *p, *t;
1405 
1406     list_for_each_entry_safe(p, t, &coredev->port_list, entry) {
1407         struct ib_port *port = container_of(p, struct ib_port, kobj);
1408 
1409         destroy_gid_attrs(port);
1410         destroy_port(coredev, port);
1411     }
1412 
1413     kobject_put(coredev->ports_kobj);
1414 }
1415 
1416 int ib_setup_port_attrs(struct ib_core_device *coredev)
1417 {
1418     struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1419     u32 port_num;
1420     int ret;
1421 
1422     coredev->ports_kobj = kobject_create_and_add("ports",
1423                              &coredev->dev.kobj);
1424     if (!coredev->ports_kobj)
1425         return -ENOMEM;
1426 
1427     rdma_for_each_port (device, port_num) {
1428         struct ib_port_attr attr;
1429         struct ib_port *port;
1430 
1431         ret = ib_query_port(device, port_num, &attr);
1432         if (ret)
1433             goto err_put;
1434 
1435         port = setup_port(coredev, port_num, &attr);
1436         if (IS_ERR(port)) {
1437             ret = PTR_ERR(port);
1438             goto err_put;
1439         }
1440 
1441         ret = setup_gid_attrs(port, &attr);
1442         if (ret)
1443             goto err_put;
1444     }
1445     return 0;
1446 
1447 err_put:
1448     ib_free_port_attrs(coredev);
1449     return ret;
1450 }
1451 
1452 /**
1453  * ib_port_register_client_groups - Add an ib_client's attributes to the port
1454  *
1455  * @ibdev: IB device to add counters
1456  * @port_num: valid port number
1457  * @groups: Group list of attributes
1458  *
1459  * Do not use. Only for legacy sysfs compatibility.
1460  */
1461 int ib_port_register_client_groups(struct ib_device *ibdev, u32 port_num,
1462                    const struct attribute_group **groups)
1463 {
1464     return sysfs_create_groups(&ibdev->port_data[port_num].sysfs->kobj,
1465                    groups);
1466 }
1467 EXPORT_SYMBOL(ib_port_register_client_groups);
1468 
1469 void ib_port_unregister_client_groups(struct ib_device *ibdev, u32 port_num,
1470                       const struct attribute_group **groups)
1471 {
1472     return sysfs_remove_groups(&ibdev->port_data[port_num].sysfs->kobj,
1473                    groups);
1474 }
1475 EXPORT_SYMBOL(ib_port_unregister_client_groups);