1 /* 2 * Copyright(c) 2015-2017 Intel Corporation. 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * BSD LICENSE 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 24 * - Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * - Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in 28 * the documentation and/or other materials provided with the 29 * distribution. 30 * - Neither the name of Intel Corporation nor the names of its 31 * contributors may be used to endorse or promote products derived 32 * from this software without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 * 46 */ 47 #include <linux/ctype.h> 48 49 #include "hfi.h" 50 #include "mad.h" 51 #include "trace.h" 52 53 /* 54 * Start of per-port congestion control structures and support code 55 */ 56 57 /* 58 * Congestion control table size followed by table entries 59 */ 60 static ssize_t read_cc_table_bin(struct file *filp, struct kobject *kobj, 61 struct bin_attribute *bin_attr, 62 char *buf, loff_t pos, size_t count) 63 { 64 int ret; 65 struct hfi1_pportdata *ppd = 66 container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 67 struct cc_state *cc_state; 68 69 ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow) 70 + sizeof(__be16); 71 72 if (pos > ret) 73 return -EINVAL; 74 75 if (count > ret - pos) 76 count = ret - pos; 77 78 if (!count) 79 return count; 80 81 rcu_read_lock(); 82 cc_state = get_cc_state(ppd); 83 if (!cc_state) { 84 rcu_read_unlock(); 85 return -EINVAL; 86 } 87 memcpy(buf, (void *)&cc_state->cct + pos, count); 88 rcu_read_unlock(); 89 90 return count; 91 } 92 93 static void port_release(struct kobject *kobj) 94 { 95 /* nothing to do since memory is freed by hfi1_free_devdata() */ 96 } 97 98 static const struct bin_attribute cc_table_bin_attr = { 99 .attr = {.name = "cc_table_bin", .mode = 0444}, 100 .read = read_cc_table_bin, 101 .size = PAGE_SIZE, 102 }; 103 104 /* 105 * Congestion settings: port control, control map and an array of 16 106 * entries for the congestion entries - increase, timer, event log 107 * trigger threshold and the minimum injection rate delay. 108 */ 109 static ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj, 110 struct bin_attribute *bin_attr, 111 char *buf, loff_t pos, size_t count) 112 { 113 int ret; 114 struct hfi1_pportdata *ppd = 115 container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 116 struct cc_state *cc_state; 117 118 ret = sizeof(struct opa_congestion_setting_attr_shadow); 119 120 if (pos > ret) 121 return -EINVAL; 122 if (count > ret - pos) 123 count = ret - pos; 124 125 if (!count) 126 return count; 127 128 rcu_read_lock(); 129 cc_state = get_cc_state(ppd); 130 if (!cc_state) { 131 rcu_read_unlock(); 132 return -EINVAL; 133 } 134 memcpy(buf, (void *)&cc_state->cong_setting + pos, count); 135 rcu_read_unlock(); 136 137 return count; 138 } 139 140 static const struct bin_attribute cc_setting_bin_attr = { 141 .attr = {.name = "cc_settings_bin", .mode = 0444}, 142 .read = read_cc_setting_bin, 143 .size = PAGE_SIZE, 144 }; 145 146 struct hfi1_port_attr { 147 struct attribute attr; 148 ssize_t (*show)(struct hfi1_pportdata *, char *); 149 ssize_t (*store)(struct hfi1_pportdata *, const char *, size_t); 150 }; 151 152 static ssize_t cc_prescan_show(struct hfi1_pportdata *ppd, char *buf) 153 { 154 return sprintf(buf, "%s\n", ppd->cc_prescan ? "on" : "off"); 155 } 156 157 static ssize_t cc_prescan_store(struct hfi1_pportdata *ppd, const char *buf, 158 size_t count) 159 { 160 if (!memcmp(buf, "on", 2)) 161 ppd->cc_prescan = true; 162 else if (!memcmp(buf, "off", 3)) 163 ppd->cc_prescan = false; 164 165 return count; 166 } 167 168 static struct hfi1_port_attr cc_prescan_attr = 169 __ATTR(cc_prescan, 0600, cc_prescan_show, cc_prescan_store); 170 171 static ssize_t cc_attr_show(struct kobject *kobj, struct attribute *attr, 172 char *buf) 173 { 174 struct hfi1_port_attr *port_attr = 175 container_of(attr, struct hfi1_port_attr, attr); 176 struct hfi1_pportdata *ppd = 177 container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 178 179 return port_attr->show(ppd, buf); 180 } 181 182 static ssize_t cc_attr_store(struct kobject *kobj, struct attribute *attr, 183 const char *buf, size_t count) 184 { 185 struct hfi1_port_attr *port_attr = 186 container_of(attr, struct hfi1_port_attr, attr); 187 struct hfi1_pportdata *ppd = 188 container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 189 190 return port_attr->store(ppd, buf, count); 191 } 192 193 static const struct sysfs_ops port_cc_sysfs_ops = { 194 .show = cc_attr_show, 195 .store = cc_attr_store 196 }; 197 198 static struct attribute *port_cc_default_attributes[] = { 199 &cc_prescan_attr.attr, 200 NULL 201 }; 202 203 static struct kobj_type port_cc_ktype = { 204 .release = port_release, 205 .sysfs_ops = &port_cc_sysfs_ops, 206 .default_attrs = port_cc_default_attributes 207 }; 208 209 /* Start sc2vl */ 210 #define HFI1_SC2VL_ATTR(N) \ 211 static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \ 212 .attr = { .name = __stringify(N), .mode = 0444 }, \ 213 .sc = N \ 214 } 215 216 struct hfi1_sc2vl_attr { 217 struct attribute attr; 218 int sc; 219 }; 220 221 HFI1_SC2VL_ATTR(0); 222 HFI1_SC2VL_ATTR(1); 223 HFI1_SC2VL_ATTR(2); 224 HFI1_SC2VL_ATTR(3); 225 HFI1_SC2VL_ATTR(4); 226 HFI1_SC2VL_ATTR(5); 227 HFI1_SC2VL_ATTR(6); 228 HFI1_SC2VL_ATTR(7); 229 HFI1_SC2VL_ATTR(8); 230 HFI1_SC2VL_ATTR(9); 231 HFI1_SC2VL_ATTR(10); 232 HFI1_SC2VL_ATTR(11); 233 HFI1_SC2VL_ATTR(12); 234 HFI1_SC2VL_ATTR(13); 235 HFI1_SC2VL_ATTR(14); 236 HFI1_SC2VL_ATTR(15); 237 HFI1_SC2VL_ATTR(16); 238 HFI1_SC2VL_ATTR(17); 239 HFI1_SC2VL_ATTR(18); 240 HFI1_SC2VL_ATTR(19); 241 HFI1_SC2VL_ATTR(20); 242 HFI1_SC2VL_ATTR(21); 243 HFI1_SC2VL_ATTR(22); 244 HFI1_SC2VL_ATTR(23); 245 HFI1_SC2VL_ATTR(24); 246 HFI1_SC2VL_ATTR(25); 247 HFI1_SC2VL_ATTR(26); 248 HFI1_SC2VL_ATTR(27); 249 HFI1_SC2VL_ATTR(28); 250 HFI1_SC2VL_ATTR(29); 251 HFI1_SC2VL_ATTR(30); 252 HFI1_SC2VL_ATTR(31); 253 254 static struct attribute *sc2vl_default_attributes[] = { 255 &hfi1_sc2vl_attr_0.attr, 256 &hfi1_sc2vl_attr_1.attr, 257 &hfi1_sc2vl_attr_2.attr, 258 &hfi1_sc2vl_attr_3.attr, 259 &hfi1_sc2vl_attr_4.attr, 260 &hfi1_sc2vl_attr_5.attr, 261 &hfi1_sc2vl_attr_6.attr, 262 &hfi1_sc2vl_attr_7.attr, 263 &hfi1_sc2vl_attr_8.attr, 264 &hfi1_sc2vl_attr_9.attr, 265 &hfi1_sc2vl_attr_10.attr, 266 &hfi1_sc2vl_attr_11.attr, 267 &hfi1_sc2vl_attr_12.attr, 268 &hfi1_sc2vl_attr_13.attr, 269 &hfi1_sc2vl_attr_14.attr, 270 &hfi1_sc2vl_attr_15.attr, 271 &hfi1_sc2vl_attr_16.attr, 272 &hfi1_sc2vl_attr_17.attr, 273 &hfi1_sc2vl_attr_18.attr, 274 &hfi1_sc2vl_attr_19.attr, 275 &hfi1_sc2vl_attr_20.attr, 276 &hfi1_sc2vl_attr_21.attr, 277 &hfi1_sc2vl_attr_22.attr, 278 &hfi1_sc2vl_attr_23.attr, 279 &hfi1_sc2vl_attr_24.attr, 280 &hfi1_sc2vl_attr_25.attr, 281 &hfi1_sc2vl_attr_26.attr, 282 &hfi1_sc2vl_attr_27.attr, 283 &hfi1_sc2vl_attr_28.attr, 284 &hfi1_sc2vl_attr_29.attr, 285 &hfi1_sc2vl_attr_30.attr, 286 &hfi1_sc2vl_attr_31.attr, 287 NULL 288 }; 289 290 static ssize_t sc2vl_attr_show(struct kobject *kobj, struct attribute *attr, 291 char *buf) 292 { 293 struct hfi1_sc2vl_attr *sattr = 294 container_of(attr, struct hfi1_sc2vl_attr, attr); 295 struct hfi1_pportdata *ppd = 296 container_of(kobj, struct hfi1_pportdata, sc2vl_kobj); 297 struct hfi1_devdata *dd = ppd->dd; 298 299 return sprintf(buf, "%u\n", *((u8 *)dd->sc2vl + sattr->sc)); 300 } 301 302 static const struct sysfs_ops hfi1_sc2vl_ops = { 303 .show = sc2vl_attr_show, 304 }; 305 306 static struct kobj_type hfi1_sc2vl_ktype = { 307 .release = port_release, 308 .sysfs_ops = &hfi1_sc2vl_ops, 309 .default_attrs = sc2vl_default_attributes 310 }; 311 312 /* End sc2vl */ 313 314 /* Start sl2sc */ 315 #define HFI1_SL2SC_ATTR(N) \ 316 static struct hfi1_sl2sc_attr hfi1_sl2sc_attr_##N = { \ 317 .attr = { .name = __stringify(N), .mode = 0444 }, \ 318 .sl = N \ 319 } 320 321 struct hfi1_sl2sc_attr { 322 struct attribute attr; 323 int sl; 324 }; 325 326 HFI1_SL2SC_ATTR(0); 327 HFI1_SL2SC_ATTR(1); 328 HFI1_SL2SC_ATTR(2); 329 HFI1_SL2SC_ATTR(3); 330 HFI1_SL2SC_ATTR(4); 331 HFI1_SL2SC_ATTR(5); 332 HFI1_SL2SC_ATTR(6); 333 HFI1_SL2SC_ATTR(7); 334 HFI1_SL2SC_ATTR(8); 335 HFI1_SL2SC_ATTR(9); 336 HFI1_SL2SC_ATTR(10); 337 HFI1_SL2SC_ATTR(11); 338 HFI1_SL2SC_ATTR(12); 339 HFI1_SL2SC_ATTR(13); 340 HFI1_SL2SC_ATTR(14); 341 HFI1_SL2SC_ATTR(15); 342 HFI1_SL2SC_ATTR(16); 343 HFI1_SL2SC_ATTR(17); 344 HFI1_SL2SC_ATTR(18); 345 HFI1_SL2SC_ATTR(19); 346 HFI1_SL2SC_ATTR(20); 347 HFI1_SL2SC_ATTR(21); 348 HFI1_SL2SC_ATTR(22); 349 HFI1_SL2SC_ATTR(23); 350 HFI1_SL2SC_ATTR(24); 351 HFI1_SL2SC_ATTR(25); 352 HFI1_SL2SC_ATTR(26); 353 HFI1_SL2SC_ATTR(27); 354 HFI1_SL2SC_ATTR(28); 355 HFI1_SL2SC_ATTR(29); 356 HFI1_SL2SC_ATTR(30); 357 HFI1_SL2SC_ATTR(31); 358 359 static struct attribute *sl2sc_default_attributes[] = { 360 &hfi1_sl2sc_attr_0.attr, 361 &hfi1_sl2sc_attr_1.attr, 362 &hfi1_sl2sc_attr_2.attr, 363 &hfi1_sl2sc_attr_3.attr, 364 &hfi1_sl2sc_attr_4.attr, 365 &hfi1_sl2sc_attr_5.attr, 366 &hfi1_sl2sc_attr_6.attr, 367 &hfi1_sl2sc_attr_7.attr, 368 &hfi1_sl2sc_attr_8.attr, 369 &hfi1_sl2sc_attr_9.attr, 370 &hfi1_sl2sc_attr_10.attr, 371 &hfi1_sl2sc_attr_11.attr, 372 &hfi1_sl2sc_attr_12.attr, 373 &hfi1_sl2sc_attr_13.attr, 374 &hfi1_sl2sc_attr_14.attr, 375 &hfi1_sl2sc_attr_15.attr, 376 &hfi1_sl2sc_attr_16.attr, 377 &hfi1_sl2sc_attr_17.attr, 378 &hfi1_sl2sc_attr_18.attr, 379 &hfi1_sl2sc_attr_19.attr, 380 &hfi1_sl2sc_attr_20.attr, 381 &hfi1_sl2sc_attr_21.attr, 382 &hfi1_sl2sc_attr_22.attr, 383 &hfi1_sl2sc_attr_23.attr, 384 &hfi1_sl2sc_attr_24.attr, 385 &hfi1_sl2sc_attr_25.attr, 386 &hfi1_sl2sc_attr_26.attr, 387 &hfi1_sl2sc_attr_27.attr, 388 &hfi1_sl2sc_attr_28.attr, 389 &hfi1_sl2sc_attr_29.attr, 390 &hfi1_sl2sc_attr_30.attr, 391 &hfi1_sl2sc_attr_31.attr, 392 NULL 393 }; 394 395 static ssize_t sl2sc_attr_show(struct kobject *kobj, struct attribute *attr, 396 char *buf) 397 { 398 struct hfi1_sl2sc_attr *sattr = 399 container_of(attr, struct hfi1_sl2sc_attr, attr); 400 struct hfi1_pportdata *ppd = 401 container_of(kobj, struct hfi1_pportdata, sl2sc_kobj); 402 struct hfi1_ibport *ibp = &ppd->ibport_data; 403 404 return sprintf(buf, "%u\n", ibp->sl_to_sc[sattr->sl]); 405 } 406 407 static const struct sysfs_ops hfi1_sl2sc_ops = { 408 .show = sl2sc_attr_show, 409 }; 410 411 static struct kobj_type hfi1_sl2sc_ktype = { 412 .release = port_release, 413 .sysfs_ops = &hfi1_sl2sc_ops, 414 .default_attrs = sl2sc_default_attributes 415 }; 416 417 /* End sl2sc */ 418 419 /* Start vl2mtu */ 420 421 #define HFI1_VL2MTU_ATTR(N) \ 422 static struct hfi1_vl2mtu_attr hfi1_vl2mtu_attr_##N = { \ 423 .attr = { .name = __stringify(N), .mode = 0444 }, \ 424 .vl = N \ 425 } 426 427 struct hfi1_vl2mtu_attr { 428 struct attribute attr; 429 int vl; 430 }; 431 432 HFI1_VL2MTU_ATTR(0); 433 HFI1_VL2MTU_ATTR(1); 434 HFI1_VL2MTU_ATTR(2); 435 HFI1_VL2MTU_ATTR(3); 436 HFI1_VL2MTU_ATTR(4); 437 HFI1_VL2MTU_ATTR(5); 438 HFI1_VL2MTU_ATTR(6); 439 HFI1_VL2MTU_ATTR(7); 440 HFI1_VL2MTU_ATTR(8); 441 HFI1_VL2MTU_ATTR(9); 442 HFI1_VL2MTU_ATTR(10); 443 HFI1_VL2MTU_ATTR(11); 444 HFI1_VL2MTU_ATTR(12); 445 HFI1_VL2MTU_ATTR(13); 446 HFI1_VL2MTU_ATTR(14); 447 HFI1_VL2MTU_ATTR(15); 448 449 static struct attribute *vl2mtu_default_attributes[] = { 450 &hfi1_vl2mtu_attr_0.attr, 451 &hfi1_vl2mtu_attr_1.attr, 452 &hfi1_vl2mtu_attr_2.attr, 453 &hfi1_vl2mtu_attr_3.attr, 454 &hfi1_vl2mtu_attr_4.attr, 455 &hfi1_vl2mtu_attr_5.attr, 456 &hfi1_vl2mtu_attr_6.attr, 457 &hfi1_vl2mtu_attr_7.attr, 458 &hfi1_vl2mtu_attr_8.attr, 459 &hfi1_vl2mtu_attr_9.attr, 460 &hfi1_vl2mtu_attr_10.attr, 461 &hfi1_vl2mtu_attr_11.attr, 462 &hfi1_vl2mtu_attr_12.attr, 463 &hfi1_vl2mtu_attr_13.attr, 464 &hfi1_vl2mtu_attr_14.attr, 465 &hfi1_vl2mtu_attr_15.attr, 466 NULL 467 }; 468 469 static ssize_t vl2mtu_attr_show(struct kobject *kobj, struct attribute *attr, 470 char *buf) 471 { 472 struct hfi1_vl2mtu_attr *vlattr = 473 container_of(attr, struct hfi1_vl2mtu_attr, attr); 474 struct hfi1_pportdata *ppd = 475 container_of(kobj, struct hfi1_pportdata, vl2mtu_kobj); 476 struct hfi1_devdata *dd = ppd->dd; 477 478 return sprintf(buf, "%u\n", dd->vld[vlattr->vl].mtu); 479 } 480 481 static const struct sysfs_ops hfi1_vl2mtu_ops = { 482 .show = vl2mtu_attr_show, 483 }; 484 485 static struct kobj_type hfi1_vl2mtu_ktype = { 486 .release = port_release, 487 .sysfs_ops = &hfi1_vl2mtu_ops, 488 .default_attrs = vl2mtu_default_attributes 489 }; 490 491 /* end of per-port file structures and support code */ 492 493 /* 494 * Start of per-unit (or driver, in some cases, but replicated 495 * per unit) functions (these get a device *) 496 */ 497 static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, 498 char *buf) 499 { 500 struct hfi1_ibdev *dev = 501 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 502 503 return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); 504 } 505 static DEVICE_ATTR_RO(hw_rev); 506 507 static ssize_t board_id_show(struct device *device, 508 struct device_attribute *attr, char *buf) 509 { 510 struct hfi1_ibdev *dev = 511 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 512 struct hfi1_devdata *dd = dd_from_dev(dev); 513 int ret; 514 515 if (!dd->boardname) 516 ret = -EINVAL; 517 else 518 ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); 519 return ret; 520 } 521 static DEVICE_ATTR_RO(board_id); 522 523 static ssize_t boardversion_show(struct device *device, 524 struct device_attribute *attr, char *buf) 525 { 526 struct hfi1_ibdev *dev = 527 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 528 struct hfi1_devdata *dd = dd_from_dev(dev); 529 530 /* The string printed here is already newline-terminated. */ 531 return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); 532 } 533 static DEVICE_ATTR_RO(boardversion); 534 535 static ssize_t nctxts_show(struct device *device, 536 struct device_attribute *attr, char *buf) 537 { 538 struct hfi1_ibdev *dev = 539 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 540 struct hfi1_devdata *dd = dd_from_dev(dev); 541 542 /* 543 * Return the smaller of send and receive contexts. 544 * Normally, user level applications would require both a send 545 * and a receive context, so returning the smaller of the two counts 546 * give a more accurate picture of total contexts available. 547 */ 548 return scnprintf(buf, PAGE_SIZE, "%u\n", 549 min(dd->num_user_contexts, 550 (u32)dd->sc_sizes[SC_USER].count)); 551 } 552 static DEVICE_ATTR_RO(nctxts); 553 554 static ssize_t nfreectxts_show(struct device *device, 555 struct device_attribute *attr, char *buf) 556 { 557 struct hfi1_ibdev *dev = 558 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 559 struct hfi1_devdata *dd = dd_from_dev(dev); 560 561 /* Return the number of free user ports (contexts) available. */ 562 return scnprintf(buf, PAGE_SIZE, "%u\n", dd->freectxts); 563 } 564 static DEVICE_ATTR_RO(nfreectxts); 565 566 static ssize_t serial_show(struct device *device, 567 struct device_attribute *attr, char *buf) 568 { 569 struct hfi1_ibdev *dev = 570 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 571 struct hfi1_devdata *dd = dd_from_dev(dev); 572 573 return scnprintf(buf, PAGE_SIZE, "%s", dd->serial); 574 } 575 static DEVICE_ATTR_RO(serial); 576 577 static ssize_t chip_reset_store(struct device *device, 578 struct device_attribute *attr, const char *buf, 579 size_t count) 580 { 581 struct hfi1_ibdev *dev = 582 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 583 struct hfi1_devdata *dd = dd_from_dev(dev); 584 int ret; 585 586 if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 587 ret = -EINVAL; 588 goto bail; 589 } 590 591 ret = hfi1_reset_device(dd->unit); 592 bail: 593 return ret < 0 ? ret : count; 594 } 595 static DEVICE_ATTR_WO(chip_reset); 596 597 /* 598 * Convert the reported temperature from an integer (reported in 599 * units of 0.25C) to a floating point number. 600 */ 601 #define temp2str(temp, buf, size, idx) \ 602 scnprintf((buf) + (idx), (size) - (idx), "%u.%02u ", \ 603 ((temp) >> 2), ((temp) & 0x3) * 25) 604 605 /* 606 * Dump tempsense values, in decimal, to ease shell-scripts. 607 */ 608 static ssize_t tempsense_show(struct device *device, 609 struct device_attribute *attr, char *buf) 610 { 611 struct hfi1_ibdev *dev = 612 rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 613 struct hfi1_devdata *dd = dd_from_dev(dev); 614 struct hfi1_temp temp; 615 int ret; 616 617 ret = hfi1_tempsense_rd(dd, &temp); 618 if (!ret) { 619 int idx = 0; 620 621 idx += temp2str(temp.curr, buf, PAGE_SIZE, idx); 622 idx += temp2str(temp.lo_lim, buf, PAGE_SIZE, idx); 623 idx += temp2str(temp.hi_lim, buf, PAGE_SIZE, idx); 624 idx += temp2str(temp.crit_lim, buf, PAGE_SIZE, idx); 625 idx += scnprintf(buf + idx, PAGE_SIZE - idx, 626 "%u %u %u\n", temp.triggers & 0x1, 627 temp.triggers & 0x2, temp.triggers & 0x4); 628 ret = idx; 629 } 630 return ret; 631 } 632 static DEVICE_ATTR_RO(tempsense); 633 634 /* 635 * end of per-unit (or driver, in some cases, but replicated 636 * per unit) functions 637 */ 638 639 /* start of per-unit file structures and support code */ 640 static struct attribute *hfi1_attributes[] = { 641 &dev_attr_hw_rev.attr, 642 &dev_attr_board_id.attr, 643 &dev_attr_nctxts.attr, 644 &dev_attr_nfreectxts.attr, 645 &dev_attr_serial.attr, 646 &dev_attr_boardversion.attr, 647 &dev_attr_tempsense.attr, 648 &dev_attr_chip_reset.attr, 649 NULL, 650 }; 651 652 const struct attribute_group ib_hfi1_attr_group = { 653 .attrs = hfi1_attributes, 654 }; 655 656 int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, 657 struct kobject *kobj) 658 { 659 struct hfi1_pportdata *ppd; 660 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 661 int ret; 662 663 if (!port_num || port_num > dd->num_pports) { 664 dd_dev_err(dd, 665 "Skipping infiniband class with invalid port %u\n", 666 port_num); 667 return -ENODEV; 668 } 669 ppd = &dd->pport[port_num - 1]; 670 671 ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj, 672 "sc2vl"); 673 if (ret) { 674 dd_dev_err(dd, 675 "Skipping sc2vl sysfs info, (err %d) port %u\n", 676 ret, port_num); 677 goto bail; 678 } 679 kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); 680 681 ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj, 682 "sl2sc"); 683 if (ret) { 684 dd_dev_err(dd, 685 "Skipping sl2sc sysfs info, (err %d) port %u\n", 686 ret, port_num); 687 goto bail_sc2vl; 688 } 689 kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); 690 691 ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj, 692 "vl2mtu"); 693 if (ret) { 694 dd_dev_err(dd, 695 "Skipping vl2mtu sysfs info, (err %d) port %u\n", 696 ret, port_num); 697 goto bail_sl2sc; 698 } 699 kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); 700 701 ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype, 702 kobj, "CCMgtA"); 703 if (ret) { 704 dd_dev_err(dd, 705 "Skipping Congestion Control sysfs info, (err %d) port %u\n", 706 ret, port_num); 707 goto bail_vl2mtu; 708 } 709 710 kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); 711 712 ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); 713 if (ret) { 714 dd_dev_err(dd, 715 "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", 716 ret, port_num); 717 goto bail_cc; 718 } 719 720 ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); 721 if (ret) { 722 dd_dev_err(dd, 723 "Skipping Congestion Control table sysfs info, (err %d) port %u\n", 724 ret, port_num); 725 goto bail_cc_entry_bin; 726 } 727 728 dd_dev_info(dd, 729 "Congestion Control Agent enabled for port %d\n", 730 port_num); 731 732 return 0; 733 734 bail_cc_entry_bin: 735 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 736 &cc_setting_bin_attr); 737 bail_cc: 738 kobject_put(&ppd->pport_cc_kobj); 739 bail_vl2mtu: 740 kobject_put(&ppd->vl2mtu_kobj); 741 bail_sl2sc: 742 kobject_put(&ppd->sl2sc_kobj); 743 bail_sc2vl: 744 kobject_put(&ppd->sc2vl_kobj); 745 bail: 746 return ret; 747 } 748 749 struct sde_attribute { 750 struct attribute attr; 751 ssize_t (*show)(struct sdma_engine *sde, char *buf); 752 ssize_t (*store)(struct sdma_engine *sde, const char *buf, size_t cnt); 753 }; 754 755 static ssize_t sde_show(struct kobject *kobj, struct attribute *attr, char *buf) 756 { 757 struct sde_attribute *sde_attr = 758 container_of(attr, struct sde_attribute, attr); 759 struct sdma_engine *sde = 760 container_of(kobj, struct sdma_engine, kobj); 761 762 if (!sde_attr->show) 763 return -EINVAL; 764 765 return sde_attr->show(sde, buf); 766 } 767 768 static ssize_t sde_store(struct kobject *kobj, struct attribute *attr, 769 const char *buf, size_t count) 770 { 771 struct sde_attribute *sde_attr = 772 container_of(attr, struct sde_attribute, attr); 773 struct sdma_engine *sde = 774 container_of(kobj, struct sdma_engine, kobj); 775 776 if (!capable(CAP_SYS_ADMIN)) 777 return -EPERM; 778 779 if (!sde_attr->store) 780 return -EINVAL; 781 782 return sde_attr->store(sde, buf, count); 783 } 784 785 static const struct sysfs_ops sde_sysfs_ops = { 786 .show = sde_show, 787 .store = sde_store, 788 }; 789 790 static struct kobj_type sde_ktype = { 791 .sysfs_ops = &sde_sysfs_ops, 792 }; 793 794 #define SDE_ATTR(_name, _mode, _show, _store) \ 795 struct sde_attribute sde_attr_##_name = \ 796 __ATTR(_name, _mode, _show, _store) 797 798 static ssize_t sde_show_cpu_to_sde_map(struct sdma_engine *sde, char *buf) 799 { 800 return sdma_get_cpu_to_sde_map(sde, buf); 801 } 802 803 static ssize_t sde_store_cpu_to_sde_map(struct sdma_engine *sde, 804 const char *buf, size_t count) 805 { 806 return sdma_set_cpu_to_sde_map(sde, buf, count); 807 } 808 809 static ssize_t sde_show_vl(struct sdma_engine *sde, char *buf) 810 { 811 int vl; 812 813 vl = sdma_engine_get_vl(sde); 814 if (vl < 0) 815 return vl; 816 817 return snprintf(buf, PAGE_SIZE, "%d\n", vl); 818 } 819 820 static SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO, 821 sde_show_cpu_to_sde_map, 822 sde_store_cpu_to_sde_map); 823 static SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL); 824 825 static struct sde_attribute *sde_attribs[] = { 826 &sde_attr_cpu_list, 827 &sde_attr_vl 828 }; 829 830 /* 831 * Register and create our files in /sys/class/infiniband. 832 */ 833 int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd) 834 { 835 struct ib_device *dev = &dd->verbs_dev.rdi.ibdev; 836 struct device *class_dev = &dev->dev; 837 int i, j, ret; 838 839 for (i = 0; i < dd->num_sdma; i++) { 840 ret = kobject_init_and_add(&dd->per_sdma[i].kobj, 841 &sde_ktype, &class_dev->kobj, 842 "sdma%d", i); 843 if (ret) 844 goto bail; 845 846 for (j = 0; j < ARRAY_SIZE(sde_attribs); j++) { 847 ret = sysfs_create_file(&dd->per_sdma[i].kobj, 848 &sde_attribs[j]->attr); 849 if (ret) 850 goto bail; 851 } 852 } 853 854 return 0; 855 bail: 856 for (i = 0; i < dd->num_sdma; i++) 857 kobject_del(&dd->per_sdma[i].kobj); 858 859 return ret; 860 } 861 862 /* 863 * Unregister and remove our files in /sys/class/infiniband. 864 */ 865 void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd) 866 { 867 struct hfi1_pportdata *ppd; 868 int i; 869 870 for (i = 0; i < dd->num_pports; i++) { 871 ppd = &dd->pport[i]; 872 873 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 874 &cc_setting_bin_attr); 875 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 876 &cc_table_bin_attr); 877 kobject_put(&ppd->pport_cc_kobj); 878 kobject_put(&ppd->vl2mtu_kobj); 879 kobject_put(&ppd->sl2sc_kobj); 880 kobject_put(&ppd->sc2vl_kobj); 881 } 882 } 883