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