1 /*
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 */
read_cc_table_bin(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)64 static 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
port_release(struct kobject * kobj)97 static void port_release(struct kobject *kobj)
98 {
99 /* nothing to do since memory is freed by hfi1_free_devdata() */
100 }
101
102 static struct kobj_type port_cc_ktype = {
103 .release = port_release,
104 };
105
106 static 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 */
read_cc_setting_bin(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)117 static 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
148 static 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
161 struct hfi1_sc2vl_attr {
162 struct attribute attr;
163 int sc;
164 };
165
166 HFI1_SC2VL_ATTR(0);
167 HFI1_SC2VL_ATTR(1);
168 HFI1_SC2VL_ATTR(2);
169 HFI1_SC2VL_ATTR(3);
170 HFI1_SC2VL_ATTR(4);
171 HFI1_SC2VL_ATTR(5);
172 HFI1_SC2VL_ATTR(6);
173 HFI1_SC2VL_ATTR(7);
174 HFI1_SC2VL_ATTR(8);
175 HFI1_SC2VL_ATTR(9);
176 HFI1_SC2VL_ATTR(10);
177 HFI1_SC2VL_ATTR(11);
178 HFI1_SC2VL_ATTR(12);
179 HFI1_SC2VL_ATTR(13);
180 HFI1_SC2VL_ATTR(14);
181 HFI1_SC2VL_ATTR(15);
182 HFI1_SC2VL_ATTR(16);
183 HFI1_SC2VL_ATTR(17);
184 HFI1_SC2VL_ATTR(18);
185 HFI1_SC2VL_ATTR(19);
186 HFI1_SC2VL_ATTR(20);
187 HFI1_SC2VL_ATTR(21);
188 HFI1_SC2VL_ATTR(22);
189 HFI1_SC2VL_ATTR(23);
190 HFI1_SC2VL_ATTR(24);
191 HFI1_SC2VL_ATTR(25);
192 HFI1_SC2VL_ATTR(26);
193 HFI1_SC2VL_ATTR(27);
194 HFI1_SC2VL_ATTR(28);
195 HFI1_SC2VL_ATTR(29);
196 HFI1_SC2VL_ATTR(30);
197 HFI1_SC2VL_ATTR(31);
198
199
200 static 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
sc2vl_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)236 static 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
248 static const struct sysfs_ops hfi1_sc2vl_ops = {
249 .show = sc2vl_attr_show,
250 };
251
252 static 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
267 struct hfi1_sl2sc_attr {
268 struct attribute attr;
269 int sl;
270 };
271
272 HFI1_SL2SC_ATTR(0);
273 HFI1_SL2SC_ATTR(1);
274 HFI1_SL2SC_ATTR(2);
275 HFI1_SL2SC_ATTR(3);
276 HFI1_SL2SC_ATTR(4);
277 HFI1_SL2SC_ATTR(5);
278 HFI1_SL2SC_ATTR(6);
279 HFI1_SL2SC_ATTR(7);
280 HFI1_SL2SC_ATTR(8);
281 HFI1_SL2SC_ATTR(9);
282 HFI1_SL2SC_ATTR(10);
283 HFI1_SL2SC_ATTR(11);
284 HFI1_SL2SC_ATTR(12);
285 HFI1_SL2SC_ATTR(13);
286 HFI1_SL2SC_ATTR(14);
287 HFI1_SL2SC_ATTR(15);
288 HFI1_SL2SC_ATTR(16);
289 HFI1_SL2SC_ATTR(17);
290 HFI1_SL2SC_ATTR(18);
291 HFI1_SL2SC_ATTR(19);
292 HFI1_SL2SC_ATTR(20);
293 HFI1_SL2SC_ATTR(21);
294 HFI1_SL2SC_ATTR(22);
295 HFI1_SL2SC_ATTR(23);
296 HFI1_SL2SC_ATTR(24);
297 HFI1_SL2SC_ATTR(25);
298 HFI1_SL2SC_ATTR(26);
299 HFI1_SL2SC_ATTR(27);
300 HFI1_SL2SC_ATTR(28);
301 HFI1_SL2SC_ATTR(29);
302 HFI1_SL2SC_ATTR(30);
303 HFI1_SL2SC_ATTR(31);
304
305
306 static 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
sl2sc_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)342 static 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
354 static const struct sysfs_ops hfi1_sl2sc_ops = {
355 .show = sl2sc_attr_show,
356 };
357
358 static 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
374 struct hfi1_vl2mtu_attr {
375 struct attribute attr;
376 int vl;
377 };
378
379 HFI1_VL2MTU_ATTR(0);
380 HFI1_VL2MTU_ATTR(1);
381 HFI1_VL2MTU_ATTR(2);
382 HFI1_VL2MTU_ATTR(3);
383 HFI1_VL2MTU_ATTR(4);
384 HFI1_VL2MTU_ATTR(5);
385 HFI1_VL2MTU_ATTR(6);
386 HFI1_VL2MTU_ATTR(7);
387 HFI1_VL2MTU_ATTR(8);
388 HFI1_VL2MTU_ATTR(9);
389 HFI1_VL2MTU_ATTR(10);
390 HFI1_VL2MTU_ATTR(11);
391 HFI1_VL2MTU_ATTR(12);
392 HFI1_VL2MTU_ATTR(13);
393 HFI1_VL2MTU_ATTR(14);
394 HFI1_VL2MTU_ATTR(15);
395
396 static 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
vl2mtu_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)416 static 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
428 static const struct sysfs_ops hfi1_vl2mtu_ops = {
429 .show = vl2mtu_attr_show,
430 };
431
432 static 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 */
show_rev(struct device * device,struct device_attribute * attr,char * buf)445 static ssize_t show_rev(struct device *device, struct device_attribute *attr,
446 char *buf)
447 {
448 struct hfi1_ibdev *dev =
449 container_of(device, struct hfi1_ibdev, ibdev.dev);
450
451 return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev);
452 }
453
show_hfi(struct device * device,struct device_attribute * attr,char * buf)454 static ssize_t show_hfi(struct device *device, struct device_attribute *attr,
455 char *buf)
456 {
457 struct hfi1_ibdev *dev =
458 container_of(device, struct hfi1_ibdev, ibdev.dev);
459 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
show_boardversion(struct device * device,struct device_attribute * attr,char * buf)469 static ssize_t show_boardversion(struct device *device,
470 struct device_attribute *attr, char *buf)
471 {
472 struct hfi1_ibdev *dev =
473 container_of(device, struct hfi1_ibdev, ibdev.dev);
474 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
show_nctxts(struct device * device,struct device_attribute * attr,char * buf)481 static ssize_t show_nctxts(struct device *device,
482 struct device_attribute *attr, char *buf)
483 {
484 struct hfi1_ibdev *dev =
485 container_of(device, struct hfi1_ibdev, ibdev.dev);
486 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
show_nfreectxts(struct device * device,struct device_attribute * attr,char * buf)499 static ssize_t show_nfreectxts(struct device *device,
500 struct device_attribute *attr, char *buf)
501 {
502 struct hfi1_ibdev *dev =
503 container_of(device, struct hfi1_ibdev, ibdev.dev);
504 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
show_serial(struct device * device,struct device_attribute * attr,char * buf)510 static ssize_t show_serial(struct device *device,
511 struct device_attribute *attr, char *buf)
512 {
513 struct hfi1_ibdev *dev =
514 container_of(device, struct hfi1_ibdev, ibdev.dev);
515 struct hfi1_devdata *dd = dd_from_dev(dev);
516
517 return scnprintf(buf, PAGE_SIZE, "%s", dd->serial);
518
519 }
520
store_chip_reset(struct device * device,struct device_attribute * attr,const char * buf,size_t count)521 static 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 =
526 container_of(device, struct hfi1_ibdev, ibdev.dev);
527 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);
536 bail:
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 */
show_tempsense(struct device * device,struct device_attribute * attr,char * buf)551 static ssize_t show_tempsense(struct device *device,
552 struct device_attribute *attr, char *buf)
553 {
554 struct hfi1_ibdev *dev =
555 container_of(device, struct hfi1_ibdev, ibdev.dev);
556 struct hfi1_devdata *dd = dd_from_dev(dev);
557 struct hfi1_temp temp;
558 int ret;
559
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 */
582 static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
583 static DEVICE_ATTR(board_id, S_IRUGO, show_hfi, NULL);
584 static DEVICE_ATTR(nctxts, S_IRUGO, show_nctxts, NULL);
585 static DEVICE_ATTR(nfreectxts, S_IRUGO, show_nfreectxts, NULL);
586 static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
587 static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
588 static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL);
589 static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset);
590
591 static 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
hfi1_create_port_files(struct ib_device * ibdev,u8 port_num,struct kobject * kobj)602 int 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
683 bail_cc_entry_bin:
684 sysfs_remove_bin_file(&ppd->pport_cc_kobj,
685 &cc_setting_bin_attr);
686 bail_cc:
687 kobject_put(&ppd->pport_cc_kobj);
688 bail_vl2mtu:
689 kobject_put(&ppd->vl2mtu_kobj);
690 bail_sl2sc:
691 kobject_put(&ppd->sl2sc_kobj);
692 bail_sc2vl:
693 kobject_put(&ppd->sc2vl_kobj);
694 bail:
695 return ret;
696 }
697
698 /*
699 * Register and create our files in /sys/class/infiniband.
700 */
hfi1_verbs_register_sysfs(struct hfi1_devdata * dd)701 int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd)
702 {
703 struct ib_device *dev = &dd->verbs_dev.ibdev;
704 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;
713 bail:
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 */
hfi1_verbs_unregister_sysfs(struct hfi1_devdata * dd)722 void 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 }
740