1 /* 2 * Copyright(c) 2015, 2016 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 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 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 }; 201 202 static struct kobj_type port_cc_ktype = { 203 .release = port_release, 204 .sysfs_ops = &port_cc_sysfs_ops, 205 .default_attrs = port_cc_default_attributes 206 }; 207 208 /* Start sc2vl */ 209 #define HFI1_SC2VL_ATTR(N) \ 210 static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \ 211 .attr = { .name = __stringify(N), .mode = 0444 }, \ 212 .sc = N \ 213 } 214 215 struct hfi1_sc2vl_attr { 216 struct attribute attr; 217 int sc; 218 }; 219 220 HFI1_SC2VL_ATTR(0); 221 HFI1_SC2VL_ATTR(1); 222 HFI1_SC2VL_ATTR(2); 223 HFI1_SC2VL_ATTR(3); 224 HFI1_SC2VL_ATTR(4); 225 HFI1_SC2VL_ATTR(5); 226 HFI1_SC2VL_ATTR(6); 227 HFI1_SC2VL_ATTR(7); 228 HFI1_SC2VL_ATTR(8); 229 HFI1_SC2VL_ATTR(9); 230 HFI1_SC2VL_ATTR(10); 231 HFI1_SC2VL_ATTR(11); 232 HFI1_SC2VL_ATTR(12); 233 HFI1_SC2VL_ATTR(13); 234 HFI1_SC2VL_ATTR(14); 235 HFI1_SC2VL_ATTR(15); 236 HFI1_SC2VL_ATTR(16); 237 HFI1_SC2VL_ATTR(17); 238 HFI1_SC2VL_ATTR(18); 239 HFI1_SC2VL_ATTR(19); 240 HFI1_SC2VL_ATTR(20); 241 HFI1_SC2VL_ATTR(21); 242 HFI1_SC2VL_ATTR(22); 243 HFI1_SC2VL_ATTR(23); 244 HFI1_SC2VL_ATTR(24); 245 HFI1_SC2VL_ATTR(25); 246 HFI1_SC2VL_ATTR(26); 247 HFI1_SC2VL_ATTR(27); 248 HFI1_SC2VL_ATTR(28); 249 HFI1_SC2VL_ATTR(29); 250 HFI1_SC2VL_ATTR(30); 251 HFI1_SC2VL_ATTR(31); 252 253 static struct attribute *sc2vl_default_attributes[] = { 254 &hfi1_sc2vl_attr_0.attr, 255 &hfi1_sc2vl_attr_1.attr, 256 &hfi1_sc2vl_attr_2.attr, 257 &hfi1_sc2vl_attr_3.attr, 258 &hfi1_sc2vl_attr_4.attr, 259 &hfi1_sc2vl_attr_5.attr, 260 &hfi1_sc2vl_attr_6.attr, 261 &hfi1_sc2vl_attr_7.attr, 262 &hfi1_sc2vl_attr_8.attr, 263 &hfi1_sc2vl_attr_9.attr, 264 &hfi1_sc2vl_attr_10.attr, 265 &hfi1_sc2vl_attr_11.attr, 266 &hfi1_sc2vl_attr_12.attr, 267 &hfi1_sc2vl_attr_13.attr, 268 &hfi1_sc2vl_attr_14.attr, 269 &hfi1_sc2vl_attr_15.attr, 270 &hfi1_sc2vl_attr_16.attr, 271 &hfi1_sc2vl_attr_17.attr, 272 &hfi1_sc2vl_attr_18.attr, 273 &hfi1_sc2vl_attr_19.attr, 274 &hfi1_sc2vl_attr_20.attr, 275 &hfi1_sc2vl_attr_21.attr, 276 &hfi1_sc2vl_attr_22.attr, 277 &hfi1_sc2vl_attr_23.attr, 278 &hfi1_sc2vl_attr_24.attr, 279 &hfi1_sc2vl_attr_25.attr, 280 &hfi1_sc2vl_attr_26.attr, 281 &hfi1_sc2vl_attr_27.attr, 282 &hfi1_sc2vl_attr_28.attr, 283 &hfi1_sc2vl_attr_29.attr, 284 &hfi1_sc2vl_attr_30.attr, 285 &hfi1_sc2vl_attr_31.attr, 286 NULL 287 }; 288 289 static ssize_t sc2vl_attr_show(struct kobject *kobj, struct attribute *attr, 290 char *buf) 291 { 292 struct hfi1_sc2vl_attr *sattr = 293 container_of(attr, struct hfi1_sc2vl_attr, attr); 294 struct hfi1_pportdata *ppd = 295 container_of(kobj, struct hfi1_pportdata, sc2vl_kobj); 296 struct hfi1_devdata *dd = ppd->dd; 297 298 return sprintf(buf, "%u\n", *((u8 *)dd->sc2vl + sattr->sc)); 299 } 300 301 static const struct sysfs_ops hfi1_sc2vl_ops = { 302 .show = sc2vl_attr_show, 303 }; 304 305 static struct kobj_type hfi1_sc2vl_ktype = { 306 .release = port_release, 307 .sysfs_ops = &hfi1_sc2vl_ops, 308 .default_attrs = sc2vl_default_attributes 309 }; 310 311 /* End sc2vl */ 312 313 /* Start sl2sc */ 314 #define HFI1_SL2SC_ATTR(N) \ 315 static struct hfi1_sl2sc_attr hfi1_sl2sc_attr_##N = { \ 316 .attr = { .name = __stringify(N), .mode = 0444 }, \ 317 .sl = N \ 318 } 319 320 struct hfi1_sl2sc_attr { 321 struct attribute attr; 322 int sl; 323 }; 324 325 HFI1_SL2SC_ATTR(0); 326 HFI1_SL2SC_ATTR(1); 327 HFI1_SL2SC_ATTR(2); 328 HFI1_SL2SC_ATTR(3); 329 HFI1_SL2SC_ATTR(4); 330 HFI1_SL2SC_ATTR(5); 331 HFI1_SL2SC_ATTR(6); 332 HFI1_SL2SC_ATTR(7); 333 HFI1_SL2SC_ATTR(8); 334 HFI1_SL2SC_ATTR(9); 335 HFI1_SL2SC_ATTR(10); 336 HFI1_SL2SC_ATTR(11); 337 HFI1_SL2SC_ATTR(12); 338 HFI1_SL2SC_ATTR(13); 339 HFI1_SL2SC_ATTR(14); 340 HFI1_SL2SC_ATTR(15); 341 HFI1_SL2SC_ATTR(16); 342 HFI1_SL2SC_ATTR(17); 343 HFI1_SL2SC_ATTR(18); 344 HFI1_SL2SC_ATTR(19); 345 HFI1_SL2SC_ATTR(20); 346 HFI1_SL2SC_ATTR(21); 347 HFI1_SL2SC_ATTR(22); 348 HFI1_SL2SC_ATTR(23); 349 HFI1_SL2SC_ATTR(24); 350 HFI1_SL2SC_ATTR(25); 351 HFI1_SL2SC_ATTR(26); 352 HFI1_SL2SC_ATTR(27); 353 HFI1_SL2SC_ATTR(28); 354 HFI1_SL2SC_ATTR(29); 355 HFI1_SL2SC_ATTR(30); 356 HFI1_SL2SC_ATTR(31); 357 358 static struct attribute *sl2sc_default_attributes[] = { 359 &hfi1_sl2sc_attr_0.attr, 360 &hfi1_sl2sc_attr_1.attr, 361 &hfi1_sl2sc_attr_2.attr, 362 &hfi1_sl2sc_attr_3.attr, 363 &hfi1_sl2sc_attr_4.attr, 364 &hfi1_sl2sc_attr_5.attr, 365 &hfi1_sl2sc_attr_6.attr, 366 &hfi1_sl2sc_attr_7.attr, 367 &hfi1_sl2sc_attr_8.attr, 368 &hfi1_sl2sc_attr_9.attr, 369 &hfi1_sl2sc_attr_10.attr, 370 &hfi1_sl2sc_attr_11.attr, 371 &hfi1_sl2sc_attr_12.attr, 372 &hfi1_sl2sc_attr_13.attr, 373 &hfi1_sl2sc_attr_14.attr, 374 &hfi1_sl2sc_attr_15.attr, 375 &hfi1_sl2sc_attr_16.attr, 376 &hfi1_sl2sc_attr_17.attr, 377 &hfi1_sl2sc_attr_18.attr, 378 &hfi1_sl2sc_attr_19.attr, 379 &hfi1_sl2sc_attr_20.attr, 380 &hfi1_sl2sc_attr_21.attr, 381 &hfi1_sl2sc_attr_22.attr, 382 &hfi1_sl2sc_attr_23.attr, 383 &hfi1_sl2sc_attr_24.attr, 384 &hfi1_sl2sc_attr_25.attr, 385 &hfi1_sl2sc_attr_26.attr, 386 &hfi1_sl2sc_attr_27.attr, 387 &hfi1_sl2sc_attr_28.attr, 388 &hfi1_sl2sc_attr_29.attr, 389 &hfi1_sl2sc_attr_30.attr, 390 &hfi1_sl2sc_attr_31.attr, 391 NULL 392 }; 393 394 static ssize_t sl2sc_attr_show(struct kobject *kobj, struct attribute *attr, 395 char *buf) 396 { 397 struct hfi1_sl2sc_attr *sattr = 398 container_of(attr, struct hfi1_sl2sc_attr, attr); 399 struct hfi1_pportdata *ppd = 400 container_of(kobj, struct hfi1_pportdata, sl2sc_kobj); 401 struct hfi1_ibport *ibp = &ppd->ibport_data; 402 403 return sprintf(buf, "%u\n", ibp->sl_to_sc[sattr->sl]); 404 } 405 406 static const struct sysfs_ops hfi1_sl2sc_ops = { 407 .show = sl2sc_attr_show, 408 }; 409 410 static struct kobj_type hfi1_sl2sc_ktype = { 411 .release = port_release, 412 .sysfs_ops = &hfi1_sl2sc_ops, 413 .default_attrs = sl2sc_default_attributes 414 }; 415 416 /* End sl2sc */ 417 418 /* Start vl2mtu */ 419 420 #define HFI1_VL2MTU_ATTR(N) \ 421 static struct hfi1_vl2mtu_attr hfi1_vl2mtu_attr_##N = { \ 422 .attr = { .name = __stringify(N), .mode = 0444 }, \ 423 .vl = N \ 424 } 425 426 struct hfi1_vl2mtu_attr { 427 struct attribute attr; 428 int vl; 429 }; 430 431 HFI1_VL2MTU_ATTR(0); 432 HFI1_VL2MTU_ATTR(1); 433 HFI1_VL2MTU_ATTR(2); 434 HFI1_VL2MTU_ATTR(3); 435 HFI1_VL2MTU_ATTR(4); 436 HFI1_VL2MTU_ATTR(5); 437 HFI1_VL2MTU_ATTR(6); 438 HFI1_VL2MTU_ATTR(7); 439 HFI1_VL2MTU_ATTR(8); 440 HFI1_VL2MTU_ATTR(9); 441 HFI1_VL2MTU_ATTR(10); 442 HFI1_VL2MTU_ATTR(11); 443 HFI1_VL2MTU_ATTR(12); 444 HFI1_VL2MTU_ATTR(13); 445 HFI1_VL2MTU_ATTR(14); 446 HFI1_VL2MTU_ATTR(15); 447 448 static struct attribute *vl2mtu_default_attributes[] = { 449 &hfi1_vl2mtu_attr_0.attr, 450 &hfi1_vl2mtu_attr_1.attr, 451 &hfi1_vl2mtu_attr_2.attr, 452 &hfi1_vl2mtu_attr_3.attr, 453 &hfi1_vl2mtu_attr_4.attr, 454 &hfi1_vl2mtu_attr_5.attr, 455 &hfi1_vl2mtu_attr_6.attr, 456 &hfi1_vl2mtu_attr_7.attr, 457 &hfi1_vl2mtu_attr_8.attr, 458 &hfi1_vl2mtu_attr_9.attr, 459 &hfi1_vl2mtu_attr_10.attr, 460 &hfi1_vl2mtu_attr_11.attr, 461 &hfi1_vl2mtu_attr_12.attr, 462 &hfi1_vl2mtu_attr_13.attr, 463 &hfi1_vl2mtu_attr_14.attr, 464 &hfi1_vl2mtu_attr_15.attr, 465 NULL 466 }; 467 468 static ssize_t vl2mtu_attr_show(struct kobject *kobj, struct attribute *attr, 469 char *buf) 470 { 471 struct hfi1_vl2mtu_attr *vlattr = 472 container_of(attr, struct hfi1_vl2mtu_attr, attr); 473 struct hfi1_pportdata *ppd = 474 container_of(kobj, struct hfi1_pportdata, vl2mtu_kobj); 475 struct hfi1_devdata *dd = ppd->dd; 476 477 return sprintf(buf, "%u\n", dd->vld[vlattr->vl].mtu); 478 } 479 480 static const struct sysfs_ops hfi1_vl2mtu_ops = { 481 .show = vl2mtu_attr_show, 482 }; 483 484 static struct kobj_type hfi1_vl2mtu_ktype = { 485 .release = port_release, 486 .sysfs_ops = &hfi1_vl2mtu_ops, 487 .default_attrs = vl2mtu_default_attributes 488 }; 489 490 /* end of per-port file structures and support code */ 491 492 /* 493 * Start of per-unit (or driver, in some cases, but replicated 494 * per unit) functions (these get a device *) 495 */ 496 static ssize_t show_rev(struct device *device, struct device_attribute *attr, 497 char *buf) 498 { 499 struct hfi1_ibdev *dev = 500 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 501 502 return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); 503 } 504 505 static ssize_t show_hfi(struct device *device, struct device_attribute *attr, 506 char *buf) 507 { 508 struct hfi1_ibdev *dev = 509 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 510 struct hfi1_devdata *dd = dd_from_dev(dev); 511 int ret; 512 513 if (!dd->boardname) 514 ret = -EINVAL; 515 else 516 ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); 517 return ret; 518 } 519 520 static ssize_t show_boardversion(struct device *device, 521 struct device_attribute *attr, char *buf) 522 { 523 struct hfi1_ibdev *dev = 524 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 525 struct hfi1_devdata *dd = dd_from_dev(dev); 526 527 /* The string printed here is already newline-terminated. */ 528 return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); 529 } 530 531 static ssize_t show_nctxts(struct device *device, 532 struct device_attribute *attr, char *buf) 533 { 534 struct hfi1_ibdev *dev = 535 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 536 struct hfi1_devdata *dd = dd_from_dev(dev); 537 538 /* 539 * Return the smaller of send and receive contexts. 540 * Normally, user level applications would require both a send 541 * and a receive context, so returning the smaller of the two counts 542 * give a more accurate picture of total contexts available. 543 */ 544 return scnprintf(buf, PAGE_SIZE, "%u\n", 545 min(dd->num_rcv_contexts - dd->first_user_ctxt, 546 (u32)dd->sc_sizes[SC_USER].count)); 547 } 548 549 static ssize_t show_nfreectxts(struct device *device, 550 struct device_attribute *attr, char *buf) 551 { 552 struct hfi1_ibdev *dev = 553 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 554 struct hfi1_devdata *dd = dd_from_dev(dev); 555 556 /* Return the number of free user ports (contexts) available. */ 557 return scnprintf(buf, PAGE_SIZE, "%u\n", dd->freectxts); 558 } 559 560 static ssize_t show_serial(struct device *device, 561 struct device_attribute *attr, char *buf) 562 { 563 struct hfi1_ibdev *dev = 564 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 565 struct hfi1_devdata *dd = dd_from_dev(dev); 566 567 return scnprintf(buf, PAGE_SIZE, "%s", dd->serial); 568 } 569 570 static ssize_t store_chip_reset(struct device *device, 571 struct device_attribute *attr, const char *buf, 572 size_t count) 573 { 574 struct hfi1_ibdev *dev = 575 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 576 struct hfi1_devdata *dd = dd_from_dev(dev); 577 int ret; 578 579 if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 580 ret = -EINVAL; 581 goto bail; 582 } 583 584 ret = hfi1_reset_device(dd->unit); 585 bail: 586 return ret < 0 ? ret : count; 587 } 588 589 /* 590 * Convert the reported temperature from an integer (reported in 591 * units of 0.25C) to a floating point number. 592 */ 593 #define temp2str(temp, buf, size, idx) \ 594 scnprintf((buf) + (idx), (size) - (idx), "%u.%02u ", \ 595 ((temp) >> 2), ((temp) & 0x3) * 25) 596 597 /* 598 * Dump tempsense values, in decimal, to ease shell-scripts. 599 */ 600 static ssize_t show_tempsense(struct device *device, 601 struct device_attribute *attr, char *buf) 602 { 603 struct hfi1_ibdev *dev = 604 container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); 605 struct hfi1_devdata *dd = dd_from_dev(dev); 606 struct hfi1_temp temp; 607 int ret; 608 609 ret = hfi1_tempsense_rd(dd, &temp); 610 if (!ret) { 611 int idx = 0; 612 613 idx += temp2str(temp.curr, buf, PAGE_SIZE, idx); 614 idx += temp2str(temp.lo_lim, buf, PAGE_SIZE, idx); 615 idx += temp2str(temp.hi_lim, buf, PAGE_SIZE, idx); 616 idx += temp2str(temp.crit_lim, buf, PAGE_SIZE, idx); 617 idx += scnprintf(buf + idx, PAGE_SIZE - idx, 618 "%u %u %u\n", temp.triggers & 0x1, 619 temp.triggers & 0x2, temp.triggers & 0x4); 620 ret = idx; 621 } 622 return ret; 623 } 624 625 /* 626 * end of per-unit (or driver, in some cases, but replicated 627 * per unit) functions 628 */ 629 630 /* start of per-unit file structures and support code */ 631 static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 632 static DEVICE_ATTR(board_id, S_IRUGO, show_hfi, NULL); 633 static DEVICE_ATTR(nctxts, S_IRUGO, show_nctxts, NULL); 634 static DEVICE_ATTR(nfreectxts, S_IRUGO, show_nfreectxts, NULL); 635 static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); 636 static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); 637 static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); 638 static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); 639 640 static struct device_attribute *hfi1_attributes[] = { 641 &dev_attr_hw_rev, 642 &dev_attr_board_id, 643 &dev_attr_nctxts, 644 &dev_attr_nfreectxts, 645 &dev_attr_serial, 646 &dev_attr_boardversion, 647 &dev_attr_tempsense, 648 &dev_attr_chip_reset, 649 }; 650 651 int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, 652 struct kobject *kobj) 653 { 654 struct hfi1_pportdata *ppd; 655 struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 656 int ret; 657 658 if (!port_num || port_num > dd->num_pports) { 659 dd_dev_err(dd, 660 "Skipping infiniband class with invalid port %u\n", 661 port_num); 662 return -ENODEV; 663 } 664 ppd = &dd->pport[port_num - 1]; 665 666 ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj, 667 "sc2vl"); 668 if (ret) { 669 dd_dev_err(dd, 670 "Skipping sc2vl sysfs info, (err %d) port %u\n", 671 ret, port_num); 672 goto bail; 673 } 674 kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); 675 676 ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj, 677 "sl2sc"); 678 if (ret) { 679 dd_dev_err(dd, 680 "Skipping sl2sc sysfs info, (err %d) port %u\n", 681 ret, port_num); 682 goto bail_sc2vl; 683 } 684 kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); 685 686 ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj, 687 "vl2mtu"); 688 if (ret) { 689 dd_dev_err(dd, 690 "Skipping vl2mtu sysfs info, (err %d) port %u\n", 691 ret, port_num); 692 goto bail_sl2sc; 693 } 694 kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); 695 696 ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype, 697 kobj, "CCMgtA"); 698 if (ret) { 699 dd_dev_err(dd, 700 "Skipping Congestion Control sysfs info, (err %d) port %u\n", 701 ret, port_num); 702 goto bail_vl2mtu; 703 } 704 705 kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); 706 707 ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); 708 if (ret) { 709 dd_dev_err(dd, 710 "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", 711 ret, port_num); 712 goto bail_cc; 713 } 714 715 ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); 716 if (ret) { 717 dd_dev_err(dd, 718 "Skipping Congestion Control table sysfs info, (err %d) port %u\n", 719 ret, port_num); 720 goto bail_cc_entry_bin; 721 } 722 723 dd_dev_info(dd, 724 "Congestion Control Agent enabled for port %d\n", 725 port_num); 726 727 return 0; 728 729 bail_cc_entry_bin: 730 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 731 &cc_setting_bin_attr); 732 bail_cc: 733 kobject_put(&ppd->pport_cc_kobj); 734 bail_vl2mtu: 735 kobject_put(&ppd->vl2mtu_kobj); 736 bail_sl2sc: 737 kobject_put(&ppd->sl2sc_kobj); 738 bail_sc2vl: 739 kobject_put(&ppd->sc2vl_kobj); 740 bail: 741 return ret; 742 } 743 744 /* 745 * Register and create our files in /sys/class/infiniband. 746 */ 747 int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd) 748 { 749 struct ib_device *dev = &dd->verbs_dev.rdi.ibdev; 750 int i, ret; 751 752 for (i = 0; i < ARRAY_SIZE(hfi1_attributes); ++i) { 753 ret = device_create_file(&dev->dev, hfi1_attributes[i]); 754 if (ret) 755 goto bail; 756 } 757 758 return 0; 759 bail: 760 for (i = 0; i < ARRAY_SIZE(hfi1_attributes); ++i) 761 device_remove_file(&dev->dev, hfi1_attributes[i]); 762 return ret; 763 } 764 765 /* 766 * Unregister and remove our files in /sys/class/infiniband. 767 */ 768 void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd) 769 { 770 struct hfi1_pportdata *ppd; 771 int i; 772 773 for (i = 0; i < dd->num_pports; i++) { 774 ppd = &dd->pport[i]; 775 776 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 777 &cc_setting_bin_attr); 778 sysfs_remove_bin_file(&ppd->pport_cc_kobj, 779 &cc_table_bin_attr); 780 kobject_put(&ppd->pport_cc_kobj); 781 kobject_put(&ppd->vl2mtu_kobj); 782 kobject_put(&ppd->sl2sc_kobj); 783 kobject_put(&ppd->sc2vl_kobj); 784 } 785 } 786