xref: /openbmc/linux/drivers/infiniband/hw/hfi1/sysfs.c (revision ee7da21a)
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 #include <rdma/ib_sysfs.h>
49 
50 #include "hfi.h"
51 #include "mad.h"
52 #include "trace.h"
53 
54 static struct hfi1_pportdata *hfi1_get_pportdata_kobj(struct kobject *kobj)
55 {
56 	u32 port_num;
57 	struct ib_device *ibdev = ib_port_sysfs_get_ibdev_kobj(kobj, &port_num);
58 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
59 
60 	return &dd->pport[port_num - 1];
61 }
62 
63 /*
64  * Start of per-port congestion control structures and support code
65  */
66 
67 /*
68  * Congestion control table size followed by table entries
69  */
70 static ssize_t cc_table_bin_read(struct file *filp, struct kobject *kobj,
71 				 struct bin_attribute *bin_attr, char *buf,
72 				 loff_t pos, size_t count)
73 {
74 	int ret;
75 	struct hfi1_pportdata *ppd = hfi1_get_pportdata_kobj(kobj);
76 	struct cc_state *cc_state;
77 
78 	ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow)
79 		 + sizeof(__be16);
80 
81 	if (pos > ret)
82 		return -EINVAL;
83 
84 	if (count > ret - pos)
85 		count = ret - pos;
86 
87 	if (!count)
88 		return count;
89 
90 	rcu_read_lock();
91 	cc_state = get_cc_state(ppd);
92 	if (!cc_state) {
93 		rcu_read_unlock();
94 		return -EINVAL;
95 	}
96 	memcpy(buf, (void *)&cc_state->cct + pos, count);
97 	rcu_read_unlock();
98 
99 	return count;
100 }
101 static BIN_ATTR_RO(cc_table_bin, PAGE_SIZE);
102 
103 /*
104  * Congestion settings: port control, control map and an array of 16
105  * entries for the congestion entries - increase, timer, event log
106  * trigger threshold and the minimum injection rate delay.
107  */
108 static ssize_t cc_setting_bin_read(struct file *filp, struct kobject *kobj,
109 				   struct bin_attribute *bin_attr,
110 				   char *buf, loff_t pos, size_t count)
111 {
112 	struct hfi1_pportdata *ppd = hfi1_get_pportdata_kobj(kobj);
113 	int ret;
114 	struct cc_state *cc_state;
115 
116 	ret = sizeof(struct opa_congestion_setting_attr_shadow);
117 
118 	if (pos > ret)
119 		return -EINVAL;
120 	if (count > ret - pos)
121 		count = ret - pos;
122 
123 	if (!count)
124 		return count;
125 
126 	rcu_read_lock();
127 	cc_state = get_cc_state(ppd);
128 	if (!cc_state) {
129 		rcu_read_unlock();
130 		return -EINVAL;
131 	}
132 	memcpy(buf, (void *)&cc_state->cong_setting + pos, count);
133 	rcu_read_unlock();
134 
135 	return count;
136 }
137 static BIN_ATTR_RO(cc_setting_bin, PAGE_SIZE);
138 
139 static struct bin_attribute *port_cc_bin_attributes[] = {
140 	&bin_attr_cc_setting_bin,
141 	&bin_attr_cc_table_bin,
142 	NULL
143 };
144 
145 static ssize_t cc_prescan_show(struct ib_device *ibdev, u32 port_num,
146 			       struct ib_port_attribute *attr, char *buf)
147 {
148 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
149 	struct hfi1_pportdata *ppd = &dd->pport[port_num - 1];
150 
151 	return sysfs_emit(buf, "%s\n", ppd->cc_prescan ? "on" : "off");
152 }
153 
154 static ssize_t cc_prescan_store(struct ib_device *ibdev, u32 port_num,
155 				struct ib_port_attribute *attr, const char *buf,
156 				size_t count)
157 {
158 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
159 	struct hfi1_pportdata *ppd = &dd->pport[port_num - 1];
160 
161 	if (!memcmp(buf, "on", 2))
162 		ppd->cc_prescan = true;
163 	else if (!memcmp(buf, "off", 3))
164 		ppd->cc_prescan = false;
165 
166 	return count;
167 }
168 static IB_PORT_ATTR_ADMIN_RW(cc_prescan);
169 
170 static struct attribute *port_cc_attributes[] = {
171 	&ib_port_attr_cc_prescan.attr,
172 	NULL
173 };
174 
175 static const struct attribute_group port_cc_group = {
176 	.name = "CCMgtA",
177 	.attrs = port_cc_attributes,
178 	.bin_attrs = port_cc_bin_attributes,
179 };
180 
181 /* Start sc2vl */
182 struct hfi1_sc2vl_attr {
183 	struct ib_port_attribute attr;
184 	int sc;
185 };
186 
187 static ssize_t sc2vl_attr_show(struct ib_device *ibdev, u32 port_num,
188 			       struct ib_port_attribute *attr, char *buf)
189 {
190 	struct hfi1_sc2vl_attr *sattr =
191 		container_of(attr, struct hfi1_sc2vl_attr, attr);
192 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
193 
194 	return sysfs_emit(buf, "%u\n", *((u8 *)dd->sc2vl + sattr->sc));
195 }
196 
197 #define HFI1_SC2VL_ATTR(N)                                                     \
198 	static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = {                  \
199 		.attr = __ATTR(N, 0444, sc2vl_attr_show, NULL),                \
200 		.sc = N,                                                       \
201 	}
202 
203 HFI1_SC2VL_ATTR(0);
204 HFI1_SC2VL_ATTR(1);
205 HFI1_SC2VL_ATTR(2);
206 HFI1_SC2VL_ATTR(3);
207 HFI1_SC2VL_ATTR(4);
208 HFI1_SC2VL_ATTR(5);
209 HFI1_SC2VL_ATTR(6);
210 HFI1_SC2VL_ATTR(7);
211 HFI1_SC2VL_ATTR(8);
212 HFI1_SC2VL_ATTR(9);
213 HFI1_SC2VL_ATTR(10);
214 HFI1_SC2VL_ATTR(11);
215 HFI1_SC2VL_ATTR(12);
216 HFI1_SC2VL_ATTR(13);
217 HFI1_SC2VL_ATTR(14);
218 HFI1_SC2VL_ATTR(15);
219 HFI1_SC2VL_ATTR(16);
220 HFI1_SC2VL_ATTR(17);
221 HFI1_SC2VL_ATTR(18);
222 HFI1_SC2VL_ATTR(19);
223 HFI1_SC2VL_ATTR(20);
224 HFI1_SC2VL_ATTR(21);
225 HFI1_SC2VL_ATTR(22);
226 HFI1_SC2VL_ATTR(23);
227 HFI1_SC2VL_ATTR(24);
228 HFI1_SC2VL_ATTR(25);
229 HFI1_SC2VL_ATTR(26);
230 HFI1_SC2VL_ATTR(27);
231 HFI1_SC2VL_ATTR(28);
232 HFI1_SC2VL_ATTR(29);
233 HFI1_SC2VL_ATTR(30);
234 HFI1_SC2VL_ATTR(31);
235 
236 static struct attribute *port_sc2vl_attributes[] = {
237 	&hfi1_sc2vl_attr_0.attr.attr,
238 	&hfi1_sc2vl_attr_1.attr.attr,
239 	&hfi1_sc2vl_attr_2.attr.attr,
240 	&hfi1_sc2vl_attr_3.attr.attr,
241 	&hfi1_sc2vl_attr_4.attr.attr,
242 	&hfi1_sc2vl_attr_5.attr.attr,
243 	&hfi1_sc2vl_attr_6.attr.attr,
244 	&hfi1_sc2vl_attr_7.attr.attr,
245 	&hfi1_sc2vl_attr_8.attr.attr,
246 	&hfi1_sc2vl_attr_9.attr.attr,
247 	&hfi1_sc2vl_attr_10.attr.attr,
248 	&hfi1_sc2vl_attr_11.attr.attr,
249 	&hfi1_sc2vl_attr_12.attr.attr,
250 	&hfi1_sc2vl_attr_13.attr.attr,
251 	&hfi1_sc2vl_attr_14.attr.attr,
252 	&hfi1_sc2vl_attr_15.attr.attr,
253 	&hfi1_sc2vl_attr_16.attr.attr,
254 	&hfi1_sc2vl_attr_17.attr.attr,
255 	&hfi1_sc2vl_attr_18.attr.attr,
256 	&hfi1_sc2vl_attr_19.attr.attr,
257 	&hfi1_sc2vl_attr_20.attr.attr,
258 	&hfi1_sc2vl_attr_21.attr.attr,
259 	&hfi1_sc2vl_attr_22.attr.attr,
260 	&hfi1_sc2vl_attr_23.attr.attr,
261 	&hfi1_sc2vl_attr_24.attr.attr,
262 	&hfi1_sc2vl_attr_25.attr.attr,
263 	&hfi1_sc2vl_attr_26.attr.attr,
264 	&hfi1_sc2vl_attr_27.attr.attr,
265 	&hfi1_sc2vl_attr_28.attr.attr,
266 	&hfi1_sc2vl_attr_29.attr.attr,
267 	&hfi1_sc2vl_attr_30.attr.attr,
268 	&hfi1_sc2vl_attr_31.attr.attr,
269 	NULL
270 };
271 
272 static const struct attribute_group port_sc2vl_group = {
273 	.name = "sc2vl",
274 	.attrs = port_sc2vl_attributes,
275 };
276 /* End sc2vl */
277 
278 /* Start sl2sc */
279 struct hfi1_sl2sc_attr {
280 	struct ib_port_attribute attr;
281 	int sl;
282 };
283 
284 static ssize_t sl2sc_attr_show(struct ib_device *ibdev, u32 port_num,
285 			       struct ib_port_attribute *attr, char *buf)
286 {
287 	struct hfi1_sl2sc_attr *sattr =
288 		container_of(attr, struct hfi1_sl2sc_attr, attr);
289 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
290 	struct hfi1_ibport *ibp = &dd->pport[port_num - 1].ibport_data;
291 
292 	return sysfs_emit(buf, "%u\n", ibp->sl_to_sc[sattr->sl]);
293 }
294 
295 #define HFI1_SL2SC_ATTR(N)                                                     \
296 	static struct hfi1_sl2sc_attr hfi1_sl2sc_attr_##N = {                  \
297 		.attr = __ATTR(N, 0444, sl2sc_attr_show, NULL), .sl = N        \
298 	}
299 
300 HFI1_SL2SC_ATTR(0);
301 HFI1_SL2SC_ATTR(1);
302 HFI1_SL2SC_ATTR(2);
303 HFI1_SL2SC_ATTR(3);
304 HFI1_SL2SC_ATTR(4);
305 HFI1_SL2SC_ATTR(5);
306 HFI1_SL2SC_ATTR(6);
307 HFI1_SL2SC_ATTR(7);
308 HFI1_SL2SC_ATTR(8);
309 HFI1_SL2SC_ATTR(9);
310 HFI1_SL2SC_ATTR(10);
311 HFI1_SL2SC_ATTR(11);
312 HFI1_SL2SC_ATTR(12);
313 HFI1_SL2SC_ATTR(13);
314 HFI1_SL2SC_ATTR(14);
315 HFI1_SL2SC_ATTR(15);
316 HFI1_SL2SC_ATTR(16);
317 HFI1_SL2SC_ATTR(17);
318 HFI1_SL2SC_ATTR(18);
319 HFI1_SL2SC_ATTR(19);
320 HFI1_SL2SC_ATTR(20);
321 HFI1_SL2SC_ATTR(21);
322 HFI1_SL2SC_ATTR(22);
323 HFI1_SL2SC_ATTR(23);
324 HFI1_SL2SC_ATTR(24);
325 HFI1_SL2SC_ATTR(25);
326 HFI1_SL2SC_ATTR(26);
327 HFI1_SL2SC_ATTR(27);
328 HFI1_SL2SC_ATTR(28);
329 HFI1_SL2SC_ATTR(29);
330 HFI1_SL2SC_ATTR(30);
331 HFI1_SL2SC_ATTR(31);
332 
333 static struct attribute *port_sl2sc_attributes[] = {
334 	&hfi1_sl2sc_attr_0.attr.attr,
335 	&hfi1_sl2sc_attr_1.attr.attr,
336 	&hfi1_sl2sc_attr_2.attr.attr,
337 	&hfi1_sl2sc_attr_3.attr.attr,
338 	&hfi1_sl2sc_attr_4.attr.attr,
339 	&hfi1_sl2sc_attr_5.attr.attr,
340 	&hfi1_sl2sc_attr_6.attr.attr,
341 	&hfi1_sl2sc_attr_7.attr.attr,
342 	&hfi1_sl2sc_attr_8.attr.attr,
343 	&hfi1_sl2sc_attr_9.attr.attr,
344 	&hfi1_sl2sc_attr_10.attr.attr,
345 	&hfi1_sl2sc_attr_11.attr.attr,
346 	&hfi1_sl2sc_attr_12.attr.attr,
347 	&hfi1_sl2sc_attr_13.attr.attr,
348 	&hfi1_sl2sc_attr_14.attr.attr,
349 	&hfi1_sl2sc_attr_15.attr.attr,
350 	&hfi1_sl2sc_attr_16.attr.attr,
351 	&hfi1_sl2sc_attr_17.attr.attr,
352 	&hfi1_sl2sc_attr_18.attr.attr,
353 	&hfi1_sl2sc_attr_19.attr.attr,
354 	&hfi1_sl2sc_attr_20.attr.attr,
355 	&hfi1_sl2sc_attr_21.attr.attr,
356 	&hfi1_sl2sc_attr_22.attr.attr,
357 	&hfi1_sl2sc_attr_23.attr.attr,
358 	&hfi1_sl2sc_attr_24.attr.attr,
359 	&hfi1_sl2sc_attr_25.attr.attr,
360 	&hfi1_sl2sc_attr_26.attr.attr,
361 	&hfi1_sl2sc_attr_27.attr.attr,
362 	&hfi1_sl2sc_attr_28.attr.attr,
363 	&hfi1_sl2sc_attr_29.attr.attr,
364 	&hfi1_sl2sc_attr_30.attr.attr,
365 	&hfi1_sl2sc_attr_31.attr.attr,
366 	NULL
367 };
368 
369 static const struct attribute_group port_sl2sc_group = {
370 	.name = "sl2sc",
371 	.attrs = port_sl2sc_attributes,
372 };
373 
374 /* End sl2sc */
375 
376 /* Start vl2mtu */
377 
378 struct hfi1_vl2mtu_attr {
379 	struct ib_port_attribute attr;
380 	int vl;
381 };
382 
383 static ssize_t vl2mtu_attr_show(struct ib_device *ibdev, u32 port_num,
384 				struct ib_port_attribute *attr, char *buf)
385 {
386 	struct hfi1_vl2mtu_attr *vlattr =
387 		container_of(attr, struct hfi1_vl2mtu_attr, attr);
388 	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
389 
390 	return sysfs_emit(buf, "%u\n", dd->vld[vlattr->vl].mtu);
391 }
392 
393 #define HFI1_VL2MTU_ATTR(N)                                                    \
394 	static struct hfi1_vl2mtu_attr hfi1_vl2mtu_attr_##N = {                \
395 		.attr = __ATTR(N, 0444, vl2mtu_attr_show, NULL),               \
396 		.vl = N,                                                       \
397 	}
398 
399 HFI1_VL2MTU_ATTR(0);
400 HFI1_VL2MTU_ATTR(1);
401 HFI1_VL2MTU_ATTR(2);
402 HFI1_VL2MTU_ATTR(3);
403 HFI1_VL2MTU_ATTR(4);
404 HFI1_VL2MTU_ATTR(5);
405 HFI1_VL2MTU_ATTR(6);
406 HFI1_VL2MTU_ATTR(7);
407 HFI1_VL2MTU_ATTR(8);
408 HFI1_VL2MTU_ATTR(9);
409 HFI1_VL2MTU_ATTR(10);
410 HFI1_VL2MTU_ATTR(11);
411 HFI1_VL2MTU_ATTR(12);
412 HFI1_VL2MTU_ATTR(13);
413 HFI1_VL2MTU_ATTR(14);
414 HFI1_VL2MTU_ATTR(15);
415 
416 static struct attribute *port_vl2mtu_attributes[] = {
417 	&hfi1_vl2mtu_attr_0.attr.attr,
418 	&hfi1_vl2mtu_attr_1.attr.attr,
419 	&hfi1_vl2mtu_attr_2.attr.attr,
420 	&hfi1_vl2mtu_attr_3.attr.attr,
421 	&hfi1_vl2mtu_attr_4.attr.attr,
422 	&hfi1_vl2mtu_attr_5.attr.attr,
423 	&hfi1_vl2mtu_attr_6.attr.attr,
424 	&hfi1_vl2mtu_attr_7.attr.attr,
425 	&hfi1_vl2mtu_attr_8.attr.attr,
426 	&hfi1_vl2mtu_attr_9.attr.attr,
427 	&hfi1_vl2mtu_attr_10.attr.attr,
428 	&hfi1_vl2mtu_attr_11.attr.attr,
429 	&hfi1_vl2mtu_attr_12.attr.attr,
430 	&hfi1_vl2mtu_attr_13.attr.attr,
431 	&hfi1_vl2mtu_attr_14.attr.attr,
432 	&hfi1_vl2mtu_attr_15.attr.attr,
433 	NULL
434 };
435 
436 static const struct attribute_group port_vl2mtu_group = {
437 	.name = "vl2mtu",
438 	.attrs = port_vl2mtu_attributes,
439 };
440 
441 /* end of per-port file structures and support code */
442 
443 /*
444  * Start of per-unit (or driver, in some cases, but replicated
445  * per unit) functions (these get a device *)
446  */
447 static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr,
448 			   char *buf)
449 {
450 	struct hfi1_ibdev *dev =
451 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
452 
453 	return sysfs_emit(buf, "%x\n", dd_from_dev(dev)->minrev);
454 }
455 static DEVICE_ATTR_RO(hw_rev);
456 
457 static ssize_t board_id_show(struct device *device,
458 			     struct device_attribute *attr, char *buf)
459 {
460 	struct hfi1_ibdev *dev =
461 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
462 	struct hfi1_devdata *dd = dd_from_dev(dev);
463 
464 	if (!dd->boardname)
465 		return -EINVAL;
466 
467 	return sysfs_emit(buf, "%s\n", dd->boardname);
468 }
469 static DEVICE_ATTR_RO(board_id);
470 
471 static ssize_t boardversion_show(struct device *device,
472 				 struct device_attribute *attr, char *buf)
473 {
474 	struct hfi1_ibdev *dev =
475 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
476 	struct hfi1_devdata *dd = dd_from_dev(dev);
477 
478 	/* The string printed here is already newline-terminated. */
479 	return sysfs_emit(buf, "%s", dd->boardversion);
480 }
481 static DEVICE_ATTR_RO(boardversion);
482 
483 static ssize_t nctxts_show(struct device *device,
484 			   struct device_attribute *attr, char *buf)
485 {
486 	struct hfi1_ibdev *dev =
487 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
488 	struct hfi1_devdata *dd = dd_from_dev(dev);
489 
490 	/*
491 	 * Return the smaller of send and receive contexts.
492 	 * Normally, user level applications would require both a send
493 	 * and a receive context, so returning the smaller of the two counts
494 	 * give a more accurate picture of total contexts available.
495 	 */
496 	return sysfs_emit(buf, "%u\n",
497 			  min(dd->num_user_contexts,
498 			      (u32)dd->sc_sizes[SC_USER].count));
499 }
500 static DEVICE_ATTR_RO(nctxts);
501 
502 static ssize_t nfreectxts_show(struct device *device,
503 			       struct device_attribute *attr, char *buf)
504 {
505 	struct hfi1_ibdev *dev =
506 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
507 	struct hfi1_devdata *dd = dd_from_dev(dev);
508 
509 	/* Return the number of free user ports (contexts) available. */
510 	return sysfs_emit(buf, "%u\n", dd->freectxts);
511 }
512 static DEVICE_ATTR_RO(nfreectxts);
513 
514 static ssize_t serial_show(struct device *device,
515 			   struct device_attribute *attr, char *buf)
516 {
517 	struct hfi1_ibdev *dev =
518 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
519 	struct hfi1_devdata *dd = dd_from_dev(dev);
520 
521 	/* dd->serial is already newline terminated in chip.c */
522 	return sysfs_emit(buf, "%s", dd->serial);
523 }
524 static DEVICE_ATTR_RO(serial);
525 
526 static ssize_t chip_reset_store(struct device *device,
527 				struct device_attribute *attr, const char *buf,
528 				size_t count)
529 {
530 	struct hfi1_ibdev *dev =
531 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
532 	struct hfi1_devdata *dd = dd_from_dev(dev);
533 	int ret;
534 
535 	if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) {
536 		ret = -EINVAL;
537 		goto bail;
538 	}
539 
540 	ret = hfi1_reset_device(dd->unit);
541 bail:
542 	return ret < 0 ? ret : count;
543 }
544 static DEVICE_ATTR_WO(chip_reset);
545 
546 /*
547  * Convert the reported temperature from an integer (reported in
548  * units of 0.25C) to a floating point number.
549  */
550 #define temp_d(t) ((t) >> 2)
551 #define temp_f(t) (((t)&0x3) * 25u)
552 
553 /*
554  * Dump tempsense values, in decimal, to ease shell-scripts.
555  */
556 static ssize_t tempsense_show(struct device *device,
557 			      struct device_attribute *attr, char *buf)
558 {
559 	struct hfi1_ibdev *dev =
560 		rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev);
561 	struct hfi1_devdata *dd = dd_from_dev(dev);
562 	struct hfi1_temp temp;
563 	int ret;
564 
565 	ret = hfi1_tempsense_rd(dd, &temp);
566 	if (ret)
567 		return ret;
568 
569 	return sysfs_emit(buf, "%u.%02u %u.%02u %u.%02u %u.%02u %u %u %u\n",
570 			  temp_d(temp.curr), temp_f(temp.curr),
571 			  temp_d(temp.lo_lim), temp_f(temp.lo_lim),
572 			  temp_d(temp.hi_lim), temp_f(temp.hi_lim),
573 			  temp_d(temp.crit_lim), temp_f(temp.crit_lim),
574 			  temp.triggers & 0x1,
575 			  temp.triggers & 0x2,
576 			  temp.triggers & 0x4);
577 }
578 static DEVICE_ATTR_RO(tempsense);
579 
580 /*
581  * end of per-unit (or driver, in some cases, but replicated
582  * per unit) functions
583  */
584 
585 /* start of per-unit file structures and support code */
586 static struct attribute *hfi1_attributes[] = {
587 	&dev_attr_hw_rev.attr,
588 	&dev_attr_board_id.attr,
589 	&dev_attr_nctxts.attr,
590 	&dev_attr_nfreectxts.attr,
591 	&dev_attr_serial.attr,
592 	&dev_attr_boardversion.attr,
593 	&dev_attr_tempsense.attr,
594 	&dev_attr_chip_reset.attr,
595 	NULL,
596 };
597 
598 const struct attribute_group ib_hfi1_attr_group = {
599 	.attrs = hfi1_attributes,
600 };
601 
602 const struct attribute_group *hfi1_attr_port_groups[] = {
603 	&port_cc_group,
604 	&port_sc2vl_group,
605 	&port_sl2sc_group,
606 	&port_vl2mtu_group,
607 	NULL,
608 };
609 
610 struct sde_attribute {
611 	struct attribute attr;
612 	ssize_t (*show)(struct sdma_engine *sde, char *buf);
613 	ssize_t (*store)(struct sdma_engine *sde, const char *buf, size_t cnt);
614 };
615 
616 static ssize_t sde_show(struct kobject *kobj, struct attribute *attr, char *buf)
617 {
618 	struct sde_attribute *sde_attr =
619 		container_of(attr, struct sde_attribute, attr);
620 	struct sdma_engine *sde =
621 		container_of(kobj, struct sdma_engine, kobj);
622 
623 	if (!sde_attr->show)
624 		return -EINVAL;
625 
626 	return sde_attr->show(sde, buf);
627 }
628 
629 static ssize_t sde_store(struct kobject *kobj, struct attribute *attr,
630 			 const char *buf, size_t count)
631 {
632 	struct sde_attribute *sde_attr =
633 		container_of(attr, struct sde_attribute, attr);
634 	struct sdma_engine *sde =
635 		container_of(kobj, struct sdma_engine, kobj);
636 
637 	if (!capable(CAP_SYS_ADMIN))
638 		return -EPERM;
639 
640 	if (!sde_attr->store)
641 		return -EINVAL;
642 
643 	return sde_attr->store(sde, buf, count);
644 }
645 
646 static const struct sysfs_ops sde_sysfs_ops = {
647 	.show = sde_show,
648 	.store = sde_store,
649 };
650 
651 static struct kobj_type sde_ktype = {
652 	.sysfs_ops = &sde_sysfs_ops,
653 };
654 
655 #define SDE_ATTR(_name, _mode, _show, _store) \
656 	struct sde_attribute sde_attr_##_name = \
657 		__ATTR(_name, _mode, _show, _store)
658 
659 static ssize_t sde_show_cpu_to_sde_map(struct sdma_engine *sde, char *buf)
660 {
661 	return sdma_get_cpu_to_sde_map(sde, buf);
662 }
663 
664 static ssize_t sde_store_cpu_to_sde_map(struct sdma_engine *sde,
665 					const char *buf, size_t count)
666 {
667 	return sdma_set_cpu_to_sde_map(sde, buf, count);
668 }
669 
670 static ssize_t sde_show_vl(struct sdma_engine *sde, char *buf)
671 {
672 	int vl;
673 
674 	vl = sdma_engine_get_vl(sde);
675 	if (vl < 0)
676 		return vl;
677 
678 	return sysfs_emit(buf, "%d\n", vl);
679 }
680 
681 static SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO,
682 		sde_show_cpu_to_sde_map,
683 		sde_store_cpu_to_sde_map);
684 static SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL);
685 
686 static struct sde_attribute *sde_attribs[] = {
687 	&sde_attr_cpu_list,
688 	&sde_attr_vl
689 };
690 
691 /*
692  * Register and create our files in /sys/class/infiniband.
693  */
694 int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd)
695 {
696 	struct ib_device *dev = &dd->verbs_dev.rdi.ibdev;
697 	struct device *class_dev = &dev->dev;
698 	int i, j, ret;
699 
700 	for (i = 0; i < dd->num_sdma; i++) {
701 		ret = kobject_init_and_add(&dd->per_sdma[i].kobj,
702 					   &sde_ktype, &class_dev->kobj,
703 					   "sdma%d", i);
704 		if (ret)
705 			goto bail;
706 
707 		for (j = 0; j < ARRAY_SIZE(sde_attribs); j++) {
708 			ret = sysfs_create_file(&dd->per_sdma[i].kobj,
709 						&sde_attribs[j]->attr);
710 			if (ret)
711 				goto bail;
712 		}
713 	}
714 
715 	return 0;
716 bail:
717 	/*
718 	 * The function kobject_put() will call kobject_del() if the kobject
719 	 * has been added successfully. The sysfs files created under the
720 	 * kobject directory will also be removed during the process.
721 	 */
722 	for (; i >= 0; i--)
723 		kobject_put(&dd->per_sdma[i].kobj);
724 
725 	return ret;
726 }
727 
728 /*
729  * Unregister and remove our files in /sys/class/infiniband.
730  */
731 void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd)
732 {
733 	int i;
734 
735 	/* Unwind operations in hfi1_verbs_register_sysfs() */
736 	for (i = 0; i < dd->num_sdma; i++)
737 		kobject_put(&dd->per_sdma[i].kobj);
738 }
739