1f931551bSRalph Campbell /* 236a8f01cSMike Marciniszyn * Copyright (c) 2012 Intel Corporation. All rights reserved. 336a8f01cSMike Marciniszyn * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. 4f931551bSRalph Campbell * Copyright (c) 2006 PathScale, Inc. All rights reserved. 5f931551bSRalph Campbell * 6f931551bSRalph Campbell * This software is available to you under a choice of one of two 7f931551bSRalph Campbell * licenses. You may choose to be licensed under the terms of the GNU 8f931551bSRalph Campbell * General Public License (GPL) Version 2, available from the file 9f931551bSRalph Campbell * COPYING in the main directory of this source tree, or the 10f931551bSRalph Campbell * OpenIB.org BSD license below: 11f931551bSRalph Campbell * 12f931551bSRalph Campbell * Redistribution and use in source and binary forms, with or 13f931551bSRalph Campbell * without modification, are permitted provided that the following 14f931551bSRalph Campbell * conditions are met: 15f931551bSRalph Campbell * 16f931551bSRalph Campbell * - Redistributions of source code must retain the above 17f931551bSRalph Campbell * copyright notice, this list of conditions and the following 18f931551bSRalph Campbell * disclaimer. 19f931551bSRalph Campbell * 20f931551bSRalph Campbell * - Redistributions in binary form must reproduce the above 21f931551bSRalph Campbell * copyright notice, this list of conditions and the following 22f931551bSRalph Campbell * disclaimer in the documentation and/or other materials 23f931551bSRalph Campbell * provided with the distribution. 24f931551bSRalph Campbell * 25f931551bSRalph Campbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26f931551bSRalph Campbell * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27f931551bSRalph Campbell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28f931551bSRalph Campbell * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29f931551bSRalph Campbell * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30f931551bSRalph Campbell * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31f931551bSRalph Campbell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32f931551bSRalph Campbell * SOFTWARE. 33f931551bSRalph Campbell */ 34f931551bSRalph Campbell #include <linux/ctype.h> 35f931551bSRalph Campbell 36f931551bSRalph Campbell #include "qib.h" 3736a8f01cSMike Marciniszyn #include "qib_mad.h" 38f931551bSRalph Campbell 39f931551bSRalph Campbell /* start of per-port functions */ 40f931551bSRalph Campbell /* 41f931551bSRalph Campbell * Get/Set heartbeat enable. OR of 1=enabled, 2=auto 42f931551bSRalph Campbell */ 43f931551bSRalph Campbell static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf) 44f931551bSRalph Campbell { 45f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 46f931551bSRalph Campbell 47*e28bf1f0SJoe Perches return sysfs_emit(buf, "%d\n", dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT)); 48f931551bSRalph Campbell } 49f931551bSRalph Campbell 50f931551bSRalph Campbell static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf, 51f931551bSRalph Campbell size_t count) 52f931551bSRalph Campbell { 53f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 54f931551bSRalph Campbell int ret; 55f931551bSRalph Campbell u16 val; 56f931551bSRalph Campbell 577fac3301SMike Marciniszyn ret = kstrtou16(buf, 0, &val); 587fac3301SMike Marciniszyn if (ret) { 597fac3301SMike Marciniszyn qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); 607fac3301SMike Marciniszyn return ret; 617fac3301SMike Marciniszyn } 62f931551bSRalph Campbell 63f931551bSRalph Campbell /* 64f931551bSRalph Campbell * Set the "intentional" heartbeat enable per either of 65f931551bSRalph Campbell * "Enable" and "Auto", as these are normally set together. 66f931551bSRalph Campbell * This bit is consulted when leaving loopback mode, 67f931551bSRalph Campbell * because entering loopback mode overrides it and automatically 68f931551bSRalph Campbell * disables heartbeat. 69f931551bSRalph Campbell */ 70f931551bSRalph Campbell ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val); 71f931551bSRalph Campbell return ret < 0 ? ret : count; 72f931551bSRalph Campbell } 73f931551bSRalph Campbell 74f931551bSRalph Campbell static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf, 75f931551bSRalph Campbell size_t count) 76f931551bSRalph Campbell { 77f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 78f931551bSRalph Campbell int ret = count, r; 79f931551bSRalph Campbell 80f931551bSRalph Campbell r = dd->f_set_ib_loopback(ppd, buf); 81f931551bSRalph Campbell if (r < 0) 82f931551bSRalph Campbell ret = r; 83f931551bSRalph Campbell 84f931551bSRalph Campbell return ret; 85f931551bSRalph Campbell } 86f931551bSRalph Campbell 87f931551bSRalph Campbell static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf, 88f931551bSRalph Campbell size_t count) 89f931551bSRalph Campbell { 90f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 91f931551bSRalph Campbell int ret; 92f931551bSRalph Campbell u16 val; 93f931551bSRalph Campbell 947fac3301SMike Marciniszyn ret = kstrtou16(buf, 0, &val); 957fac3301SMike Marciniszyn if (ret) { 96f931551bSRalph Campbell qib_dev_err(dd, "attempt to set invalid LED override\n"); 977fac3301SMike Marciniszyn return ret; 987fac3301SMike Marciniszyn } 997fac3301SMike Marciniszyn 1007fac3301SMike Marciniszyn qib_set_led_override(ppd, val); 1017fac3301SMike Marciniszyn return count; 102f931551bSRalph Campbell } 103f931551bSRalph Campbell 104f931551bSRalph Campbell static ssize_t show_status(struct qib_pportdata *ppd, char *buf) 105f931551bSRalph Campbell { 106f931551bSRalph Campbell if (!ppd->statusp) 107*e28bf1f0SJoe Perches return -EINVAL; 108*e28bf1f0SJoe Perches 109*e28bf1f0SJoe Perches return sysfs_emit(buf, "0x%llx\n", (unsigned long long)*(ppd->statusp)); 110f931551bSRalph Campbell } 111f931551bSRalph Campbell 112f931551bSRalph Campbell /* 113f931551bSRalph Campbell * For userland compatibility, these offsets must remain fixed. 114f931551bSRalph Campbell * They are strings for QIB_STATUS_* 115f931551bSRalph Campbell */ 116865b64beSMike Marciniszyn static const char * const qib_status_str[] = { 117f931551bSRalph Campbell "Initted", 118f931551bSRalph Campbell "", 119f931551bSRalph Campbell "", 120f931551bSRalph Campbell "", 121f931551bSRalph Campbell "", 122f931551bSRalph Campbell "Present", 123f931551bSRalph Campbell "IB_link_up", 124f931551bSRalph Campbell "IB_configured", 125f931551bSRalph Campbell "", 126f931551bSRalph Campbell "Fatal_Hardware_Error", 127f931551bSRalph Campbell NULL, 128f931551bSRalph Campbell }; 129f931551bSRalph Campbell 130f931551bSRalph Campbell static ssize_t show_status_str(struct qib_pportdata *ppd, char *buf) 131f931551bSRalph Campbell { 132f931551bSRalph Campbell int i, any; 133f931551bSRalph Campbell u64 s; 134f931551bSRalph Campbell ssize_t ret; 135f931551bSRalph Campbell 136f931551bSRalph Campbell if (!ppd->statusp) { 137f931551bSRalph Campbell ret = -EINVAL; 138f931551bSRalph Campbell goto bail; 139f931551bSRalph Campbell } 140f931551bSRalph Campbell 141f931551bSRalph Campbell s = *(ppd->statusp); 142f931551bSRalph Campbell *buf = '\0'; 143f931551bSRalph Campbell for (any = i = 0; s && qib_status_str[i]; i++) { 144f931551bSRalph Campbell if (s & 1) { 145f931551bSRalph Campbell /* if overflow */ 146f931551bSRalph Campbell if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) 147f931551bSRalph Campbell break; 148f931551bSRalph Campbell if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >= 149f931551bSRalph Campbell PAGE_SIZE) 150f931551bSRalph Campbell break; 151f931551bSRalph Campbell any = 1; 152f931551bSRalph Campbell } 153f931551bSRalph Campbell s >>= 1; 154f931551bSRalph Campbell } 155f931551bSRalph Campbell if (any) 156f931551bSRalph Campbell strlcat(buf, "\n", PAGE_SIZE); 157f931551bSRalph Campbell 158f931551bSRalph Campbell ret = strlen(buf); 159f931551bSRalph Campbell 160f931551bSRalph Campbell bail: 161f931551bSRalph Campbell return ret; 162f931551bSRalph Campbell } 163f931551bSRalph Campbell 164f931551bSRalph Campbell /* end of per-port functions */ 165f931551bSRalph Campbell 166f931551bSRalph Campbell /* 167f931551bSRalph Campbell * Start of per-port file structures and support code 168f931551bSRalph Campbell * Because we are fitting into other infrastructure, we have to supply the 169f931551bSRalph Campbell * full set of kobject/sysfs_ops structures and routines. 170f931551bSRalph Campbell */ 171f931551bSRalph Campbell #define QIB_PORT_ATTR(name, mode, show, store) \ 172f931551bSRalph Campbell static struct qib_port_attr qib_port_attr_##name = \ 173f931551bSRalph Campbell __ATTR(name, mode, show, store) 174f931551bSRalph Campbell 175f931551bSRalph Campbell struct qib_port_attr { 176f931551bSRalph Campbell struct attribute attr; 177f931551bSRalph Campbell ssize_t (*show)(struct qib_pportdata *, char *); 178f931551bSRalph Campbell ssize_t (*store)(struct qib_pportdata *, const char *, size_t); 179f931551bSRalph Campbell }; 180f931551bSRalph Campbell 181f931551bSRalph Campbell QIB_PORT_ATTR(loopback, S_IWUSR, NULL, store_loopback); 182f931551bSRalph Campbell QIB_PORT_ATTR(led_override, S_IWUSR, NULL, store_led_override); 183f931551bSRalph Campbell QIB_PORT_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, 184f931551bSRalph Campbell store_hrtbt_enb); 185f931551bSRalph Campbell QIB_PORT_ATTR(status, S_IRUGO, show_status, NULL); 186f931551bSRalph Campbell QIB_PORT_ATTR(status_str, S_IRUGO, show_status_str, NULL); 187f931551bSRalph Campbell 188f931551bSRalph Campbell static struct attribute *port_default_attributes[] = { 189f931551bSRalph Campbell &qib_port_attr_loopback.attr, 190f931551bSRalph Campbell &qib_port_attr_led_override.attr, 191f931551bSRalph Campbell &qib_port_attr_hrtbt_enable.attr, 192f931551bSRalph Campbell &qib_port_attr_status.attr, 193f931551bSRalph Campbell &qib_port_attr_status_str.attr, 194f931551bSRalph Campbell NULL 195f931551bSRalph Campbell }; 196f931551bSRalph Campbell 19736a8f01cSMike Marciniszyn /* 19836a8f01cSMike Marciniszyn * Start of per-port congestion control structures and support code 19936a8f01cSMike Marciniszyn */ 20036a8f01cSMike Marciniszyn 20136a8f01cSMike Marciniszyn /* 20236a8f01cSMike Marciniszyn * Congestion control table size followed by table entries 20336a8f01cSMike Marciniszyn */ 20436a8f01cSMike Marciniszyn static ssize_t read_cc_table_bin(struct file *filp, struct kobject *kobj, 20536a8f01cSMike Marciniszyn struct bin_attribute *bin_attr, 20636a8f01cSMike Marciniszyn char *buf, loff_t pos, size_t count) 20736a8f01cSMike Marciniszyn { 20836a8f01cSMike Marciniszyn int ret; 20936a8f01cSMike Marciniszyn struct qib_pportdata *ppd = 21036a8f01cSMike Marciniszyn container_of(kobj, struct qib_pportdata, pport_cc_kobj); 21136a8f01cSMike Marciniszyn 21236a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->ccti_entries_shadow) 21336a8f01cSMike Marciniszyn return -EINVAL; 21436a8f01cSMike Marciniszyn 21536a8f01cSMike Marciniszyn ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow) 21636a8f01cSMike Marciniszyn + sizeof(__be16); 21736a8f01cSMike Marciniszyn 21836a8f01cSMike Marciniszyn if (pos > ret) 21936a8f01cSMike Marciniszyn return -EINVAL; 22036a8f01cSMike Marciniszyn 22136a8f01cSMike Marciniszyn if (count > ret - pos) 22236a8f01cSMike Marciniszyn count = ret - pos; 22336a8f01cSMike Marciniszyn 22436a8f01cSMike Marciniszyn if (!count) 22536a8f01cSMike Marciniszyn return count; 22636a8f01cSMike Marciniszyn 22736a8f01cSMike Marciniszyn spin_lock(&ppd->cc_shadow_lock); 22836a8f01cSMike Marciniszyn memcpy(buf, ppd->ccti_entries_shadow, count); 22936a8f01cSMike Marciniszyn spin_unlock(&ppd->cc_shadow_lock); 23036a8f01cSMike Marciniszyn 23136a8f01cSMike Marciniszyn return count; 23236a8f01cSMike Marciniszyn } 23336a8f01cSMike Marciniszyn 23436a8f01cSMike Marciniszyn static void qib_port_release(struct kobject *kobj) 23536a8f01cSMike Marciniszyn { 23636a8f01cSMike Marciniszyn /* nothing to do since memory is freed by qib_free_devdata() */ 23736a8f01cSMike Marciniszyn } 23836a8f01cSMike Marciniszyn 23936a8f01cSMike Marciniszyn static struct kobj_type qib_port_cc_ktype = { 24036a8f01cSMike Marciniszyn .release = qib_port_release, 24136a8f01cSMike Marciniszyn }; 24236a8f01cSMike Marciniszyn 243238f43a7SBhumika Goyal static const struct bin_attribute cc_table_bin_attr = { 24436a8f01cSMike Marciniszyn .attr = {.name = "cc_table_bin", .mode = 0444}, 24536a8f01cSMike Marciniszyn .read = read_cc_table_bin, 24636a8f01cSMike Marciniszyn .size = PAGE_SIZE, 24736a8f01cSMike Marciniszyn }; 24836a8f01cSMike Marciniszyn 24936a8f01cSMike Marciniszyn /* 25036a8f01cSMike Marciniszyn * Congestion settings: port control, control map and an array of 16 25136a8f01cSMike Marciniszyn * entries for the congestion entries - increase, timer, event log 25236a8f01cSMike Marciniszyn * trigger threshold and the minimum injection rate delay. 25336a8f01cSMike Marciniszyn */ 25436a8f01cSMike Marciniszyn static ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj, 25536a8f01cSMike Marciniszyn struct bin_attribute *bin_attr, 25636a8f01cSMike Marciniszyn char *buf, loff_t pos, size_t count) 25736a8f01cSMike Marciniszyn { 25836a8f01cSMike Marciniszyn int ret; 25936a8f01cSMike Marciniszyn struct qib_pportdata *ppd = 26036a8f01cSMike Marciniszyn container_of(kobj, struct qib_pportdata, pport_cc_kobj); 26136a8f01cSMike Marciniszyn 26236a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->congestion_entries_shadow) 26336a8f01cSMike Marciniszyn return -EINVAL; 26436a8f01cSMike Marciniszyn 26536a8f01cSMike Marciniszyn ret = sizeof(struct ib_cc_congestion_setting_attr_shadow); 26636a8f01cSMike Marciniszyn 26736a8f01cSMike Marciniszyn if (pos > ret) 26836a8f01cSMike Marciniszyn return -EINVAL; 26936a8f01cSMike Marciniszyn if (count > ret - pos) 27036a8f01cSMike Marciniszyn count = ret - pos; 27136a8f01cSMike Marciniszyn 27236a8f01cSMike Marciniszyn if (!count) 27336a8f01cSMike Marciniszyn return count; 27436a8f01cSMike Marciniszyn 27536a8f01cSMike Marciniszyn spin_lock(&ppd->cc_shadow_lock); 27636a8f01cSMike Marciniszyn memcpy(buf, ppd->congestion_entries_shadow, count); 27736a8f01cSMike Marciniszyn spin_unlock(&ppd->cc_shadow_lock); 27836a8f01cSMike Marciniszyn 27936a8f01cSMike Marciniszyn return count; 28036a8f01cSMike Marciniszyn } 28136a8f01cSMike Marciniszyn 282238f43a7SBhumika Goyal static const struct bin_attribute cc_setting_bin_attr = { 28336a8f01cSMike Marciniszyn .attr = {.name = "cc_settings_bin", .mode = 0444}, 28436a8f01cSMike Marciniszyn .read = read_cc_setting_bin, 28536a8f01cSMike Marciniszyn .size = PAGE_SIZE, 28636a8f01cSMike Marciniszyn }; 28736a8f01cSMike Marciniszyn 28836a8f01cSMike Marciniszyn 289f931551bSRalph Campbell static ssize_t qib_portattr_show(struct kobject *kobj, 290f931551bSRalph Campbell struct attribute *attr, char *buf) 291f931551bSRalph Campbell { 292f931551bSRalph Campbell struct qib_port_attr *pattr = 293f931551bSRalph Campbell container_of(attr, struct qib_port_attr, attr); 294f931551bSRalph Campbell struct qib_pportdata *ppd = 295f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, pport_kobj); 296f931551bSRalph Campbell 2977ee23491SViresh Kumar if (!pattr->show) 2987ee23491SViresh Kumar return -EIO; 2997ee23491SViresh Kumar 300f931551bSRalph Campbell return pattr->show(ppd, buf); 301f931551bSRalph Campbell } 302f931551bSRalph Campbell 303f931551bSRalph Campbell static ssize_t qib_portattr_store(struct kobject *kobj, 304f931551bSRalph Campbell struct attribute *attr, const char *buf, size_t len) 305f931551bSRalph Campbell { 306f931551bSRalph Campbell struct qib_port_attr *pattr = 307f931551bSRalph Campbell container_of(attr, struct qib_port_attr, attr); 308f931551bSRalph Campbell struct qib_pportdata *ppd = 309f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, pport_kobj); 310f931551bSRalph Campbell 3117ee23491SViresh Kumar if (!pattr->store) 3127ee23491SViresh Kumar return -EIO; 3137ee23491SViresh Kumar 314f931551bSRalph Campbell return pattr->store(ppd, buf, len); 315f931551bSRalph Campbell } 316f931551bSRalph Campbell 317f931551bSRalph Campbell 318f931551bSRalph Campbell static const struct sysfs_ops qib_port_ops = { 319f931551bSRalph Campbell .show = qib_portattr_show, 320f931551bSRalph Campbell .store = qib_portattr_store, 321f931551bSRalph Campbell }; 322f931551bSRalph Campbell 323f931551bSRalph Campbell static struct kobj_type qib_port_ktype = { 324f931551bSRalph Campbell .release = qib_port_release, 325f931551bSRalph Campbell .sysfs_ops = &qib_port_ops, 326f931551bSRalph Campbell .default_attrs = port_default_attributes 327f931551bSRalph Campbell }; 328f931551bSRalph Campbell 329f931551bSRalph Campbell /* Start sl2vl */ 330f931551bSRalph Campbell 331f931551bSRalph Campbell #define QIB_SL2VL_ATTR(N) \ 332f931551bSRalph Campbell static struct qib_sl2vl_attr qib_sl2vl_attr_##N = { \ 333f931551bSRalph Campbell .attr = { .name = __stringify(N), .mode = 0444 }, \ 334f931551bSRalph Campbell .sl = N \ 335f931551bSRalph Campbell } 336f931551bSRalph Campbell 337f931551bSRalph Campbell struct qib_sl2vl_attr { 338f931551bSRalph Campbell struct attribute attr; 339f931551bSRalph Campbell int sl; 340f931551bSRalph Campbell }; 341f931551bSRalph Campbell 342f931551bSRalph Campbell QIB_SL2VL_ATTR(0); 343f931551bSRalph Campbell QIB_SL2VL_ATTR(1); 344f931551bSRalph Campbell QIB_SL2VL_ATTR(2); 345f931551bSRalph Campbell QIB_SL2VL_ATTR(3); 346f931551bSRalph Campbell QIB_SL2VL_ATTR(4); 347f931551bSRalph Campbell QIB_SL2VL_ATTR(5); 348f931551bSRalph Campbell QIB_SL2VL_ATTR(6); 349f931551bSRalph Campbell QIB_SL2VL_ATTR(7); 350f931551bSRalph Campbell QIB_SL2VL_ATTR(8); 351f931551bSRalph Campbell QIB_SL2VL_ATTR(9); 352f931551bSRalph Campbell QIB_SL2VL_ATTR(10); 353f931551bSRalph Campbell QIB_SL2VL_ATTR(11); 354f931551bSRalph Campbell QIB_SL2VL_ATTR(12); 355f931551bSRalph Campbell QIB_SL2VL_ATTR(13); 356f931551bSRalph Campbell QIB_SL2VL_ATTR(14); 357f931551bSRalph Campbell QIB_SL2VL_ATTR(15); 358f931551bSRalph Campbell 359f931551bSRalph Campbell static struct attribute *sl2vl_default_attributes[] = { 360f931551bSRalph Campbell &qib_sl2vl_attr_0.attr, 361f931551bSRalph Campbell &qib_sl2vl_attr_1.attr, 362f931551bSRalph Campbell &qib_sl2vl_attr_2.attr, 363f931551bSRalph Campbell &qib_sl2vl_attr_3.attr, 364f931551bSRalph Campbell &qib_sl2vl_attr_4.attr, 365f931551bSRalph Campbell &qib_sl2vl_attr_5.attr, 366f931551bSRalph Campbell &qib_sl2vl_attr_6.attr, 367f931551bSRalph Campbell &qib_sl2vl_attr_7.attr, 368f931551bSRalph Campbell &qib_sl2vl_attr_8.attr, 369f931551bSRalph Campbell &qib_sl2vl_attr_9.attr, 370f931551bSRalph Campbell &qib_sl2vl_attr_10.attr, 371f931551bSRalph Campbell &qib_sl2vl_attr_11.attr, 372f931551bSRalph Campbell &qib_sl2vl_attr_12.attr, 373f931551bSRalph Campbell &qib_sl2vl_attr_13.attr, 374f931551bSRalph Campbell &qib_sl2vl_attr_14.attr, 375f931551bSRalph Campbell &qib_sl2vl_attr_15.attr, 376f931551bSRalph Campbell NULL 377f931551bSRalph Campbell }; 378f931551bSRalph Campbell 379f931551bSRalph Campbell static ssize_t sl2vl_attr_show(struct kobject *kobj, struct attribute *attr, 380f931551bSRalph Campbell char *buf) 381f931551bSRalph Campbell { 382f931551bSRalph Campbell struct qib_sl2vl_attr *sattr = 383f931551bSRalph Campbell container_of(attr, struct qib_sl2vl_attr, attr); 384f931551bSRalph Campbell struct qib_pportdata *ppd = 385f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, sl2vl_kobj); 386f931551bSRalph Campbell struct qib_ibport *qibp = &ppd->ibport_data; 387f931551bSRalph Campbell 388*e28bf1f0SJoe Perches return sysfs_emit(buf, "%u\n", qibp->sl_to_vl[sattr->sl]); 389f931551bSRalph Campbell } 390f931551bSRalph Campbell 391f931551bSRalph Campbell static const struct sysfs_ops qib_sl2vl_ops = { 392f931551bSRalph Campbell .show = sl2vl_attr_show, 393f931551bSRalph Campbell }; 394f931551bSRalph Campbell 395f931551bSRalph Campbell static struct kobj_type qib_sl2vl_ktype = { 396f931551bSRalph Campbell .release = qib_port_release, 397f931551bSRalph Campbell .sysfs_ops = &qib_sl2vl_ops, 398f931551bSRalph Campbell .default_attrs = sl2vl_default_attributes 399f931551bSRalph Campbell }; 400f931551bSRalph Campbell 401f931551bSRalph Campbell /* End sl2vl */ 402f931551bSRalph Campbell 403f931551bSRalph Campbell /* Start diag_counters */ 404f931551bSRalph Campbell 405f931551bSRalph Campbell #define QIB_DIAGC_ATTR(N) \ 406f931551bSRalph Campbell static struct qib_diagc_attr qib_diagc_attr_##N = { \ 4074c6931f5SIra Weiny .attr = { .name = __stringify(N), .mode = 0664 }, \ 408f24a6d48SHarish Chegondi .counter = offsetof(struct qib_ibport, rvp.n_##N) \ 409f24a6d48SHarish Chegondi } 410f24a6d48SHarish Chegondi 411f24a6d48SHarish Chegondi #define QIB_DIAGC_ATTR_PER_CPU(N) \ 412f24a6d48SHarish Chegondi static struct qib_diagc_attr qib_diagc_attr_##N = { \ 413f24a6d48SHarish Chegondi .attr = { .name = __stringify(N), .mode = 0664 }, \ 414f24a6d48SHarish Chegondi .counter = offsetof(struct qib_ibport, rvp.z_##N) \ 415f931551bSRalph Campbell } 416f931551bSRalph Campbell 417f931551bSRalph Campbell struct qib_diagc_attr { 418f931551bSRalph Campbell struct attribute attr; 419f931551bSRalph Campbell size_t counter; 420f931551bSRalph Campbell }; 421f931551bSRalph Campbell 422f24a6d48SHarish Chegondi QIB_DIAGC_ATTR_PER_CPU(rc_acks); 423f24a6d48SHarish Chegondi QIB_DIAGC_ATTR_PER_CPU(rc_qacks); 424f24a6d48SHarish Chegondi QIB_DIAGC_ATTR_PER_CPU(rc_delayed_comp); 425f24a6d48SHarish Chegondi 426f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_resends); 427f931551bSRalph Campbell QIB_DIAGC_ATTR(seq_naks); 428f931551bSRalph Campbell QIB_DIAGC_ATTR(rdma_seq); 429f931551bSRalph Campbell QIB_DIAGC_ATTR(rnr_naks); 430f931551bSRalph Campbell QIB_DIAGC_ATTR(other_naks); 431f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_timeouts); 432f931551bSRalph Campbell QIB_DIAGC_ATTR(loop_pkts); 433f931551bSRalph Campbell QIB_DIAGC_ATTR(pkt_drops); 434f931551bSRalph Campbell QIB_DIAGC_ATTR(dmawait); 435f931551bSRalph Campbell QIB_DIAGC_ATTR(unaligned); 436f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_dupreq); 437f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_seqnak); 43871994354SKaike Wan QIB_DIAGC_ATTR(rc_crwaits); 439f931551bSRalph Campbell 440f931551bSRalph Campbell static struct attribute *diagc_default_attributes[] = { 441f931551bSRalph Campbell &qib_diagc_attr_rc_resends.attr, 442f931551bSRalph Campbell &qib_diagc_attr_rc_acks.attr, 443f931551bSRalph Campbell &qib_diagc_attr_rc_qacks.attr, 444f931551bSRalph Campbell &qib_diagc_attr_rc_delayed_comp.attr, 445f931551bSRalph Campbell &qib_diagc_attr_seq_naks.attr, 446f931551bSRalph Campbell &qib_diagc_attr_rdma_seq.attr, 447f931551bSRalph Campbell &qib_diagc_attr_rnr_naks.attr, 448f931551bSRalph Campbell &qib_diagc_attr_other_naks.attr, 449f931551bSRalph Campbell &qib_diagc_attr_rc_timeouts.attr, 450f931551bSRalph Campbell &qib_diagc_attr_loop_pkts.attr, 451f931551bSRalph Campbell &qib_diagc_attr_pkt_drops.attr, 452f931551bSRalph Campbell &qib_diagc_attr_dmawait.attr, 453f931551bSRalph Campbell &qib_diagc_attr_unaligned.attr, 454f931551bSRalph Campbell &qib_diagc_attr_rc_dupreq.attr, 455f931551bSRalph Campbell &qib_diagc_attr_rc_seqnak.attr, 45671994354SKaike Wan &qib_diagc_attr_rc_crwaits.attr, 457f931551bSRalph Campbell NULL 458f931551bSRalph Campbell }; 459f931551bSRalph Campbell 460f24a6d48SHarish Chegondi static u64 get_all_cpu_total(u64 __percpu *cntr) 461f24a6d48SHarish Chegondi { 462f24a6d48SHarish Chegondi int cpu; 463f24a6d48SHarish Chegondi u64 counter = 0; 464f24a6d48SHarish Chegondi 465f24a6d48SHarish Chegondi for_each_possible_cpu(cpu) 466f24a6d48SHarish Chegondi counter += *per_cpu_ptr(cntr, cpu); 467f24a6d48SHarish Chegondi return counter; 468f24a6d48SHarish Chegondi } 469f24a6d48SHarish Chegondi 470f24a6d48SHarish Chegondi #define def_write_per_cpu(cntr) \ 471f24a6d48SHarish Chegondi static void write_per_cpu_##cntr(struct qib_pportdata *ppd, u32 data) \ 472f24a6d48SHarish Chegondi { \ 473f24a6d48SHarish Chegondi struct qib_devdata *dd = ppd->dd; \ 474f24a6d48SHarish Chegondi struct qib_ibport *qibp = &ppd->ibport_data; \ 475f24a6d48SHarish Chegondi /* A write can only zero the counter */ \ 476f24a6d48SHarish Chegondi if (data == 0) \ 477f24a6d48SHarish Chegondi qibp->rvp.z_##cntr = get_all_cpu_total(qibp->rvp.cntr); \ 478f24a6d48SHarish Chegondi else \ 479f24a6d48SHarish Chegondi qib_dev_err(dd, "Per CPU cntrs can only be zeroed"); \ 480f24a6d48SHarish Chegondi } 481f24a6d48SHarish Chegondi 482f24a6d48SHarish Chegondi def_write_per_cpu(rc_acks) 483f24a6d48SHarish Chegondi def_write_per_cpu(rc_qacks) 484f24a6d48SHarish Chegondi def_write_per_cpu(rc_delayed_comp) 485f24a6d48SHarish Chegondi 486f24a6d48SHarish Chegondi #define READ_PER_CPU_CNTR(cntr) (get_all_cpu_total(qibp->rvp.cntr) - \ 487f24a6d48SHarish Chegondi qibp->rvp.z_##cntr) 488f24a6d48SHarish Chegondi 489f931551bSRalph Campbell static ssize_t diagc_attr_show(struct kobject *kobj, struct attribute *attr, 490f931551bSRalph Campbell char *buf) 491f931551bSRalph Campbell { 492f931551bSRalph Campbell struct qib_diagc_attr *dattr = 493f931551bSRalph Campbell container_of(attr, struct qib_diagc_attr, attr); 494f931551bSRalph Campbell struct qib_pportdata *ppd = 495f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, diagc_kobj); 496f931551bSRalph Campbell struct qib_ibport *qibp = &ppd->ibport_data; 497*e28bf1f0SJoe Perches u64 val; 498f931551bSRalph Campbell 499f24a6d48SHarish Chegondi if (!strncmp(dattr->attr.name, "rc_acks", 7)) 500*e28bf1f0SJoe Perches val = READ_PER_CPU_CNTR(rc_acks); 501f24a6d48SHarish Chegondi else if (!strncmp(dattr->attr.name, "rc_qacks", 8)) 502*e28bf1f0SJoe Perches val = READ_PER_CPU_CNTR(rc_qacks); 503f24a6d48SHarish Chegondi else if (!strncmp(dattr->attr.name, "rc_delayed_comp", 15)) 504*e28bf1f0SJoe Perches val = READ_PER_CPU_CNTR(rc_delayed_comp); 505f24a6d48SHarish Chegondi else 506*e28bf1f0SJoe Perches val = *(u32 *)((char *)qibp + dattr->counter); 507*e28bf1f0SJoe Perches 508*e28bf1f0SJoe Perches return sysfs_emit(buf, "%llu\n", val); 509f931551bSRalph Campbell } 510f931551bSRalph Campbell 5114c6931f5SIra Weiny static ssize_t diagc_attr_store(struct kobject *kobj, struct attribute *attr, 5124c6931f5SIra Weiny const char *buf, size_t size) 5134c6931f5SIra Weiny { 5144c6931f5SIra Weiny struct qib_diagc_attr *dattr = 5154c6931f5SIra Weiny container_of(attr, struct qib_diagc_attr, attr); 5164c6931f5SIra Weiny struct qib_pportdata *ppd = 5174c6931f5SIra Weiny container_of(kobj, struct qib_pportdata, diagc_kobj); 5184c6931f5SIra Weiny struct qib_ibport *qibp = &ppd->ibport_data; 5197fac3301SMike Marciniszyn u32 val; 5207fac3301SMike Marciniszyn int ret; 5214c6931f5SIra Weiny 5227fac3301SMike Marciniszyn ret = kstrtou32(buf, 0, &val); 5237fac3301SMike Marciniszyn if (ret) 5247fac3301SMike Marciniszyn return ret; 525f24a6d48SHarish Chegondi 526f24a6d48SHarish Chegondi if (!strncmp(dattr->attr.name, "rc_acks", 7)) 527f24a6d48SHarish Chegondi write_per_cpu_rc_acks(ppd, val); 528f24a6d48SHarish Chegondi else if (!strncmp(dattr->attr.name, "rc_qacks", 8)) 529f24a6d48SHarish Chegondi write_per_cpu_rc_qacks(ppd, val); 530f24a6d48SHarish Chegondi else if (!strncmp(dattr->attr.name, "rc_delayed_comp", 15)) 531f24a6d48SHarish Chegondi write_per_cpu_rc_delayed_comp(ppd, val); 532f24a6d48SHarish Chegondi else 5334c6931f5SIra Weiny *(u32 *)((char *)qibp + dattr->counter) = val; 5344c6931f5SIra Weiny return size; 5354c6931f5SIra Weiny } 5364c6931f5SIra Weiny 537f931551bSRalph Campbell static const struct sysfs_ops qib_diagc_ops = { 538f931551bSRalph Campbell .show = diagc_attr_show, 5394c6931f5SIra Weiny .store = diagc_attr_store, 540f931551bSRalph Campbell }; 541f931551bSRalph Campbell 542f931551bSRalph Campbell static struct kobj_type qib_diagc_ktype = { 543f931551bSRalph Campbell .release = qib_port_release, 544f931551bSRalph Campbell .sysfs_ops = &qib_diagc_ops, 545f931551bSRalph Campbell .default_attrs = diagc_default_attributes 546f931551bSRalph Campbell }; 547f931551bSRalph Campbell 548f931551bSRalph Campbell /* End diag_counters */ 549f931551bSRalph Campbell 550f931551bSRalph Campbell /* end of per-port file structures and support code */ 551f931551bSRalph Campbell 552f931551bSRalph Campbell /* 553f931551bSRalph Campbell * Start of per-unit (or driver, in some cases, but replicated 554f931551bSRalph Campbell * per unit) functions (these get a device *) 555f931551bSRalph Campbell */ 556508a523fSParav Pandit static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, 557f931551bSRalph Campbell char *buf) 558f931551bSRalph Campbell { 559f931551bSRalph Campbell struct qib_ibdev *dev = 56054747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 561f931551bSRalph Campbell 5621c7fd726SJoe Perches return sysfs_emit(buf, "%x\n", dd_from_dev(dev)->minrev); 563f931551bSRalph Campbell } 564508a523fSParav Pandit static DEVICE_ATTR_RO(hw_rev); 565f931551bSRalph Campbell 566508a523fSParav Pandit static ssize_t hca_type_show(struct device *device, 567508a523fSParav Pandit struct device_attribute *attr, char *buf) 568f931551bSRalph Campbell { 569f931551bSRalph Campbell struct qib_ibdev *dev = 57054747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 571f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 572f931551bSRalph Campbell 573f931551bSRalph Campbell if (!dd->boardname) 57445808361SJoe Perches return -EINVAL; 57545808361SJoe Perches return sysfs_emit(buf, "%s\n", dd->boardname); 576f931551bSRalph Campbell } 577508a523fSParav Pandit static DEVICE_ATTR_RO(hca_type); 578508a523fSParav Pandit static DEVICE_ATTR(board_id, 0444, hca_type_show, NULL); 579f931551bSRalph Campbell 580508a523fSParav Pandit static ssize_t version_show(struct device *device, 581f931551bSRalph Campbell struct device_attribute *attr, char *buf) 582f931551bSRalph Campbell { 583f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 5841c7fd726SJoe Perches return sysfs_emit(buf, "%s", (char *)ib_qib_version); 585f931551bSRalph Campbell } 586508a523fSParav Pandit static DEVICE_ATTR_RO(version); 587f931551bSRalph Campbell 588508a523fSParav Pandit static ssize_t boardversion_show(struct device *device, 589f931551bSRalph Campbell struct device_attribute *attr, char *buf) 590f931551bSRalph Campbell { 591f931551bSRalph Campbell struct qib_ibdev *dev = 59254747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 593f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 594f931551bSRalph Campbell 595f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 5961c7fd726SJoe Perches return sysfs_emit(buf, "%s", dd->boardversion); 597f931551bSRalph Campbell } 598508a523fSParav Pandit static DEVICE_ATTR_RO(boardversion); 599f931551bSRalph Campbell 600508a523fSParav Pandit static ssize_t localbus_info_show(struct device *device, 601f931551bSRalph Campbell struct device_attribute *attr, char *buf) 602f931551bSRalph Campbell { 603f931551bSRalph Campbell struct qib_ibdev *dev = 60454747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 605f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 606f931551bSRalph Campbell 607f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 6081c7fd726SJoe Perches return sysfs_emit(buf, "%s", dd->lbus_info); 609f931551bSRalph Campbell } 610508a523fSParav Pandit static DEVICE_ATTR_RO(localbus_info); 611f931551bSRalph Campbell 612508a523fSParav Pandit static ssize_t nctxts_show(struct device *device, 613f931551bSRalph Campbell struct device_attribute *attr, char *buf) 614f931551bSRalph Campbell { 615f931551bSRalph Campbell struct qib_ibdev *dev = 61654747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 617f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 618f931551bSRalph Campbell 619f931551bSRalph Campbell /* Return the number of user ports (contexts) available. */ 6206ceaadeeSMitko Haralanov /* The calculation below deals with a special case where 6216ceaadeeSMitko Haralanov * cfgctxts is set to 1 on a single-port board. */ 6221c7fd726SJoe Perches return sysfs_emit(buf, "%u\n", 6231c7fd726SJoe Perches (dd->first_user_ctxt > dd->cfgctxts) ? 6241c7fd726SJoe Perches 0 : 6256ceaadeeSMitko Haralanov (dd->cfgctxts - dd->first_user_ctxt)); 626f931551bSRalph Campbell } 627508a523fSParav Pandit static DEVICE_ATTR_RO(nctxts); 628f931551bSRalph Campbell 629508a523fSParav Pandit static ssize_t nfreectxts_show(struct device *device, 6302df4f757SRam Vepa struct device_attribute *attr, char *buf) 6312df4f757SRam Vepa { 6322df4f757SRam Vepa struct qib_ibdev *dev = 63354747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 6342df4f757SRam Vepa struct qib_devdata *dd = dd_from_dev(dev); 6352df4f757SRam Vepa 6362df4f757SRam Vepa /* Return the number of free user ports (contexts) available. */ 6371c7fd726SJoe Perches return sysfs_emit(buf, "%u\n", dd->freectxts); 6382df4f757SRam Vepa } 639508a523fSParav Pandit static DEVICE_ATTR_RO(nfreectxts); 6402df4f757SRam Vepa 64145808361SJoe Perches static ssize_t serial_show(struct device *device, struct device_attribute *attr, 64245808361SJoe Perches char *buf) 643f931551bSRalph Campbell { 644f931551bSRalph Campbell struct qib_ibdev *dev = 64554747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 646f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 64745808361SJoe Perches const u8 *end = memchr(dd->serial, 0, ARRAY_SIZE(dd->serial)); 64845808361SJoe Perches int size = end ? end - dd->serial : ARRAY_SIZE(dd->serial); 649f931551bSRalph Campbell 65045808361SJoe Perches return sysfs_emit(buf, ".%*s\n", size, dd->serial); 651f931551bSRalph Campbell } 652508a523fSParav Pandit static DEVICE_ATTR_RO(serial); 653f931551bSRalph Campbell 654508a523fSParav Pandit static ssize_t chip_reset_store(struct device *device, 655f931551bSRalph Campbell struct device_attribute *attr, const char *buf, 656f931551bSRalph Campbell size_t count) 657f931551bSRalph Campbell { 658f931551bSRalph Campbell struct qib_ibdev *dev = 65954747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 660f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 661f931551bSRalph Campbell int ret; 662f931551bSRalph Campbell 663f931551bSRalph Campbell if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 664f931551bSRalph Campbell ret = -EINVAL; 665f931551bSRalph Campbell goto bail; 666f931551bSRalph Campbell } 667f931551bSRalph Campbell 668f931551bSRalph Campbell ret = qib_reset_device(dd->unit); 669f931551bSRalph Campbell bail: 670f931551bSRalph Campbell return ret < 0 ? ret : count; 671f931551bSRalph Campbell } 672508a523fSParav Pandit static DEVICE_ATTR_WO(chip_reset); 673f931551bSRalph Campbell 674f931551bSRalph Campbell /* 675f931551bSRalph Campbell * Dump tempsense regs. in decimal, to ease shell-scripts. 676f931551bSRalph Campbell */ 677508a523fSParav Pandit static ssize_t tempsense_show(struct device *device, 678f931551bSRalph Campbell struct device_attribute *attr, char *buf) 679f931551bSRalph Campbell { 680f931551bSRalph Campbell struct qib_ibdev *dev = 68154747231SParav Pandit rdma_device_to_drv_device(device, struct qib_ibdev, rdi.ibdev); 682f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 68345808361SJoe Perches int i; 684f931551bSRalph Campbell u8 regvals[8]; 685f931551bSRalph Campbell 68645808361SJoe Perches for (i = 0; i < 8; i++) { 68745808361SJoe Perches int ret; 68845808361SJoe Perches 68945808361SJoe Perches if (i == 6) 690f931551bSRalph Campbell continue; 69145808361SJoe Perches ret = dd->f_tempsense_rd(dd, i); 692f931551bSRalph Campbell if (ret < 0) 69345808361SJoe Perches return ret; /* return error on bad read */ 69445808361SJoe Perches regvals[i] = ret; 695f931551bSRalph Campbell } 69645808361SJoe Perches return sysfs_emit(buf, "%d %d %02X %02X %d %d\n", 69745808361SJoe Perches (signed char)regvals[0], 69845808361SJoe Perches (signed char)regvals[1], 69945808361SJoe Perches regvals[2], 70045808361SJoe Perches regvals[3], 70145808361SJoe Perches (signed char)regvals[5], 70245808361SJoe Perches (signed char)regvals[7]); 703f931551bSRalph Campbell } 704508a523fSParav Pandit static DEVICE_ATTR_RO(tempsense); 705f931551bSRalph Campbell 706f931551bSRalph Campbell /* 707f931551bSRalph Campbell * end of per-unit (or driver, in some cases, but replicated 708f931551bSRalph Campbell * per unit) functions 709f931551bSRalph Campbell */ 710f931551bSRalph Campbell 711f931551bSRalph Campbell /* start of per-unit file structures and support code */ 712508a523fSParav Pandit static struct attribute *qib_attributes[] = { 713508a523fSParav Pandit &dev_attr_hw_rev.attr, 714508a523fSParav Pandit &dev_attr_hca_type.attr, 715508a523fSParav Pandit &dev_attr_board_id.attr, 716508a523fSParav Pandit &dev_attr_version.attr, 717508a523fSParav Pandit &dev_attr_nctxts.attr, 718508a523fSParav Pandit &dev_attr_nfreectxts.attr, 719508a523fSParav Pandit &dev_attr_serial.attr, 720508a523fSParav Pandit &dev_attr_boardversion.attr, 721508a523fSParav Pandit &dev_attr_tempsense.attr, 722508a523fSParav Pandit &dev_attr_localbus_info.attr, 723508a523fSParav Pandit &dev_attr_chip_reset.attr, 724508a523fSParav Pandit NULL, 725508a523fSParav Pandit }; 726f931551bSRalph Campbell 727508a523fSParav Pandit const struct attribute_group qib_attr_group = { 728508a523fSParav Pandit .attrs = qib_attributes, 729f931551bSRalph Campbell }; 730f931551bSRalph Campbell 731f931551bSRalph Campbell int qib_create_port_files(struct ib_device *ibdev, u8 port_num, 732f931551bSRalph Campbell struct kobject *kobj) 733f931551bSRalph Campbell { 734f931551bSRalph Campbell struct qib_pportdata *ppd; 735f931551bSRalph Campbell struct qib_devdata *dd = dd_from_ibdev(ibdev); 736f931551bSRalph Campbell int ret; 737f931551bSRalph Campbell 738f931551bSRalph Campbell if (!port_num || port_num > dd->num_pports) { 7397fac3301SMike Marciniszyn qib_dev_err(dd, 7407fac3301SMike Marciniszyn "Skipping infiniband class with invalid port %u\n", 7417fac3301SMike Marciniszyn port_num); 742f931551bSRalph Campbell ret = -ENODEV; 743f931551bSRalph Campbell goto bail; 744f931551bSRalph Campbell } 745f931551bSRalph Campbell ppd = &dd->pport[port_num - 1]; 746f931551bSRalph Campbell 747f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj, 748f931551bSRalph Campbell "linkcontrol"); 749f931551bSRalph Campbell if (ret) { 7507fac3301SMike Marciniszyn qib_dev_err(dd, 7517fac3301SMike Marciniszyn "Skipping linkcontrol sysfs info, (err %d) port %u\n", 7527fac3301SMike Marciniszyn ret, port_num); 753a35cd644SKaike Wan goto bail_link; 754f931551bSRalph Campbell } 755f931551bSRalph Campbell kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); 756f931551bSRalph Campbell 757f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj, 758f931551bSRalph Campbell "sl2vl"); 759f931551bSRalph Campbell if (ret) { 7607fac3301SMike Marciniszyn qib_dev_err(dd, 7617fac3301SMike Marciniszyn "Skipping sl2vl sysfs info, (err %d) port %u\n", 7627fac3301SMike Marciniszyn ret, port_num); 763a35cd644SKaike Wan goto bail_sl; 764f931551bSRalph Campbell } 765f931551bSRalph Campbell kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); 766f931551bSRalph Campbell 767f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj, 768f931551bSRalph Campbell "diag_counters"); 769f931551bSRalph Campbell if (ret) { 7707fac3301SMike Marciniszyn qib_dev_err(dd, 7717fac3301SMike Marciniszyn "Skipping diag_counters sysfs info, (err %d) port %u\n", 7727fac3301SMike Marciniszyn ret, port_num); 773a35cd644SKaike Wan goto bail_diagc; 774f931551bSRalph Campbell } 775f931551bSRalph Campbell kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); 776f931551bSRalph Campbell 77736a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->congestion_entries_shadow) 778f931551bSRalph Campbell return 0; 779f931551bSRalph Campbell 78036a8f01cSMike Marciniszyn ret = kobject_init_and_add(&ppd->pport_cc_kobj, &qib_port_cc_ktype, 78136a8f01cSMike Marciniszyn kobj, "CCMgtA"); 78236a8f01cSMike Marciniszyn if (ret) { 78336a8f01cSMike Marciniszyn qib_dev_err(dd, 78436a8f01cSMike Marciniszyn "Skipping Congestion Control sysfs info, (err %d) port %u\n", 78536a8f01cSMike Marciniszyn ret, port_num); 786a35cd644SKaike Wan goto bail_cc; 78736a8f01cSMike Marciniszyn } 78836a8f01cSMike Marciniszyn 78936a8f01cSMike Marciniszyn kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); 79036a8f01cSMike Marciniszyn 79136a8f01cSMike Marciniszyn ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, 79236a8f01cSMike Marciniszyn &cc_setting_bin_attr); 79336a8f01cSMike Marciniszyn if (ret) { 79436a8f01cSMike Marciniszyn qib_dev_err(dd, 79536a8f01cSMike Marciniszyn "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", 79636a8f01cSMike Marciniszyn ret, port_num); 79736a8f01cSMike Marciniszyn goto bail_cc; 79836a8f01cSMike Marciniszyn } 79936a8f01cSMike Marciniszyn 80036a8f01cSMike Marciniszyn ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, 80136a8f01cSMike Marciniszyn &cc_table_bin_attr); 80236a8f01cSMike Marciniszyn if (ret) { 80336a8f01cSMike Marciniszyn qib_dev_err(dd, 80436a8f01cSMike Marciniszyn "Skipping Congestion Control table sysfs info, (err %d) port %u\n", 80536a8f01cSMike Marciniszyn ret, port_num); 80636a8f01cSMike Marciniszyn goto bail_cc_entry_bin; 80736a8f01cSMike Marciniszyn } 80836a8f01cSMike Marciniszyn 80936a8f01cSMike Marciniszyn qib_devinfo(dd->pcidev, 81036a8f01cSMike Marciniszyn "IB%u: Congestion Control Agent enabled for port %d\n", 81136a8f01cSMike Marciniszyn dd->unit, port_num); 81236a8f01cSMike Marciniszyn 81336a8f01cSMike Marciniszyn return 0; 81436a8f01cSMike Marciniszyn 81536a8f01cSMike Marciniszyn bail_cc_entry_bin: 81636a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); 81736a8f01cSMike Marciniszyn bail_cc: 81836a8f01cSMike Marciniszyn kobject_put(&ppd->pport_cc_kobj); 819f931551bSRalph Campbell bail_diagc: 82036a8f01cSMike Marciniszyn kobject_put(&ppd->diagc_kobj); 821f931551bSRalph Campbell bail_sl: 82236a8f01cSMike Marciniszyn kobject_put(&ppd->sl2vl_kobj); 82336a8f01cSMike Marciniszyn bail_link: 824f931551bSRalph Campbell kobject_put(&ppd->pport_kobj); 825f931551bSRalph Campbell bail: 826f931551bSRalph Campbell return ret; 827f931551bSRalph Campbell } 828f931551bSRalph Campbell 829f931551bSRalph Campbell /* 830f931551bSRalph Campbell * Unregister and remove our files in /sys/class/infiniband. 831f931551bSRalph Campbell */ 832f931551bSRalph Campbell void qib_verbs_unregister_sysfs(struct qib_devdata *dd) 833f931551bSRalph Campbell { 834f931551bSRalph Campbell struct qib_pportdata *ppd; 835f931551bSRalph Campbell int i; 836f931551bSRalph Campbell 837f931551bSRalph Campbell for (i = 0; i < dd->num_pports; i++) { 838f931551bSRalph Campbell ppd = &dd->pport[i]; 83936a8f01cSMike Marciniszyn if (qib_cc_table_size && 84036a8f01cSMike Marciniszyn ppd->congestion_entries_shadow) { 84136a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, 84236a8f01cSMike Marciniszyn &cc_setting_bin_attr); 84336a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, 84436a8f01cSMike Marciniszyn &cc_table_bin_attr); 84536a8f01cSMike Marciniszyn kobject_put(&ppd->pport_cc_kobj); 84636a8f01cSMike Marciniszyn } 847a35cd644SKaike Wan kobject_put(&ppd->diagc_kobj); 848f931551bSRalph Campbell kobject_put(&ppd->sl2vl_kobj); 84936a8f01cSMike Marciniszyn kobject_put(&ppd->pport_kobj); 850f931551bSRalph Campbell } 851f931551bSRalph Campbell } 852