18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright(c) 2015-2017 Intel Corporation. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. When using or 58c2ecf20Sopenharmony_ci * redistributing this file, you may do so under either license. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * GPL LICENSE SUMMARY 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 108c2ecf20Sopenharmony_ci * it under the terms of version 2 of the GNU General Public License as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 148c2ecf20Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 158c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 168c2ecf20Sopenharmony_ci * General Public License for more details. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * BSD LICENSE 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 218c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 228c2ecf20Sopenharmony_ci * are met: 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * - Redistributions of source code must retain the above copyright 258c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 268c2ecf20Sopenharmony_ci * - Redistributions in binary form must reproduce the above copyright 278c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 288c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 298c2ecf20Sopenharmony_ci * distribution. 308c2ecf20Sopenharmony_ci * - Neither the name of Intel Corporation nor the names of its 318c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived 328c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 358c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 368c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 378c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 388c2ecf20Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 398c2ecf20Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 408c2ecf20Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 418c2ecf20Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 428c2ecf20Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 438c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 448c2ecf20Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci#include <linux/ctype.h> 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#include "hfi.h" 508c2ecf20Sopenharmony_ci#include "mad.h" 518c2ecf20Sopenharmony_ci#include "trace.h" 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* 548c2ecf20Sopenharmony_ci * Start of per-port congestion control structures and support code 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * Congestion control table size followed by table entries 598c2ecf20Sopenharmony_ci */ 608c2ecf20Sopenharmony_cistatic ssize_t read_cc_table_bin(struct file *filp, struct kobject *kobj, 618c2ecf20Sopenharmony_ci struct bin_attribute *bin_attr, 628c2ecf20Sopenharmony_ci char *buf, loff_t pos, size_t count) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci int ret; 658c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 668c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 678c2ecf20Sopenharmony_ci struct cc_state *cc_state; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow) 708c2ecf20Sopenharmony_ci + sizeof(__be16); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci if (pos > ret) 738c2ecf20Sopenharmony_ci return -EINVAL; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci if (count > ret - pos) 768c2ecf20Sopenharmony_ci count = ret - pos; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (!count) 798c2ecf20Sopenharmony_ci return count; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci rcu_read_lock(); 828c2ecf20Sopenharmony_ci cc_state = get_cc_state(ppd); 838c2ecf20Sopenharmony_ci if (!cc_state) { 848c2ecf20Sopenharmony_ci rcu_read_unlock(); 858c2ecf20Sopenharmony_ci return -EINVAL; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci memcpy(buf, (void *)&cc_state->cct + pos, count); 888c2ecf20Sopenharmony_ci rcu_read_unlock(); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci return count; 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic void port_release(struct kobject *kobj) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci /* nothing to do since memory is freed by hfi1_free_devdata() */ 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic const struct bin_attribute cc_table_bin_attr = { 998c2ecf20Sopenharmony_ci .attr = {.name = "cc_table_bin", .mode = 0444}, 1008c2ecf20Sopenharmony_ci .read = read_cc_table_bin, 1018c2ecf20Sopenharmony_ci .size = PAGE_SIZE, 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* 1058c2ecf20Sopenharmony_ci * Congestion settings: port control, control map and an array of 16 1068c2ecf20Sopenharmony_ci * entries for the congestion entries - increase, timer, event log 1078c2ecf20Sopenharmony_ci * trigger threshold and the minimum injection rate delay. 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_cistatic ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj, 1108c2ecf20Sopenharmony_ci struct bin_attribute *bin_attr, 1118c2ecf20Sopenharmony_ci char *buf, loff_t pos, size_t count) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci int ret; 1148c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 1158c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 1168c2ecf20Sopenharmony_ci struct cc_state *cc_state; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci ret = sizeof(struct opa_congestion_setting_attr_shadow); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci if (pos > ret) 1218c2ecf20Sopenharmony_ci return -EINVAL; 1228c2ecf20Sopenharmony_ci if (count > ret - pos) 1238c2ecf20Sopenharmony_ci count = ret - pos; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (!count) 1268c2ecf20Sopenharmony_ci return count; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci rcu_read_lock(); 1298c2ecf20Sopenharmony_ci cc_state = get_cc_state(ppd); 1308c2ecf20Sopenharmony_ci if (!cc_state) { 1318c2ecf20Sopenharmony_ci rcu_read_unlock(); 1328c2ecf20Sopenharmony_ci return -EINVAL; 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci memcpy(buf, (void *)&cc_state->cong_setting + pos, count); 1358c2ecf20Sopenharmony_ci rcu_read_unlock(); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci return count; 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic const struct bin_attribute cc_setting_bin_attr = { 1418c2ecf20Sopenharmony_ci .attr = {.name = "cc_settings_bin", .mode = 0444}, 1428c2ecf20Sopenharmony_ci .read = read_cc_setting_bin, 1438c2ecf20Sopenharmony_ci .size = PAGE_SIZE, 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistruct hfi1_port_attr { 1478c2ecf20Sopenharmony_ci struct attribute attr; 1488c2ecf20Sopenharmony_ci ssize_t (*show)(struct hfi1_pportdata *, char *); 1498c2ecf20Sopenharmony_ci ssize_t (*store)(struct hfi1_pportdata *, const char *, size_t); 1508c2ecf20Sopenharmony_ci}; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic ssize_t cc_prescan_show(struct hfi1_pportdata *ppd, char *buf) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", ppd->cc_prescan ? "on" : "off"); 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic ssize_t cc_prescan_store(struct hfi1_pportdata *ppd, const char *buf, 1588c2ecf20Sopenharmony_ci size_t count) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci if (!memcmp(buf, "on", 2)) 1618c2ecf20Sopenharmony_ci ppd->cc_prescan = true; 1628c2ecf20Sopenharmony_ci else if (!memcmp(buf, "off", 3)) 1638c2ecf20Sopenharmony_ci ppd->cc_prescan = false; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci return count; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic struct hfi1_port_attr cc_prescan_attr = 1698c2ecf20Sopenharmony_ci __ATTR(cc_prescan, 0600, cc_prescan_show, cc_prescan_store); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic ssize_t cc_attr_show(struct kobject *kobj, struct attribute *attr, 1728c2ecf20Sopenharmony_ci char *buf) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci struct hfi1_port_attr *port_attr = 1758c2ecf20Sopenharmony_ci container_of(attr, struct hfi1_port_attr, attr); 1768c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 1778c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return port_attr->show(ppd, buf); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic ssize_t cc_attr_store(struct kobject *kobj, struct attribute *attr, 1838c2ecf20Sopenharmony_ci const char *buf, size_t count) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci struct hfi1_port_attr *port_attr = 1868c2ecf20Sopenharmony_ci container_of(attr, struct hfi1_port_attr, attr); 1878c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 1888c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, pport_cc_kobj); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci return port_attr->store(ppd, buf, count); 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic const struct sysfs_ops port_cc_sysfs_ops = { 1948c2ecf20Sopenharmony_ci .show = cc_attr_show, 1958c2ecf20Sopenharmony_ci .store = cc_attr_store 1968c2ecf20Sopenharmony_ci}; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic struct attribute *port_cc_default_attributes[] = { 1998c2ecf20Sopenharmony_ci &cc_prescan_attr.attr, 2008c2ecf20Sopenharmony_ci NULL 2018c2ecf20Sopenharmony_ci}; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic struct kobj_type port_cc_ktype = { 2048c2ecf20Sopenharmony_ci .release = port_release, 2058c2ecf20Sopenharmony_ci .sysfs_ops = &port_cc_sysfs_ops, 2068c2ecf20Sopenharmony_ci .default_attrs = port_cc_default_attributes 2078c2ecf20Sopenharmony_ci}; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* Start sc2vl */ 2108c2ecf20Sopenharmony_ci#define HFI1_SC2VL_ATTR(N) \ 2118c2ecf20Sopenharmony_ci static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \ 2128c2ecf20Sopenharmony_ci .attr = { .name = __stringify(N), .mode = 0444 }, \ 2138c2ecf20Sopenharmony_ci .sc = N \ 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistruct hfi1_sc2vl_attr { 2178c2ecf20Sopenharmony_ci struct attribute attr; 2188c2ecf20Sopenharmony_ci int sc; 2198c2ecf20Sopenharmony_ci}; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(0); 2228c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(1); 2238c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(2); 2248c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(3); 2258c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(4); 2268c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(5); 2278c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(6); 2288c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(7); 2298c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(8); 2308c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(9); 2318c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(10); 2328c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(11); 2338c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(12); 2348c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(13); 2358c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(14); 2368c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(15); 2378c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(16); 2388c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(17); 2398c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(18); 2408c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(19); 2418c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(20); 2428c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(21); 2438c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(22); 2448c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(23); 2458c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(24); 2468c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(25); 2478c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(26); 2488c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(27); 2498c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(28); 2508c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(29); 2518c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(30); 2528c2ecf20Sopenharmony_ciHFI1_SC2VL_ATTR(31); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic struct attribute *sc2vl_default_attributes[] = { 2558c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_0.attr, 2568c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_1.attr, 2578c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_2.attr, 2588c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_3.attr, 2598c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_4.attr, 2608c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_5.attr, 2618c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_6.attr, 2628c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_7.attr, 2638c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_8.attr, 2648c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_9.attr, 2658c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_10.attr, 2668c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_11.attr, 2678c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_12.attr, 2688c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_13.attr, 2698c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_14.attr, 2708c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_15.attr, 2718c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_16.attr, 2728c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_17.attr, 2738c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_18.attr, 2748c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_19.attr, 2758c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_20.attr, 2768c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_21.attr, 2778c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_22.attr, 2788c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_23.attr, 2798c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_24.attr, 2808c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_25.attr, 2818c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_26.attr, 2828c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_27.attr, 2838c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_28.attr, 2848c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_29.attr, 2858c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_30.attr, 2868c2ecf20Sopenharmony_ci &hfi1_sc2vl_attr_31.attr, 2878c2ecf20Sopenharmony_ci NULL 2888c2ecf20Sopenharmony_ci}; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistatic ssize_t sc2vl_attr_show(struct kobject *kobj, struct attribute *attr, 2918c2ecf20Sopenharmony_ci char *buf) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci struct hfi1_sc2vl_attr *sattr = 2948c2ecf20Sopenharmony_ci container_of(attr, struct hfi1_sc2vl_attr, attr); 2958c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 2968c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, sc2vl_kobj); 2978c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = ppd->dd; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", *((u8 *)dd->sc2vl + sattr->sc)); 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic const struct sysfs_ops hfi1_sc2vl_ops = { 3038c2ecf20Sopenharmony_ci .show = sc2vl_attr_show, 3048c2ecf20Sopenharmony_ci}; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistatic struct kobj_type hfi1_sc2vl_ktype = { 3078c2ecf20Sopenharmony_ci .release = port_release, 3088c2ecf20Sopenharmony_ci .sysfs_ops = &hfi1_sc2vl_ops, 3098c2ecf20Sopenharmony_ci .default_attrs = sc2vl_default_attributes 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci/* End sc2vl */ 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci/* Start sl2sc */ 3158c2ecf20Sopenharmony_ci#define HFI1_SL2SC_ATTR(N) \ 3168c2ecf20Sopenharmony_ci static struct hfi1_sl2sc_attr hfi1_sl2sc_attr_##N = { \ 3178c2ecf20Sopenharmony_ci .attr = { .name = __stringify(N), .mode = 0444 }, \ 3188c2ecf20Sopenharmony_ci .sl = N \ 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistruct hfi1_sl2sc_attr { 3228c2ecf20Sopenharmony_ci struct attribute attr; 3238c2ecf20Sopenharmony_ci int sl; 3248c2ecf20Sopenharmony_ci}; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(0); 3278c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(1); 3288c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(2); 3298c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(3); 3308c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(4); 3318c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(5); 3328c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(6); 3338c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(7); 3348c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(8); 3358c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(9); 3368c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(10); 3378c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(11); 3388c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(12); 3398c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(13); 3408c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(14); 3418c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(15); 3428c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(16); 3438c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(17); 3448c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(18); 3458c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(19); 3468c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(20); 3478c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(21); 3488c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(22); 3498c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(23); 3508c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(24); 3518c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(25); 3528c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(26); 3538c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(27); 3548c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(28); 3558c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(29); 3568c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(30); 3578c2ecf20Sopenharmony_ciHFI1_SL2SC_ATTR(31); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic struct attribute *sl2sc_default_attributes[] = { 3608c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_0.attr, 3618c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_1.attr, 3628c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_2.attr, 3638c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_3.attr, 3648c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_4.attr, 3658c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_5.attr, 3668c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_6.attr, 3678c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_7.attr, 3688c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_8.attr, 3698c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_9.attr, 3708c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_10.attr, 3718c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_11.attr, 3728c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_12.attr, 3738c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_13.attr, 3748c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_14.attr, 3758c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_15.attr, 3768c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_16.attr, 3778c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_17.attr, 3788c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_18.attr, 3798c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_19.attr, 3808c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_20.attr, 3818c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_21.attr, 3828c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_22.attr, 3838c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_23.attr, 3848c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_24.attr, 3858c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_25.attr, 3868c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_26.attr, 3878c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_27.attr, 3888c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_28.attr, 3898c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_29.attr, 3908c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_30.attr, 3918c2ecf20Sopenharmony_ci &hfi1_sl2sc_attr_31.attr, 3928c2ecf20Sopenharmony_ci NULL 3938c2ecf20Sopenharmony_ci}; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistatic ssize_t sl2sc_attr_show(struct kobject *kobj, struct attribute *attr, 3968c2ecf20Sopenharmony_ci char *buf) 3978c2ecf20Sopenharmony_ci{ 3988c2ecf20Sopenharmony_ci struct hfi1_sl2sc_attr *sattr = 3998c2ecf20Sopenharmony_ci container_of(attr, struct hfi1_sl2sc_attr, attr); 4008c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 4018c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, sl2sc_kobj); 4028c2ecf20Sopenharmony_ci struct hfi1_ibport *ibp = &ppd->ibport_data; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", ibp->sl_to_sc[sattr->sl]); 4058c2ecf20Sopenharmony_ci} 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic const struct sysfs_ops hfi1_sl2sc_ops = { 4088c2ecf20Sopenharmony_ci .show = sl2sc_attr_show, 4098c2ecf20Sopenharmony_ci}; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_cistatic struct kobj_type hfi1_sl2sc_ktype = { 4128c2ecf20Sopenharmony_ci .release = port_release, 4138c2ecf20Sopenharmony_ci .sysfs_ops = &hfi1_sl2sc_ops, 4148c2ecf20Sopenharmony_ci .default_attrs = sl2sc_default_attributes 4158c2ecf20Sopenharmony_ci}; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci/* End sl2sc */ 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci/* Start vl2mtu */ 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci#define HFI1_VL2MTU_ATTR(N) \ 4228c2ecf20Sopenharmony_ci static struct hfi1_vl2mtu_attr hfi1_vl2mtu_attr_##N = { \ 4238c2ecf20Sopenharmony_ci .attr = { .name = __stringify(N), .mode = 0444 }, \ 4248c2ecf20Sopenharmony_ci .vl = N \ 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistruct hfi1_vl2mtu_attr { 4288c2ecf20Sopenharmony_ci struct attribute attr; 4298c2ecf20Sopenharmony_ci int vl; 4308c2ecf20Sopenharmony_ci}; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(0); 4338c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(1); 4348c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(2); 4358c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(3); 4368c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(4); 4378c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(5); 4388c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(6); 4398c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(7); 4408c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(8); 4418c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(9); 4428c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(10); 4438c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(11); 4448c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(12); 4458c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(13); 4468c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(14); 4478c2ecf20Sopenharmony_ciHFI1_VL2MTU_ATTR(15); 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistatic struct attribute *vl2mtu_default_attributes[] = { 4508c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_0.attr, 4518c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_1.attr, 4528c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_2.attr, 4538c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_3.attr, 4548c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_4.attr, 4558c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_5.attr, 4568c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_6.attr, 4578c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_7.attr, 4588c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_8.attr, 4598c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_9.attr, 4608c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_10.attr, 4618c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_11.attr, 4628c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_12.attr, 4638c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_13.attr, 4648c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_14.attr, 4658c2ecf20Sopenharmony_ci &hfi1_vl2mtu_attr_15.attr, 4668c2ecf20Sopenharmony_ci NULL 4678c2ecf20Sopenharmony_ci}; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic ssize_t vl2mtu_attr_show(struct kobject *kobj, struct attribute *attr, 4708c2ecf20Sopenharmony_ci char *buf) 4718c2ecf20Sopenharmony_ci{ 4728c2ecf20Sopenharmony_ci struct hfi1_vl2mtu_attr *vlattr = 4738c2ecf20Sopenharmony_ci container_of(attr, struct hfi1_vl2mtu_attr, attr); 4748c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd = 4758c2ecf20Sopenharmony_ci container_of(kobj, struct hfi1_pportdata, vl2mtu_kobj); 4768c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = ppd->dd; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", dd->vld[vlattr->vl].mtu); 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_cistatic const struct sysfs_ops hfi1_vl2mtu_ops = { 4828c2ecf20Sopenharmony_ci .show = vl2mtu_attr_show, 4838c2ecf20Sopenharmony_ci}; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic struct kobj_type hfi1_vl2mtu_ktype = { 4868c2ecf20Sopenharmony_ci .release = port_release, 4878c2ecf20Sopenharmony_ci .sysfs_ops = &hfi1_vl2mtu_ops, 4888c2ecf20Sopenharmony_ci .default_attrs = vl2mtu_default_attributes 4898c2ecf20Sopenharmony_ci}; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci/* end of per-port file structures and support code */ 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci/* 4948c2ecf20Sopenharmony_ci * Start of per-unit (or driver, in some cases, but replicated 4958c2ecf20Sopenharmony_ci * per unit) functions (these get a device *) 4968c2ecf20Sopenharmony_ci */ 4978c2ecf20Sopenharmony_cistatic ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, 4988c2ecf20Sopenharmony_ci char *buf) 4998c2ecf20Sopenharmony_ci{ 5008c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5018c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); 5048c2ecf20Sopenharmony_ci} 5058c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(hw_rev); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic ssize_t board_id_show(struct device *device, 5088c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5118c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5128c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5138c2ecf20Sopenharmony_ci int ret; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci if (!dd->boardname) 5168c2ecf20Sopenharmony_ci ret = -EINVAL; 5178c2ecf20Sopenharmony_ci else 5188c2ecf20Sopenharmony_ci ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); 5198c2ecf20Sopenharmony_ci return ret; 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(board_id); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_cistatic ssize_t boardversion_show(struct device *device, 5248c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5278c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5288c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci /* The string printed here is already newline-terminated. */ 5318c2ecf20Sopenharmony_ci return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(boardversion); 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_cistatic ssize_t nctxts_show(struct device *device, 5368c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 5378c2ecf20Sopenharmony_ci{ 5388c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5398c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5408c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci /* 5438c2ecf20Sopenharmony_ci * Return the smaller of send and receive contexts. 5448c2ecf20Sopenharmony_ci * Normally, user level applications would require both a send 5458c2ecf20Sopenharmony_ci * and a receive context, so returning the smaller of the two counts 5468c2ecf20Sopenharmony_ci * give a more accurate picture of total contexts available. 5478c2ecf20Sopenharmony_ci */ 5488c2ecf20Sopenharmony_ci return scnprintf(buf, PAGE_SIZE, "%u\n", 5498c2ecf20Sopenharmony_ci min(dd->num_user_contexts, 5508c2ecf20Sopenharmony_ci (u32)dd->sc_sizes[SC_USER].count)); 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(nctxts); 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_cistatic ssize_t nfreectxts_show(struct device *device, 5558c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 5568c2ecf20Sopenharmony_ci{ 5578c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5588c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5598c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci /* Return the number of free user ports (contexts) available. */ 5628c2ecf20Sopenharmony_ci return scnprintf(buf, PAGE_SIZE, "%u\n", dd->freectxts); 5638c2ecf20Sopenharmony_ci} 5648c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(nfreectxts); 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_cistatic ssize_t serial_show(struct device *device, 5678c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 5688c2ecf20Sopenharmony_ci{ 5698c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5708c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5718c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci return scnprintf(buf, PAGE_SIZE, "%s", dd->serial); 5748c2ecf20Sopenharmony_ci} 5758c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(serial); 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_cistatic ssize_t chip_reset_store(struct device *device, 5788c2ecf20Sopenharmony_ci struct device_attribute *attr, const char *buf, 5798c2ecf20Sopenharmony_ci size_t count) 5808c2ecf20Sopenharmony_ci{ 5818c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 5828c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 5838c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 5848c2ecf20Sopenharmony_ci int ret; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 5878c2ecf20Sopenharmony_ci ret = -EINVAL; 5888c2ecf20Sopenharmony_ci goto bail; 5898c2ecf20Sopenharmony_ci } 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci ret = hfi1_reset_device(dd->unit); 5928c2ecf20Sopenharmony_cibail: 5938c2ecf20Sopenharmony_ci return ret < 0 ? ret : count; 5948c2ecf20Sopenharmony_ci} 5958c2ecf20Sopenharmony_cistatic DEVICE_ATTR_WO(chip_reset); 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci/* 5988c2ecf20Sopenharmony_ci * Convert the reported temperature from an integer (reported in 5998c2ecf20Sopenharmony_ci * units of 0.25C) to a floating point number. 6008c2ecf20Sopenharmony_ci */ 6018c2ecf20Sopenharmony_ci#define temp2str(temp, buf, size, idx) \ 6028c2ecf20Sopenharmony_ci scnprintf((buf) + (idx), (size) - (idx), "%u.%02u ", \ 6038c2ecf20Sopenharmony_ci ((temp) >> 2), ((temp) & 0x3) * 25) 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci/* 6068c2ecf20Sopenharmony_ci * Dump tempsense values, in decimal, to ease shell-scripts. 6078c2ecf20Sopenharmony_ci */ 6088c2ecf20Sopenharmony_cistatic ssize_t tempsense_show(struct device *device, 6098c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 6108c2ecf20Sopenharmony_ci{ 6118c2ecf20Sopenharmony_ci struct hfi1_ibdev *dev = 6128c2ecf20Sopenharmony_ci rdma_device_to_drv_device(device, struct hfi1_ibdev, rdi.ibdev); 6138c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_dev(dev); 6148c2ecf20Sopenharmony_ci struct hfi1_temp temp; 6158c2ecf20Sopenharmony_ci int ret; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci ret = hfi1_tempsense_rd(dd, &temp); 6188c2ecf20Sopenharmony_ci if (!ret) { 6198c2ecf20Sopenharmony_ci int idx = 0; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci idx += temp2str(temp.curr, buf, PAGE_SIZE, idx); 6228c2ecf20Sopenharmony_ci idx += temp2str(temp.lo_lim, buf, PAGE_SIZE, idx); 6238c2ecf20Sopenharmony_ci idx += temp2str(temp.hi_lim, buf, PAGE_SIZE, idx); 6248c2ecf20Sopenharmony_ci idx += temp2str(temp.crit_lim, buf, PAGE_SIZE, idx); 6258c2ecf20Sopenharmony_ci idx += scnprintf(buf + idx, PAGE_SIZE - idx, 6268c2ecf20Sopenharmony_ci "%u %u %u\n", temp.triggers & 0x1, 6278c2ecf20Sopenharmony_ci temp.triggers & 0x2, temp.triggers & 0x4); 6288c2ecf20Sopenharmony_ci ret = idx; 6298c2ecf20Sopenharmony_ci } 6308c2ecf20Sopenharmony_ci return ret; 6318c2ecf20Sopenharmony_ci} 6328c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(tempsense); 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci/* 6358c2ecf20Sopenharmony_ci * end of per-unit (or driver, in some cases, but replicated 6368c2ecf20Sopenharmony_ci * per unit) functions 6378c2ecf20Sopenharmony_ci */ 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci/* start of per-unit file structures and support code */ 6408c2ecf20Sopenharmony_cistatic struct attribute *hfi1_attributes[] = { 6418c2ecf20Sopenharmony_ci &dev_attr_hw_rev.attr, 6428c2ecf20Sopenharmony_ci &dev_attr_board_id.attr, 6438c2ecf20Sopenharmony_ci &dev_attr_nctxts.attr, 6448c2ecf20Sopenharmony_ci &dev_attr_nfreectxts.attr, 6458c2ecf20Sopenharmony_ci &dev_attr_serial.attr, 6468c2ecf20Sopenharmony_ci &dev_attr_boardversion.attr, 6478c2ecf20Sopenharmony_ci &dev_attr_tempsense.attr, 6488c2ecf20Sopenharmony_ci &dev_attr_chip_reset.attr, 6498c2ecf20Sopenharmony_ci NULL, 6508c2ecf20Sopenharmony_ci}; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ciconst struct attribute_group ib_hfi1_attr_group = { 6538c2ecf20Sopenharmony_ci .attrs = hfi1_attributes, 6548c2ecf20Sopenharmony_ci}; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ciint hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, 6578c2ecf20Sopenharmony_ci struct kobject *kobj) 6588c2ecf20Sopenharmony_ci{ 6598c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd; 6608c2ecf20Sopenharmony_ci struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 6618c2ecf20Sopenharmony_ci int ret; 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci if (!port_num || port_num > dd->num_pports) { 6648c2ecf20Sopenharmony_ci dd_dev_err(dd, 6658c2ecf20Sopenharmony_ci "Skipping infiniband class with invalid port %u\n", 6668c2ecf20Sopenharmony_ci port_num); 6678c2ecf20Sopenharmony_ci return -ENODEV; 6688c2ecf20Sopenharmony_ci } 6698c2ecf20Sopenharmony_ci ppd = &dd->pport[port_num - 1]; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj, 6728c2ecf20Sopenharmony_ci "sc2vl"); 6738c2ecf20Sopenharmony_ci if (ret) { 6748c2ecf20Sopenharmony_ci dd_dev_err(dd, 6758c2ecf20Sopenharmony_ci "Skipping sc2vl sysfs info, (err %d) port %u\n", 6768c2ecf20Sopenharmony_ci ret, port_num); 6778c2ecf20Sopenharmony_ci /* 6788c2ecf20Sopenharmony_ci * Based on the documentation for kobject_init_and_add(), the 6798c2ecf20Sopenharmony_ci * caller should call kobject_put even if this call fails. 6808c2ecf20Sopenharmony_ci */ 6818c2ecf20Sopenharmony_ci goto bail_sc2vl; 6828c2ecf20Sopenharmony_ci } 6838c2ecf20Sopenharmony_ci kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj, 6868c2ecf20Sopenharmony_ci "sl2sc"); 6878c2ecf20Sopenharmony_ci if (ret) { 6888c2ecf20Sopenharmony_ci dd_dev_err(dd, 6898c2ecf20Sopenharmony_ci "Skipping sl2sc sysfs info, (err %d) port %u\n", 6908c2ecf20Sopenharmony_ci ret, port_num); 6918c2ecf20Sopenharmony_ci goto bail_sl2sc; 6928c2ecf20Sopenharmony_ci } 6938c2ecf20Sopenharmony_ci kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj, 6968c2ecf20Sopenharmony_ci "vl2mtu"); 6978c2ecf20Sopenharmony_ci if (ret) { 6988c2ecf20Sopenharmony_ci dd_dev_err(dd, 6998c2ecf20Sopenharmony_ci "Skipping vl2mtu sysfs info, (err %d) port %u\n", 7008c2ecf20Sopenharmony_ci ret, port_num); 7018c2ecf20Sopenharmony_ci goto bail_vl2mtu; 7028c2ecf20Sopenharmony_ci } 7038c2ecf20Sopenharmony_ci kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype, 7068c2ecf20Sopenharmony_ci kobj, "CCMgtA"); 7078c2ecf20Sopenharmony_ci if (ret) { 7088c2ecf20Sopenharmony_ci dd_dev_err(dd, 7098c2ecf20Sopenharmony_ci "Skipping Congestion Control sysfs info, (err %d) port %u\n", 7108c2ecf20Sopenharmony_ci ret, port_num); 7118c2ecf20Sopenharmony_ci goto bail_cc; 7128c2ecf20Sopenharmony_ci } 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); 7178c2ecf20Sopenharmony_ci if (ret) { 7188c2ecf20Sopenharmony_ci dd_dev_err(dd, 7198c2ecf20Sopenharmony_ci "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", 7208c2ecf20Sopenharmony_ci ret, port_num); 7218c2ecf20Sopenharmony_ci goto bail_cc; 7228c2ecf20Sopenharmony_ci } 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr); 7258c2ecf20Sopenharmony_ci if (ret) { 7268c2ecf20Sopenharmony_ci dd_dev_err(dd, 7278c2ecf20Sopenharmony_ci "Skipping Congestion Control table sysfs info, (err %d) port %u\n", 7288c2ecf20Sopenharmony_ci ret, port_num); 7298c2ecf20Sopenharmony_ci goto bail_cc_entry_bin; 7308c2ecf20Sopenharmony_ci } 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci dd_dev_info(dd, 7338c2ecf20Sopenharmony_ci "Congestion Control Agent enabled for port %d\n", 7348c2ecf20Sopenharmony_ci port_num); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci return 0; 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_cibail_cc_entry_bin: 7398c2ecf20Sopenharmony_ci sysfs_remove_bin_file(&ppd->pport_cc_kobj, 7408c2ecf20Sopenharmony_ci &cc_setting_bin_attr); 7418c2ecf20Sopenharmony_cibail_cc: 7428c2ecf20Sopenharmony_ci kobject_put(&ppd->pport_cc_kobj); 7438c2ecf20Sopenharmony_cibail_vl2mtu: 7448c2ecf20Sopenharmony_ci kobject_put(&ppd->vl2mtu_kobj); 7458c2ecf20Sopenharmony_cibail_sl2sc: 7468c2ecf20Sopenharmony_ci kobject_put(&ppd->sl2sc_kobj); 7478c2ecf20Sopenharmony_cibail_sc2vl: 7488c2ecf20Sopenharmony_ci kobject_put(&ppd->sc2vl_kobj); 7498c2ecf20Sopenharmony_ci return ret; 7508c2ecf20Sopenharmony_ci} 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistruct sde_attribute { 7538c2ecf20Sopenharmony_ci struct attribute attr; 7548c2ecf20Sopenharmony_ci ssize_t (*show)(struct sdma_engine *sde, char *buf); 7558c2ecf20Sopenharmony_ci ssize_t (*store)(struct sdma_engine *sde, const char *buf, size_t cnt); 7568c2ecf20Sopenharmony_ci}; 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_cistatic ssize_t sde_show(struct kobject *kobj, struct attribute *attr, char *buf) 7598c2ecf20Sopenharmony_ci{ 7608c2ecf20Sopenharmony_ci struct sde_attribute *sde_attr = 7618c2ecf20Sopenharmony_ci container_of(attr, struct sde_attribute, attr); 7628c2ecf20Sopenharmony_ci struct sdma_engine *sde = 7638c2ecf20Sopenharmony_ci container_of(kobj, struct sdma_engine, kobj); 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci if (!sde_attr->show) 7668c2ecf20Sopenharmony_ci return -EINVAL; 7678c2ecf20Sopenharmony_ci 7688c2ecf20Sopenharmony_ci return sde_attr->show(sde, buf); 7698c2ecf20Sopenharmony_ci} 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_cistatic ssize_t sde_store(struct kobject *kobj, struct attribute *attr, 7728c2ecf20Sopenharmony_ci const char *buf, size_t count) 7738c2ecf20Sopenharmony_ci{ 7748c2ecf20Sopenharmony_ci struct sde_attribute *sde_attr = 7758c2ecf20Sopenharmony_ci container_of(attr, struct sde_attribute, attr); 7768c2ecf20Sopenharmony_ci struct sdma_engine *sde = 7778c2ecf20Sopenharmony_ci container_of(kobj, struct sdma_engine, kobj); 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci if (!capable(CAP_SYS_ADMIN)) 7808c2ecf20Sopenharmony_ci return -EPERM; 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci if (!sde_attr->store) 7838c2ecf20Sopenharmony_ci return -EINVAL; 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci return sde_attr->store(sde, buf, count); 7868c2ecf20Sopenharmony_ci} 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_cistatic const struct sysfs_ops sde_sysfs_ops = { 7898c2ecf20Sopenharmony_ci .show = sde_show, 7908c2ecf20Sopenharmony_ci .store = sde_store, 7918c2ecf20Sopenharmony_ci}; 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_cistatic struct kobj_type sde_ktype = { 7948c2ecf20Sopenharmony_ci .sysfs_ops = &sde_sysfs_ops, 7958c2ecf20Sopenharmony_ci}; 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci#define SDE_ATTR(_name, _mode, _show, _store) \ 7988c2ecf20Sopenharmony_ci struct sde_attribute sde_attr_##_name = \ 7998c2ecf20Sopenharmony_ci __ATTR(_name, _mode, _show, _store) 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_cistatic ssize_t sde_show_cpu_to_sde_map(struct sdma_engine *sde, char *buf) 8028c2ecf20Sopenharmony_ci{ 8038c2ecf20Sopenharmony_ci return sdma_get_cpu_to_sde_map(sde, buf); 8048c2ecf20Sopenharmony_ci} 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_cistatic ssize_t sde_store_cpu_to_sde_map(struct sdma_engine *sde, 8078c2ecf20Sopenharmony_ci const char *buf, size_t count) 8088c2ecf20Sopenharmony_ci{ 8098c2ecf20Sopenharmony_ci return sdma_set_cpu_to_sde_map(sde, buf, count); 8108c2ecf20Sopenharmony_ci} 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_cistatic ssize_t sde_show_vl(struct sdma_engine *sde, char *buf) 8138c2ecf20Sopenharmony_ci{ 8148c2ecf20Sopenharmony_ci int vl; 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci vl = sdma_engine_get_vl(sde); 8178c2ecf20Sopenharmony_ci if (vl < 0) 8188c2ecf20Sopenharmony_ci return vl; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%d\n", vl); 8218c2ecf20Sopenharmony_ci} 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_cistatic SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO, 8248c2ecf20Sopenharmony_ci sde_show_cpu_to_sde_map, 8258c2ecf20Sopenharmony_ci sde_store_cpu_to_sde_map); 8268c2ecf20Sopenharmony_cistatic SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL); 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_cistatic struct sde_attribute *sde_attribs[] = { 8298c2ecf20Sopenharmony_ci &sde_attr_cpu_list, 8308c2ecf20Sopenharmony_ci &sde_attr_vl 8318c2ecf20Sopenharmony_ci}; 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci/* 8348c2ecf20Sopenharmony_ci * Register and create our files in /sys/class/infiniband. 8358c2ecf20Sopenharmony_ci */ 8368c2ecf20Sopenharmony_ciint hfi1_verbs_register_sysfs(struct hfi1_devdata *dd) 8378c2ecf20Sopenharmony_ci{ 8388c2ecf20Sopenharmony_ci struct ib_device *dev = &dd->verbs_dev.rdi.ibdev; 8398c2ecf20Sopenharmony_ci struct device *class_dev = &dev->dev; 8408c2ecf20Sopenharmony_ci int i, j, ret; 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci for (i = 0; i < dd->num_sdma; i++) { 8438c2ecf20Sopenharmony_ci ret = kobject_init_and_add(&dd->per_sdma[i].kobj, 8448c2ecf20Sopenharmony_ci &sde_ktype, &class_dev->kobj, 8458c2ecf20Sopenharmony_ci "sdma%d", i); 8468c2ecf20Sopenharmony_ci if (ret) 8478c2ecf20Sopenharmony_ci goto bail; 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci for (j = 0; j < ARRAY_SIZE(sde_attribs); j++) { 8508c2ecf20Sopenharmony_ci ret = sysfs_create_file(&dd->per_sdma[i].kobj, 8518c2ecf20Sopenharmony_ci &sde_attribs[j]->attr); 8528c2ecf20Sopenharmony_ci if (ret) 8538c2ecf20Sopenharmony_ci goto bail; 8548c2ecf20Sopenharmony_ci } 8558c2ecf20Sopenharmony_ci } 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci return 0; 8588c2ecf20Sopenharmony_cibail: 8598c2ecf20Sopenharmony_ci /* 8608c2ecf20Sopenharmony_ci * The function kobject_put() will call kobject_del() if the kobject 8618c2ecf20Sopenharmony_ci * has been added successfully. The sysfs files created under the 8628c2ecf20Sopenharmony_ci * kobject directory will also be removed during the process. 8638c2ecf20Sopenharmony_ci */ 8648c2ecf20Sopenharmony_ci for (; i >= 0; i--) 8658c2ecf20Sopenharmony_ci kobject_put(&dd->per_sdma[i].kobj); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci return ret; 8688c2ecf20Sopenharmony_ci} 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci/* 8718c2ecf20Sopenharmony_ci * Unregister and remove our files in /sys/class/infiniband. 8728c2ecf20Sopenharmony_ci */ 8738c2ecf20Sopenharmony_civoid hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd) 8748c2ecf20Sopenharmony_ci{ 8758c2ecf20Sopenharmony_ci struct hfi1_pportdata *ppd; 8768c2ecf20Sopenharmony_ci int i; 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci /* Unwind operations in hfi1_verbs_register_sysfs() */ 8798c2ecf20Sopenharmony_ci for (i = 0; i < dd->num_sdma; i++) 8808c2ecf20Sopenharmony_ci kobject_put(&dd->per_sdma[i].kobj); 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ci for (i = 0; i < dd->num_pports; i++) { 8838c2ecf20Sopenharmony_ci ppd = &dd->pport[i]; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci sysfs_remove_bin_file(&ppd->pport_cc_kobj, 8868c2ecf20Sopenharmony_ci &cc_setting_bin_attr); 8878c2ecf20Sopenharmony_ci sysfs_remove_bin_file(&ppd->pport_cc_kobj, 8888c2ecf20Sopenharmony_ci &cc_table_bin_attr); 8898c2ecf20Sopenharmony_ci kobject_put(&ppd->pport_cc_kobj); 8908c2ecf20Sopenharmony_ci kobject_put(&ppd->vl2mtu_kobj); 8918c2ecf20Sopenharmony_ci kobject_put(&ppd->sl2sc_kobj); 8928c2ecf20Sopenharmony_ci kobject_put(&ppd->sc2vl_kobj); 8938c2ecf20Sopenharmony_ci } 8948c2ecf20Sopenharmony_ci} 895