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