root/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. board_id_show
  2. config_show
  3. iface_show
  4. max_vf_show
  5. qp_per_vf_show
  6. cq_per_vf_show
  7. usnic_ib_qpn_attr_show
  8. context_show
  9. summary_show
  10. usnic_ib_sysfs_register_usdev
  11. usnic_ib_sysfs_unregister_usdev
  12. usnic_ib_sysfs_qpn_add
  13. usnic_ib_sysfs_qpn_remove

   1 /*
   2  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
   3  *
   4  * This software is available to you under a choice of one of two
   5  * licenses.  You may choose to be licensed under the terms of the GNU
   6  * General Public License (GPL) Version 2, available from the file
   7  * COPYING in the main directory of this source tree, or the
   8  * BSD license below:
   9  *
  10  *     Redistribution and use in source and binary forms, with or
  11  *     without modification, are permitted provided that the following
  12  *     conditions are met:
  13  *
  14  *      - Redistributions of source code must retain the above
  15  *        copyright notice, this list of conditions and the following
  16  *        disclaimer.
  17  *
  18  *      - Redistributions in binary form must reproduce the above
  19  *        copyright notice, this list of conditions and the following
  20  *        disclaimer in the documentation and/or other materials
  21  *        provided with the distribution.
  22  *
  23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30  * SOFTWARE.
  31  *
  32  */
  33 
  34 #include <linux/module.h>
  35 #include <linux/init.h>
  36 #include <linux/errno.h>
  37 
  38 #include <rdma/ib_user_verbs.h>
  39 #include <rdma/ib_addr.h>
  40 
  41 #include "usnic_common_util.h"
  42 #include "usnic_ib.h"
  43 #include "usnic_ib_qp_grp.h"
  44 #include "usnic_vnic.h"
  45 #include "usnic_ib_verbs.h"
  46 #include "usnic_ib_sysfs.h"
  47 #include "usnic_log.h"
  48 
  49 static ssize_t board_id_show(struct device *device,
  50                              struct device_attribute *attr, char *buf)
  51 {
  52         struct usnic_ib_dev *us_ibdev =
  53                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
  54         unsigned short subsystem_device_id;
  55 
  56         mutex_lock(&us_ibdev->usdev_lock);
  57         subsystem_device_id = us_ibdev->pdev->subsystem_device;
  58         mutex_unlock(&us_ibdev->usdev_lock);
  59 
  60         return scnprintf(buf, PAGE_SIZE, "%hu\n", subsystem_device_id);
  61 }
  62 static DEVICE_ATTR_RO(board_id);
  63 
  64 /*
  65  * Report the configuration for this PF
  66  */
  67 static ssize_t
  68 config_show(struct device *device, struct device_attribute *attr, char *buf)
  69 {
  70         struct usnic_ib_dev *us_ibdev =
  71                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
  72         char *ptr;
  73         unsigned left;
  74         unsigned n;
  75         enum usnic_vnic_res_type res_type;
  76 
  77         /* Buffer space limit is 1 page */
  78         ptr = buf;
  79         left = PAGE_SIZE;
  80 
  81         mutex_lock(&us_ibdev->usdev_lock);
  82         if (kref_read(&us_ibdev->vf_cnt) > 0) {
  83                 char *busname;
  84 
  85                 /*
  86                  * bus name seems to come with annoying prefix.
  87                  * Remove it if it is predictable
  88                  */
  89                 busname = us_ibdev->pdev->bus->name;
  90                 if (strncmp(busname, "PCI Bus ", 8) == 0)
  91                         busname += 8;
  92 
  93                 n = scnprintf(ptr, left,
  94                         "%s: %s:%d.%d, %s, %pM, %u VFs\n Per VF:",
  95                         dev_name(&us_ibdev->ib_dev.dev),
  96                         busname,
  97                         PCI_SLOT(us_ibdev->pdev->devfn),
  98                         PCI_FUNC(us_ibdev->pdev->devfn),
  99                         netdev_name(us_ibdev->netdev),
 100                         us_ibdev->ufdev->mac,
 101                         kref_read(&us_ibdev->vf_cnt));
 102                 UPDATE_PTR_LEFT(n, ptr, left);
 103 
 104                 for (res_type = USNIC_VNIC_RES_TYPE_EOL;
 105                                 res_type < USNIC_VNIC_RES_TYPE_MAX;
 106                                 res_type++) {
 107                         if (us_ibdev->vf_res_cnt[res_type] == 0)
 108                                 continue;
 109                         n = scnprintf(ptr, left, " %d %s%s",
 110                                 us_ibdev->vf_res_cnt[res_type],
 111                                 usnic_vnic_res_type_to_str(res_type),
 112                                 (res_type < (USNIC_VNIC_RES_TYPE_MAX - 1)) ?
 113                                  "," : "");
 114                         UPDATE_PTR_LEFT(n, ptr, left);
 115                 }
 116                 n = scnprintf(ptr, left, "\n");
 117                 UPDATE_PTR_LEFT(n, ptr, left);
 118         } else {
 119                 n = scnprintf(ptr, left, "%s: no VFs\n",
 120                                 dev_name(&us_ibdev->ib_dev.dev));
 121                 UPDATE_PTR_LEFT(n, ptr, left);
 122         }
 123         mutex_unlock(&us_ibdev->usdev_lock);
 124 
 125         return ptr - buf;
 126 }
 127 static DEVICE_ATTR_RO(config);
 128 
 129 static ssize_t
 130 iface_show(struct device *device, struct device_attribute *attr, char *buf)
 131 {
 132         struct usnic_ib_dev *us_ibdev =
 133                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
 134 
 135         return scnprintf(buf, PAGE_SIZE, "%s\n",
 136                         netdev_name(us_ibdev->netdev));
 137 }
 138 static DEVICE_ATTR_RO(iface);
 139 
 140 static ssize_t
 141 max_vf_show(struct device *device, struct device_attribute *attr, char *buf)
 142 {
 143         struct usnic_ib_dev *us_ibdev =
 144                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
 145 
 146         return scnprintf(buf, PAGE_SIZE, "%u\n",
 147                         kref_read(&us_ibdev->vf_cnt));
 148 }
 149 static DEVICE_ATTR_RO(max_vf);
 150 
 151 static ssize_t
 152 qp_per_vf_show(struct device *device, struct device_attribute *attr, char *buf)
 153 {
 154         struct usnic_ib_dev *us_ibdev =
 155                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
 156         int qp_per_vf;
 157 
 158         qp_per_vf = max(us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_WQ],
 159                         us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_RQ]);
 160 
 161         return scnprintf(buf, PAGE_SIZE,
 162                                 "%d\n", qp_per_vf);
 163 }
 164 static DEVICE_ATTR_RO(qp_per_vf);
 165 
 166 static ssize_t
 167 cq_per_vf_show(struct device *device, struct device_attribute *attr, char *buf)
 168 {
 169         struct usnic_ib_dev *us_ibdev =
 170                 rdma_device_to_drv_device(device, struct usnic_ib_dev, ib_dev);
 171 
 172         return scnprintf(buf, PAGE_SIZE, "%d\n",
 173                         us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ]);
 174 }
 175 static DEVICE_ATTR_RO(cq_per_vf);
 176 
 177 static struct attribute *usnic_class_attributes[] = {
 178         &dev_attr_board_id.attr,
 179         &dev_attr_config.attr,
 180         &dev_attr_iface.attr,
 181         &dev_attr_max_vf.attr,
 182         &dev_attr_qp_per_vf.attr,
 183         &dev_attr_cq_per_vf.attr,
 184         NULL
 185 };
 186 
 187 const struct attribute_group usnic_attr_group = {
 188         .attrs = usnic_class_attributes,
 189 };
 190 
 191 struct qpn_attribute {
 192         struct attribute attr;
 193         ssize_t (*show)(struct usnic_ib_qp_grp *, char *buf);
 194 };
 195 
 196 /*
 197  * Definitions for supporting QPN entries in sysfs
 198  */
 199 static ssize_t
 200 usnic_ib_qpn_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
 201 {
 202         struct usnic_ib_qp_grp *qp_grp;
 203         struct qpn_attribute *qpn_attr;
 204 
 205         qp_grp = container_of(kobj, struct usnic_ib_qp_grp, kobj);
 206         qpn_attr = container_of(attr, struct qpn_attribute, attr);
 207 
 208         return qpn_attr->show(qp_grp, buf);
 209 }
 210 
 211 static const struct sysfs_ops usnic_ib_qpn_sysfs_ops = {
 212         .show = usnic_ib_qpn_attr_show
 213 };
 214 
 215 #define QPN_ATTR_RO(NAME) \
 216 struct qpn_attribute qpn_attr_##NAME = __ATTR_RO(NAME)
 217 
 218 static ssize_t context_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
 219 {
 220         return scnprintf(buf, PAGE_SIZE, "0x%p\n", qp_grp->ctx);
 221 }
 222 
 223 static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
 224 {
 225         int i, j, n;
 226         int left;
 227         char *ptr;
 228         struct usnic_vnic_res_chunk *res_chunk;
 229         struct usnic_vnic_res *vnic_res;
 230 
 231         left = PAGE_SIZE;
 232         ptr = buf;
 233 
 234         n = scnprintf(ptr, left,
 235                         "QPN: %d State: (%s) PID: %u VF Idx: %hu ",
 236                         qp_grp->ibqp.qp_num,
 237                         usnic_ib_qp_grp_state_to_string(qp_grp->state),
 238                         qp_grp->owner_pid,
 239                         usnic_vnic_get_index(qp_grp->vf->vnic));
 240         UPDATE_PTR_LEFT(n, ptr, left);
 241 
 242         for (i = 0; qp_grp->res_chunk_list[i]; i++) {
 243                 res_chunk = qp_grp->res_chunk_list[i];
 244                 for (j = 0; j < res_chunk->cnt; j++) {
 245                         vnic_res = res_chunk->res[j];
 246                         n = scnprintf(ptr, left, "%s[%d] ",
 247                                 usnic_vnic_res_type_to_str(vnic_res->type),
 248                                 vnic_res->vnic_idx);
 249                         UPDATE_PTR_LEFT(n, ptr, left);
 250                 }
 251         }
 252 
 253         n = scnprintf(ptr, left, "\n");
 254         UPDATE_PTR_LEFT(n, ptr, left);
 255 
 256         return ptr - buf;
 257 }
 258 
 259 static QPN_ATTR_RO(context);
 260 static QPN_ATTR_RO(summary);
 261 
 262 static struct attribute *usnic_ib_qpn_default_attrs[] = {
 263         &qpn_attr_context.attr,
 264         &qpn_attr_summary.attr,
 265         NULL
 266 };
 267 
 268 static struct kobj_type usnic_ib_qpn_type = {
 269         .sysfs_ops = &usnic_ib_qpn_sysfs_ops,
 270         .default_attrs = usnic_ib_qpn_default_attrs
 271 };
 272 
 273 int usnic_ib_sysfs_register_usdev(struct usnic_ib_dev *us_ibdev)
 274 {
 275         /* create kernel object for looking at individual QPs */
 276         kobject_get(&us_ibdev->ib_dev.dev.kobj);
 277         us_ibdev->qpn_kobj = kobject_create_and_add("qpn",
 278                         &us_ibdev->ib_dev.dev.kobj);
 279         if (us_ibdev->qpn_kobj == NULL) {
 280                 kobject_put(&us_ibdev->ib_dev.dev.kobj);
 281                 return -ENOMEM;
 282         }
 283 
 284         return 0;
 285 }
 286 
 287 void usnic_ib_sysfs_unregister_usdev(struct usnic_ib_dev *us_ibdev)
 288 {
 289         kobject_put(us_ibdev->qpn_kobj);
 290 }
 291 
 292 void usnic_ib_sysfs_qpn_add(struct usnic_ib_qp_grp *qp_grp)
 293 {
 294         struct usnic_ib_dev *us_ibdev;
 295         int err;
 296 
 297         us_ibdev = qp_grp->vf->pf;
 298 
 299         err = kobject_init_and_add(&qp_grp->kobj, &usnic_ib_qpn_type,
 300                         kobject_get(us_ibdev->qpn_kobj),
 301                         "%d", qp_grp->grp_id);
 302         if (err) {
 303                 kobject_put(us_ibdev->qpn_kobj);
 304                 return;
 305         }
 306 }
 307 
 308 void usnic_ib_sysfs_qpn_remove(struct usnic_ib_qp_grp *qp_grp)
 309 {
 310         struct usnic_ib_dev *us_ibdev;
 311 
 312         us_ibdev = qp_grp->vf->pf;
 313 
 314         kobject_put(&qp_grp->kobj);
 315         kobject_put(us_ibdev->qpn_kobj);
 316 }

/* [<][>][^][v][top][bottom][index][help] */