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