1 /* 2 * Copyright (c) 2012 Mellanox Technologies. 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 * OpenIB.org 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 /*#include "core_priv.h"*/ 34 #include "mlx4_ib.h" 35 #include <linux/slab.h> 36 #include <linux/string.h> 37 #include <linux/stat.h> 38 39 #include <rdma/ib_mad.h> 40 /*show_admin_alias_guid returns the administratively assigned value of that GUID. 41 * Values returned in buf parameter string: 42 * 0 - requests opensm to assign a value. 43 * ffffffffffffffff - delete this entry. 44 * other - value assigned by administrator. 45 */ 46 static ssize_t show_admin_alias_guid(struct device *dev, 47 struct device_attribute *attr, char *buf) 48 { 49 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry = 50 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry); 51 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx; 52 struct mlx4_ib_dev *mdev = port->dev; 53 __be64 sysadmin_ag_val; 54 55 sysadmin_ag_val = mlx4_get_admin_guid(mdev->dev, 56 mlx4_ib_iov_dentry->entry_num, 57 port->num); 58 59 return sysfs_emit(buf, "%llx\n", be64_to_cpu(sysadmin_ag_val)); 60 } 61 62 /* store_admin_alias_guid stores the (new) administratively assigned value of that GUID. 63 * Values in buf parameter string: 64 * 0 - requests opensm to assign a value. 65 * 0xffffffffffffffff - delete this entry. 66 * other - guid value assigned by the administrator. 67 */ 68 static ssize_t store_admin_alias_guid(struct device *dev, 69 struct device_attribute *attr, 70 const char *buf, size_t count) 71 { 72 int record_num;/*0-15*/ 73 int guid_index_in_rec; /*0 - 7*/ 74 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry = 75 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry); 76 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx; 77 struct mlx4_ib_dev *mdev = port->dev; 78 u64 sysadmin_ag_val; 79 unsigned long flags; 80 81 record_num = mlx4_ib_iov_dentry->entry_num / 8; 82 guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8; 83 if (0 == record_num && 0 == guid_index_in_rec) { 84 pr_err("GUID 0 block 0 is RO\n"); 85 return count; 86 } 87 spin_lock_irqsave(&mdev->sriov.alias_guid.ag_work_lock, flags); 88 sscanf(buf, "%llx", &sysadmin_ag_val); 89 *(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1]. 90 all_rec_per_port[record_num]. 91 all_recs[GUID_REC_SIZE * guid_index_in_rec] = 92 cpu_to_be64(sysadmin_ag_val); 93 94 /* Change the state to be pending for update */ 95 mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status 96 = MLX4_GUID_INFO_STATUS_IDLE ; 97 mlx4_set_admin_guid(mdev->dev, cpu_to_be64(sysadmin_ag_val), 98 mlx4_ib_iov_dentry->entry_num, 99 port->num); 100 101 /* set the record index */ 102 mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes 103 |= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec); 104 105 spin_unlock_irqrestore(&mdev->sriov.alias_guid.ag_work_lock, flags); 106 mlx4_ib_init_alias_guid_work(mdev, port->num - 1); 107 108 return count; 109 } 110 111 static ssize_t show_port_gid(struct device *dev, 112 struct device_attribute *attr, 113 char *buf) 114 { 115 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry = 116 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry); 117 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx; 118 struct mlx4_ib_dev *mdev = port->dev; 119 union ib_gid gid; 120 int ret; 121 __be16 *raw; 122 123 ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num, 124 mlx4_ib_iov_dentry->entry_num, &gid, 1); 125 if (ret) 126 return ret; 127 128 raw = (__be16 *)gid.raw; 129 return sysfs_emit(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 130 be16_to_cpu(raw[0]), 131 be16_to_cpu(raw[1]), 132 be16_to_cpu(raw[2]), 133 be16_to_cpu(raw[3]), 134 be16_to_cpu(raw[4]), 135 be16_to_cpu(raw[5]), 136 be16_to_cpu(raw[6]), 137 be16_to_cpu(raw[7])); 138 } 139 140 static ssize_t show_phys_port_pkey(struct device *dev, 141 struct device_attribute *attr, 142 char *buf) 143 { 144 struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry = 145 container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry); 146 struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx; 147 struct mlx4_ib_dev *mdev = port->dev; 148 u16 pkey; 149 ssize_t ret; 150 151 ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num, 152 mlx4_ib_iov_dentry->entry_num, &pkey, 1); 153 if (ret) 154 return ret; 155 156 return sysfs_emit(buf, "0x%04x\n", pkey); 157 } 158 159 #define DENTRY_REMOVE(_dentry) \ 160 do { \ 161 sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr); \ 162 } while (0); 163 164 static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry, 165 char *_name, struct kobject *_kobj, 166 ssize_t (*show)(struct device *dev, 167 struct device_attribute *attr, 168 char *buf), 169 ssize_t (*store)(struct device *dev, 170 struct device_attribute *attr, 171 const char *buf, size_t count) 172 ) 173 { 174 int ret = 0; 175 struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry; 176 177 vdentry->ctx = _ctx; 178 vdentry->dentry.show = show; 179 vdentry->dentry.store = store; 180 sysfs_attr_init(&vdentry->dentry.attr); 181 vdentry->dentry.attr.name = vdentry->name; 182 vdentry->dentry.attr.mode = 0; 183 vdentry->kobj = _kobj; 184 snprintf(vdentry->name, 15, "%s", _name); 185 186 if (vdentry->dentry.store) 187 vdentry->dentry.attr.mode |= S_IWUSR; 188 189 if (vdentry->dentry.show) 190 vdentry->dentry.attr.mode |= S_IRUGO; 191 192 ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr); 193 if (ret) { 194 pr_err("failed to create %s\n", vdentry->dentry.attr.name); 195 vdentry->ctx = NULL; 196 return ret; 197 } 198 199 return ret; 200 } 201 202 int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, 203 struct attribute *attr) 204 { 205 struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1]; 206 int ret; 207 208 ret = sysfs_create_file(port->mcgs_parent, attr); 209 if (ret) 210 pr_err("failed to create %s\n", attr->name); 211 212 return ret; 213 } 214 215 void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, 216 struct attribute *attr) 217 { 218 struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1]; 219 220 sysfs_remove_file(port->mcgs_parent, attr); 221 } 222 223 static int add_port_entries(struct mlx4_ib_dev *device, int port_num) 224 { 225 int i; 226 char buff[12]; 227 struct mlx4_ib_iov_port *port = NULL; 228 int ret = 0 ; 229 struct ib_port_attr attr; 230 231 memset(&attr, 0, sizeof(attr)); 232 /* get the physical gid and pkey table sizes.*/ 233 ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1); 234 if (ret) 235 goto err; 236 237 port = &device->iov_ports[port_num - 1]; 238 port->dev = device; 239 port->num = port_num; 240 /* Directory structure: 241 * iov - 242 * port num - 243 * admin_guids 244 * gids (operational) 245 * mcg_table 246 */ 247 port->dentr_ar = kzalloc_obj(struct mlx4_ib_iov_sysfs_attr_ar); 248 if (!port->dentr_ar) { 249 ret = -ENOMEM; 250 goto err; 251 } 252 sprintf(buff, "%d", port_num); 253 port->cur_port = kobject_create_and_add(buff, 254 kobject_get(device->ports_parent)); 255 if (!port->cur_port) { 256 ret = -ENOMEM; 257 goto kobj_create_err; 258 } 259 /* admin GUIDs */ 260 port->admin_alias_parent = kobject_create_and_add("admin_guids", 261 kobject_get(port->cur_port)); 262 if (!port->admin_alias_parent) { 263 ret = -ENOMEM; 264 goto err_admin_guids; 265 } 266 for (i = 0 ; i < attr.gid_tbl_len; i++) { 267 sprintf(buff, "%d", i); 268 port->dentr_ar->dentries[i].entry_num = i; 269 ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i], 270 buff, port->admin_alias_parent, 271 show_admin_alias_guid, store_admin_alias_guid); 272 if (ret) 273 goto err_admin_alias_parent; 274 } 275 276 /* gids subdirectory (operational gids) */ 277 port->gids_parent = kobject_create_and_add("gids", 278 kobject_get(port->cur_port)); 279 if (!port->gids_parent) { 280 ret = -ENOMEM; 281 goto err_gids; 282 } 283 284 for (i = 0 ; i < attr.gid_tbl_len; i++) { 285 sprintf(buff, "%d", i); 286 port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i; 287 ret = create_sysfs_entry(port, 288 &port->dentr_ar->dentries[attr.gid_tbl_len + i], 289 buff, 290 port->gids_parent, show_port_gid, NULL); 291 if (ret) 292 goto err_gids_parent; 293 } 294 295 /* physical port pkey table */ 296 port->pkeys_parent = 297 kobject_create_and_add("pkeys", kobject_get(port->cur_port)); 298 if (!port->pkeys_parent) { 299 ret = -ENOMEM; 300 goto err_pkeys; 301 } 302 303 for (i = 0 ; i < attr.pkey_tbl_len; i++) { 304 sprintf(buff, "%d", i); 305 port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i; 306 ret = create_sysfs_entry(port, 307 &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i], 308 buff, port->pkeys_parent, 309 show_phys_port_pkey, NULL); 310 if (ret) 311 goto err_pkeys_parent; 312 } 313 314 /* MCGs table */ 315 port->mcgs_parent = 316 kobject_create_and_add("mcgs", kobject_get(port->cur_port)); 317 if (!port->mcgs_parent) { 318 ret = -ENOMEM; 319 goto err_mcgs; 320 } 321 return 0; 322 323 err_mcgs: 324 kobject_put(port->cur_port); 325 326 err_pkeys_parent: 327 kobject_put(port->pkeys_parent); 328 329 err_pkeys: 330 kobject_put(port->cur_port); 331 332 err_gids_parent: 333 kobject_put(port->gids_parent); 334 335 err_gids: 336 kobject_put(port->cur_port); 337 338 err_admin_alias_parent: 339 kobject_put(port->admin_alias_parent); 340 341 err_admin_guids: 342 kobject_put(port->cur_port); 343 kobject_put(port->cur_port); /* once more for create_and_add buff */ 344 345 kobj_create_err: 346 kobject_put(device->ports_parent); 347 kfree(port->dentr_ar); 348 349 err: 350 pr_err("add_port_entries FAILED: for port:%d, error: %d\n", 351 port_num, ret); 352 return ret; 353 } 354 355 static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max) 356 { 357 /* pci_name format is: bus:dev:func -> xxxx:yy:zz.n 358 * with no ARI only 3 last bits are used so when the fn is higher than 8 359 * need to add it to the dev num, so count in the last number will be 360 * modulo 8 */ 361 snprintf(name, max, "%.8s%.2d.%d", pci_name(dev->dev->persist->pdev), 362 i / 8, i % 8); 363 } 364 365 struct mlx4_port { 366 struct kobject kobj; 367 struct mlx4_ib_dev *dev; 368 struct attribute_group pkey_group; 369 struct attribute_group gid_group; 370 struct device_attribute enable_smi_admin; 371 struct device_attribute smi_enabled; 372 int slave; 373 u8 port_num; 374 }; 375 376 377 static void mlx4_port_release(struct kobject *kobj) 378 { 379 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj); 380 struct attribute *a; 381 int i; 382 383 for (i = 0; (a = p->pkey_group.attrs[i]); ++i) 384 kfree(a); 385 kfree(p->pkey_group.attrs); 386 for (i = 0; (a = p->gid_group.attrs[i]); ++i) 387 kfree(a); 388 kfree(p->gid_group.attrs); 389 kfree(p); 390 } 391 392 struct port_attribute { 393 struct attribute attr; 394 ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf); 395 ssize_t (*store)(struct mlx4_port *, struct port_attribute *, 396 const char *buf, size_t count); 397 }; 398 399 static ssize_t port_attr_show(struct kobject *kobj, 400 struct attribute *attr, char *buf) 401 { 402 struct port_attribute *port_attr = 403 container_of(attr, struct port_attribute, attr); 404 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj); 405 406 if (!port_attr->show) 407 return -EIO; 408 return port_attr->show(p, port_attr, buf); 409 } 410 411 static ssize_t port_attr_store(struct kobject *kobj, 412 struct attribute *attr, 413 const char *buf, size_t size) 414 { 415 struct port_attribute *port_attr = 416 container_of(attr, struct port_attribute, attr); 417 struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj); 418 419 if (!port_attr->store) 420 return -EIO; 421 return port_attr->store(p, port_attr, buf, size); 422 } 423 424 static const struct sysfs_ops port_sysfs_ops = { 425 .show = port_attr_show, 426 .store = port_attr_store, 427 }; 428 429 static struct kobj_type port_type = { 430 .release = mlx4_port_release, 431 .sysfs_ops = &port_sysfs_ops, 432 }; 433 434 struct port_table_attribute { 435 struct port_attribute attr; 436 char name[8]; 437 int index; 438 }; 439 440 static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr, 441 char *buf) 442 { 443 struct port_table_attribute *tab_attr = 444 container_of(attr, struct port_table_attribute, attr); 445 struct pkey_mgt *m = &p->dev->pkeys; 446 u8 key = m->virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index]; 447 448 if (key >= p->dev->dev->caps.pkey_table_len[p->port_num]) 449 return sysfs_emit(buf, "none\n"); 450 return sysfs_emit(buf, "%d\n", key); 451 } 452 453 static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr, 454 const char *buf, size_t count) 455 { 456 struct port_table_attribute *tab_attr = 457 container_of(attr, struct port_table_attribute, attr); 458 int idx; 459 int err; 460 461 /* do not allow remapping Dom0 virtual pkey table */ 462 if (p->slave == mlx4_master_func_num(p->dev->dev)) 463 return -EINVAL; 464 465 if (!strncasecmp(buf, "no", 2)) 466 idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1; 467 else if (sscanf(buf, "%i", &idx) != 1 || 468 idx >= p->dev->dev->caps.pkey_table_len[p->port_num] || 469 idx < 0) 470 return -EINVAL; 471 472 p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1] 473 [tab_attr->index] = idx; 474 mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num, 475 tab_attr->index, idx); 476 err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num); 477 if (err) { 478 pr_err("mlx4_gen_pkey_eqe failed for slave %d," 479 " port %d, index %d\n", p->slave, p->port_num, idx); 480 return err; 481 } 482 return count; 483 } 484 485 static ssize_t show_port_gid_idx(struct mlx4_port *p, 486 struct port_attribute *attr, char *buf) 487 { 488 return sysfs_emit(buf, "%d\n", p->slave); 489 } 490 491 static struct attribute ** 492 alloc_group_attrs(ssize_t (*show)(struct mlx4_port *, 493 struct port_attribute *, char *buf), 494 ssize_t (*store)(struct mlx4_port *, struct port_attribute *, 495 const char *buf, size_t count), 496 int len) 497 { 498 struct attribute **tab_attr; 499 struct port_table_attribute *element; 500 int i; 501 502 tab_attr = kzalloc_objs(struct attribute *, 1 + len); 503 if (!tab_attr) 504 return NULL; 505 506 for (i = 0; i < len; i++) { 507 element = kzalloc_obj(struct port_table_attribute); 508 if (!element) 509 goto err; 510 if (snprintf(element->name, sizeof (element->name), 511 "%d", i) >= sizeof (element->name)) { 512 kfree(element); 513 goto err; 514 } 515 sysfs_attr_init(&element->attr.attr); 516 element->attr.attr.name = element->name; 517 if (store) { 518 element->attr.attr.mode = S_IWUSR | S_IRUGO; 519 element->attr.store = store; 520 } else 521 element->attr.attr.mode = S_IRUGO; 522 523 element->attr.show = show; 524 element->index = i; 525 tab_attr[i] = &element->attr.attr; 526 } 527 return tab_attr; 528 529 err: 530 while (--i >= 0) 531 kfree(tab_attr[i]); 532 kfree(tab_attr); 533 return NULL; 534 } 535 536 static ssize_t sysfs_show_smi_enabled(struct device *dev, 537 struct device_attribute *attr, char *buf) 538 { 539 struct mlx4_port *p = 540 container_of(attr, struct mlx4_port, smi_enabled); 541 542 return sysfs_emit(buf, "%d\n", 543 !!mlx4_vf_smi_enabled(p->dev->dev, p->slave, 544 p->port_num)); 545 } 546 547 static ssize_t sysfs_show_enable_smi_admin(struct device *dev, 548 struct device_attribute *attr, 549 char *buf) 550 { 551 struct mlx4_port *p = 552 container_of(attr, struct mlx4_port, enable_smi_admin); 553 554 return sysfs_emit(buf, "%d\n", 555 !!mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave, 556 p->port_num)); 557 } 558 559 static ssize_t sysfs_store_enable_smi_admin(struct device *dev, 560 struct device_attribute *attr, 561 const char *buf, size_t count) 562 { 563 struct mlx4_port *p = 564 container_of(attr, struct mlx4_port, enable_smi_admin); 565 int enable; 566 567 if (sscanf(buf, "%i", &enable) != 1 || 568 enable < 0 || enable > 1) 569 return -EINVAL; 570 571 if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable)) 572 return -EINVAL; 573 return count; 574 } 575 576 static int add_vf_smi_entries(struct mlx4_port *p) 577 { 578 int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) == 579 IB_LINK_LAYER_ETHERNET; 580 int ret; 581 582 /* do not display entries if eth transport, or if master */ 583 if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev)) 584 return 0; 585 586 sysfs_attr_init(&p->smi_enabled.attr); 587 p->smi_enabled.show = sysfs_show_smi_enabled; 588 p->smi_enabled.store = NULL; 589 p->smi_enabled.attr.name = "smi_enabled"; 590 p->smi_enabled.attr.mode = 0444; 591 ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr); 592 if (ret) { 593 pr_err("failed to create smi_enabled\n"); 594 return ret; 595 } 596 597 sysfs_attr_init(&p->enable_smi_admin.attr); 598 p->enable_smi_admin.show = sysfs_show_enable_smi_admin; 599 p->enable_smi_admin.store = sysfs_store_enable_smi_admin; 600 p->enable_smi_admin.attr.name = "enable_smi_admin"; 601 p->enable_smi_admin.attr.mode = 0644; 602 ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr); 603 if (ret) { 604 pr_err("failed to create enable_smi_admin\n"); 605 sysfs_remove_file(&p->kobj, &p->smi_enabled.attr); 606 return ret; 607 } 608 return 0; 609 } 610 611 static void remove_vf_smi_entries(struct mlx4_port *p) 612 { 613 int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) == 614 IB_LINK_LAYER_ETHERNET; 615 616 if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev)) 617 return; 618 619 sysfs_remove_file(&p->kobj, &p->smi_enabled.attr); 620 sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr); 621 } 622 623 static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave) 624 { 625 struct mlx4_port *p; 626 int i; 627 int ret; 628 int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) == 629 IB_LINK_LAYER_ETHERNET; 630 631 p = kzalloc_obj(*p); 632 if (!p) 633 return -ENOMEM; 634 635 p->dev = dev; 636 p->port_num = port_num; 637 p->slave = slave; 638 639 ret = kobject_init_and_add(&p->kobj, &port_type, 640 kobject_get(dev->dev_ports_parent[slave]), 641 "%d", port_num); 642 if (ret) 643 goto err_alloc; 644 645 p->pkey_group.name = "pkey_idx"; 646 p->pkey_group.attrs = 647 alloc_group_attrs(show_port_pkey, 648 is_eth ? NULL : store_port_pkey, 649 dev->dev->caps.pkey_table_len[port_num]); 650 if (!p->pkey_group.attrs) { 651 ret = -ENOMEM; 652 goto err_alloc; 653 } 654 655 ret = sysfs_create_group(&p->kobj, &p->pkey_group); 656 if (ret) 657 goto err_free_pkey; 658 659 p->gid_group.name = "gid_idx"; 660 p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1); 661 if (!p->gid_group.attrs) { 662 ret = -ENOMEM; 663 goto err_free_pkey; 664 } 665 666 ret = sysfs_create_group(&p->kobj, &p->gid_group); 667 if (ret) 668 goto err_free_gid; 669 670 ret = add_vf_smi_entries(p); 671 if (ret) 672 goto err_free_gid; 673 674 list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]); 675 return 0; 676 677 err_free_gid: 678 kfree(p->gid_group.attrs[0]); 679 kfree(p->gid_group.attrs); 680 681 err_free_pkey: 682 for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i) 683 kfree(p->pkey_group.attrs[i]); 684 kfree(p->pkey_group.attrs); 685 686 err_alloc: 687 kobject_put(dev->dev_ports_parent[slave]); 688 kfree(p); 689 return ret; 690 } 691 692 static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave) 693 { 694 char name[32]; 695 int err; 696 int port; 697 struct kobject *p, *t; 698 struct mlx4_port *mport; 699 struct mlx4_active_ports actv_ports; 700 701 get_name(dev, name, slave, sizeof name); 702 703 dev->pkeys.device_parent[slave] = 704 kobject_create_and_add(name, kobject_get(dev->iov_parent)); 705 706 if (!dev->pkeys.device_parent[slave]) { 707 err = -ENOMEM; 708 goto fail_dev; 709 } 710 711 INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]); 712 713 dev->dev_ports_parent[slave] = 714 kobject_create_and_add("ports", 715 kobject_get(dev->pkeys.device_parent[slave])); 716 717 if (!dev->dev_ports_parent[slave]) { 718 err = -ENOMEM; 719 goto err_ports; 720 } 721 722 actv_ports = mlx4_get_active_ports(dev->dev, slave); 723 724 for (port = 1; port <= dev->dev->caps.num_ports; ++port) { 725 if (!test_bit(port - 1, actv_ports.ports)) 726 continue; 727 err = add_port(dev, port, slave); 728 if (err) 729 goto err_add; 730 } 731 return 0; 732 733 err_add: 734 list_for_each_entry_safe(p, t, 735 &dev->pkeys.pkey_port_list[slave], 736 entry) { 737 list_del(&p->entry); 738 mport = container_of(p, struct mlx4_port, kobj); 739 sysfs_remove_group(p, &mport->pkey_group); 740 sysfs_remove_group(p, &mport->gid_group); 741 remove_vf_smi_entries(mport); 742 kobject_put(p); 743 } 744 kobject_put(dev->dev_ports_parent[slave]); 745 746 err_ports: 747 kobject_put(dev->pkeys.device_parent[slave]); 748 /* extra put for the device_parent create_and_add */ 749 kobject_put(dev->pkeys.device_parent[slave]); 750 751 fail_dev: 752 kobject_put(dev->iov_parent); 753 return err; 754 } 755 756 static int register_pkey_tree(struct mlx4_ib_dev *device) 757 { 758 int i; 759 760 if (!mlx4_is_master(device->dev)) 761 return 0; 762 763 for (i = 0; i <= device->dev->persist->num_vfs; ++i) 764 register_one_pkey_tree(device, i); 765 766 return 0; 767 } 768 769 static void unregister_pkey_tree(struct mlx4_ib_dev *device) 770 { 771 int slave; 772 struct kobject *p, *t; 773 struct mlx4_port *port; 774 775 if (!mlx4_is_master(device->dev)) 776 return; 777 778 for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) { 779 list_for_each_entry_safe(p, t, 780 &device->pkeys.pkey_port_list[slave], 781 entry) { 782 list_del(&p->entry); 783 port = container_of(p, struct mlx4_port, kobj); 784 sysfs_remove_group(p, &port->pkey_group); 785 sysfs_remove_group(p, &port->gid_group); 786 remove_vf_smi_entries(port); 787 kobject_put(p); 788 kobject_put(device->dev_ports_parent[slave]); 789 } 790 kobject_put(device->dev_ports_parent[slave]); 791 kobject_put(device->pkeys.device_parent[slave]); 792 kobject_put(device->pkeys.device_parent[slave]); 793 kobject_put(device->iov_parent); 794 } 795 } 796 797 int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *dev) 798 { 799 unsigned int i; 800 int ret = 0; 801 802 if (!mlx4_is_master(dev->dev)) 803 return 0; 804 805 dev->iov_parent = kobject_create_and_add("iov", &dev->ib_dev.dev.kobj); 806 if (!dev->iov_parent) { 807 ret = -ENOMEM; 808 goto err; 809 } 810 dev->ports_parent = 811 kobject_create_and_add("ports", 812 kobject_get(dev->iov_parent)); 813 if (!dev->ports_parent) { 814 ret = -ENOMEM; 815 goto err_ports; 816 } 817 818 rdma_for_each_port(&dev->ib_dev, i) { 819 ret = add_port_entries(dev, i); 820 if (ret) 821 goto err_add_entries; 822 } 823 824 ret = register_pkey_tree(dev); 825 if (ret) 826 goto err_add_entries; 827 return 0; 828 829 err_add_entries: 830 kobject_put(dev->ports_parent); 831 832 err_ports: 833 kobject_put(dev->iov_parent); 834 err: 835 pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret); 836 return ret; 837 } 838 839 static void unregister_alias_guid_tree(struct mlx4_ib_dev *device) 840 { 841 struct mlx4_ib_iov_port *p; 842 int i; 843 844 if (!mlx4_is_master(device->dev)) 845 return; 846 847 for (i = 0; i < device->dev->caps.num_ports; i++) { 848 p = &device->iov_ports[i]; 849 kobject_put(p->admin_alias_parent); 850 kobject_put(p->gids_parent); 851 kobject_put(p->pkeys_parent); 852 kobject_put(p->mcgs_parent); 853 kobject_put(p->cur_port); 854 kobject_put(p->cur_port); 855 kobject_put(p->cur_port); 856 kobject_put(p->cur_port); 857 kobject_put(p->cur_port); 858 kobject_put(p->dev->ports_parent); 859 kfree(p->dentr_ar); 860 } 861 } 862 863 void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device) 864 { 865 unregister_alias_guid_tree(device); 866 unregister_pkey_tree(device); 867 kobject_put(device->ports_parent); 868 kobject_put(device->iov_parent); 869 kobject_put(device->iov_parent); 870 } 871