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 int ret; 47f931551bSRalph Campbell 48f931551bSRalph Campbell ret = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT); 49f931551bSRalph Campbell ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); 50f931551bSRalph Campbell return ret; 51f931551bSRalph Campbell } 52f931551bSRalph Campbell 53f931551bSRalph Campbell static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf, 54f931551bSRalph Campbell size_t count) 55f931551bSRalph Campbell { 56f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 57f931551bSRalph Campbell int ret; 58f931551bSRalph Campbell u16 val; 59f931551bSRalph Campbell 60*7fac3301SMike Marciniszyn ret = kstrtou16(buf, 0, &val); 61*7fac3301SMike Marciniszyn if (ret) { 62*7fac3301SMike Marciniszyn qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); 63*7fac3301SMike Marciniszyn return ret; 64*7fac3301SMike Marciniszyn } 65f931551bSRalph Campbell 66f931551bSRalph Campbell /* 67f931551bSRalph Campbell * Set the "intentional" heartbeat enable per either of 68f931551bSRalph Campbell * "Enable" and "Auto", as these are normally set together. 69f931551bSRalph Campbell * This bit is consulted when leaving loopback mode, 70f931551bSRalph Campbell * because entering loopback mode overrides it and automatically 71f931551bSRalph Campbell * disables heartbeat. 72f931551bSRalph Campbell */ 73f931551bSRalph Campbell ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val); 74f931551bSRalph Campbell return ret < 0 ? ret : count; 75f931551bSRalph Campbell } 76f931551bSRalph Campbell 77f931551bSRalph Campbell static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf, 78f931551bSRalph Campbell size_t count) 79f931551bSRalph Campbell { 80f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 81f931551bSRalph Campbell int ret = count, r; 82f931551bSRalph Campbell 83f931551bSRalph Campbell r = dd->f_set_ib_loopback(ppd, buf); 84f931551bSRalph Campbell if (r < 0) 85f931551bSRalph Campbell ret = r; 86f931551bSRalph Campbell 87f931551bSRalph Campbell return ret; 88f931551bSRalph Campbell } 89f931551bSRalph Campbell 90f931551bSRalph Campbell static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf, 91f931551bSRalph Campbell size_t count) 92f931551bSRalph Campbell { 93f931551bSRalph Campbell struct qib_devdata *dd = ppd->dd; 94f931551bSRalph Campbell int ret; 95f931551bSRalph Campbell u16 val; 96f931551bSRalph Campbell 97*7fac3301SMike Marciniszyn ret = kstrtou16(buf, 0, &val); 98*7fac3301SMike Marciniszyn if (ret) { 99f931551bSRalph Campbell qib_dev_err(dd, "attempt to set invalid LED override\n"); 100*7fac3301SMike Marciniszyn return ret; 101*7fac3301SMike Marciniszyn } 102*7fac3301SMike Marciniszyn 103*7fac3301SMike Marciniszyn qib_set_led_override(ppd, val); 104*7fac3301SMike Marciniszyn return count; 105f931551bSRalph Campbell } 106f931551bSRalph Campbell 107f931551bSRalph Campbell static ssize_t show_status(struct qib_pportdata *ppd, char *buf) 108f931551bSRalph Campbell { 109f931551bSRalph Campbell ssize_t ret; 110f931551bSRalph Campbell 111f931551bSRalph Campbell if (!ppd->statusp) 112f931551bSRalph Campbell ret = -EINVAL; 113f931551bSRalph Campbell else 114f931551bSRalph Campbell ret = scnprintf(buf, PAGE_SIZE, "0x%llx\n", 115f931551bSRalph Campbell (unsigned long long) *(ppd->statusp)); 116f931551bSRalph Campbell return ret; 117f931551bSRalph Campbell } 118f931551bSRalph Campbell 119f931551bSRalph Campbell /* 120f931551bSRalph Campbell * For userland compatibility, these offsets must remain fixed. 121f931551bSRalph Campbell * They are strings for QIB_STATUS_* 122f931551bSRalph Campbell */ 123865b64beSMike Marciniszyn static const char * const qib_status_str[] = { 124f931551bSRalph Campbell "Initted", 125f931551bSRalph Campbell "", 126f931551bSRalph Campbell "", 127f931551bSRalph Campbell "", 128f931551bSRalph Campbell "", 129f931551bSRalph Campbell "Present", 130f931551bSRalph Campbell "IB_link_up", 131f931551bSRalph Campbell "IB_configured", 132f931551bSRalph Campbell "", 133f931551bSRalph Campbell "Fatal_Hardware_Error", 134f931551bSRalph Campbell NULL, 135f931551bSRalph Campbell }; 136f931551bSRalph Campbell 137f931551bSRalph Campbell static ssize_t show_status_str(struct qib_pportdata *ppd, char *buf) 138f931551bSRalph Campbell { 139f931551bSRalph Campbell int i, any; 140f931551bSRalph Campbell u64 s; 141f931551bSRalph Campbell ssize_t ret; 142f931551bSRalph Campbell 143f931551bSRalph Campbell if (!ppd->statusp) { 144f931551bSRalph Campbell ret = -EINVAL; 145f931551bSRalph Campbell goto bail; 146f931551bSRalph Campbell } 147f931551bSRalph Campbell 148f931551bSRalph Campbell s = *(ppd->statusp); 149f931551bSRalph Campbell *buf = '\0'; 150f931551bSRalph Campbell for (any = i = 0; s && qib_status_str[i]; i++) { 151f931551bSRalph Campbell if (s & 1) { 152f931551bSRalph Campbell /* if overflow */ 153f931551bSRalph Campbell if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) 154f931551bSRalph Campbell break; 155f931551bSRalph Campbell if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >= 156f931551bSRalph Campbell PAGE_SIZE) 157f931551bSRalph Campbell break; 158f931551bSRalph Campbell any = 1; 159f931551bSRalph Campbell } 160f931551bSRalph Campbell s >>= 1; 161f931551bSRalph Campbell } 162f931551bSRalph Campbell if (any) 163f931551bSRalph Campbell strlcat(buf, "\n", PAGE_SIZE); 164f931551bSRalph Campbell 165f931551bSRalph Campbell ret = strlen(buf); 166f931551bSRalph Campbell 167f931551bSRalph Campbell bail: 168f931551bSRalph Campbell return ret; 169f931551bSRalph Campbell } 170f931551bSRalph Campbell 171f931551bSRalph Campbell /* end of per-port functions */ 172f931551bSRalph Campbell 173f931551bSRalph Campbell /* 174f931551bSRalph Campbell * Start of per-port file structures and support code 175f931551bSRalph Campbell * Because we are fitting into other infrastructure, we have to supply the 176f931551bSRalph Campbell * full set of kobject/sysfs_ops structures and routines. 177f931551bSRalph Campbell */ 178f931551bSRalph Campbell #define QIB_PORT_ATTR(name, mode, show, store) \ 179f931551bSRalph Campbell static struct qib_port_attr qib_port_attr_##name = \ 180f931551bSRalph Campbell __ATTR(name, mode, show, store) 181f931551bSRalph Campbell 182f931551bSRalph Campbell struct qib_port_attr { 183f931551bSRalph Campbell struct attribute attr; 184f931551bSRalph Campbell ssize_t (*show)(struct qib_pportdata *, char *); 185f931551bSRalph Campbell ssize_t (*store)(struct qib_pportdata *, const char *, size_t); 186f931551bSRalph Campbell }; 187f931551bSRalph Campbell 188f931551bSRalph Campbell QIB_PORT_ATTR(loopback, S_IWUSR, NULL, store_loopback); 189f931551bSRalph Campbell QIB_PORT_ATTR(led_override, S_IWUSR, NULL, store_led_override); 190f931551bSRalph Campbell QIB_PORT_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, 191f931551bSRalph Campbell store_hrtbt_enb); 192f931551bSRalph Campbell QIB_PORT_ATTR(status, S_IRUGO, show_status, NULL); 193f931551bSRalph Campbell QIB_PORT_ATTR(status_str, S_IRUGO, show_status_str, NULL); 194f931551bSRalph Campbell 195f931551bSRalph Campbell static struct attribute *port_default_attributes[] = { 196f931551bSRalph Campbell &qib_port_attr_loopback.attr, 197f931551bSRalph Campbell &qib_port_attr_led_override.attr, 198f931551bSRalph Campbell &qib_port_attr_hrtbt_enable.attr, 199f931551bSRalph Campbell &qib_port_attr_status.attr, 200f931551bSRalph Campbell &qib_port_attr_status_str.attr, 201f931551bSRalph Campbell NULL 202f931551bSRalph Campbell }; 203f931551bSRalph Campbell 20436a8f01cSMike Marciniszyn /* 20536a8f01cSMike Marciniszyn * Start of per-port congestion control structures and support code 20636a8f01cSMike Marciniszyn */ 20736a8f01cSMike Marciniszyn 20836a8f01cSMike Marciniszyn /* 20936a8f01cSMike Marciniszyn * Congestion control table size followed by table entries 21036a8f01cSMike Marciniszyn */ 21136a8f01cSMike Marciniszyn static ssize_t read_cc_table_bin(struct file *filp, struct kobject *kobj, 21236a8f01cSMike Marciniszyn struct bin_attribute *bin_attr, 21336a8f01cSMike Marciniszyn char *buf, loff_t pos, size_t count) 21436a8f01cSMike Marciniszyn { 21536a8f01cSMike Marciniszyn int ret; 21636a8f01cSMike Marciniszyn struct qib_pportdata *ppd = 21736a8f01cSMike Marciniszyn container_of(kobj, struct qib_pportdata, pport_cc_kobj); 21836a8f01cSMike Marciniszyn 21936a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->ccti_entries_shadow) 22036a8f01cSMike Marciniszyn return -EINVAL; 22136a8f01cSMike Marciniszyn 22236a8f01cSMike Marciniszyn ret = ppd->total_cct_entry * sizeof(struct ib_cc_table_entry_shadow) 22336a8f01cSMike Marciniszyn + sizeof(__be16); 22436a8f01cSMike Marciniszyn 22536a8f01cSMike Marciniszyn if (pos > ret) 22636a8f01cSMike Marciniszyn return -EINVAL; 22736a8f01cSMike Marciniszyn 22836a8f01cSMike Marciniszyn if (count > ret - pos) 22936a8f01cSMike Marciniszyn count = ret - pos; 23036a8f01cSMike Marciniszyn 23136a8f01cSMike Marciniszyn if (!count) 23236a8f01cSMike Marciniszyn return count; 23336a8f01cSMike Marciniszyn 23436a8f01cSMike Marciniszyn spin_lock(&ppd->cc_shadow_lock); 23536a8f01cSMike Marciniszyn memcpy(buf, ppd->ccti_entries_shadow, count); 23636a8f01cSMike Marciniszyn spin_unlock(&ppd->cc_shadow_lock); 23736a8f01cSMike Marciniszyn 23836a8f01cSMike Marciniszyn return count; 23936a8f01cSMike Marciniszyn } 24036a8f01cSMike Marciniszyn 24136a8f01cSMike Marciniszyn static void qib_port_release(struct kobject *kobj) 24236a8f01cSMike Marciniszyn { 24336a8f01cSMike Marciniszyn /* nothing to do since memory is freed by qib_free_devdata() */ 24436a8f01cSMike Marciniszyn } 24536a8f01cSMike Marciniszyn 24636a8f01cSMike Marciniszyn static struct kobj_type qib_port_cc_ktype = { 24736a8f01cSMike Marciniszyn .release = qib_port_release, 24836a8f01cSMike Marciniszyn }; 24936a8f01cSMike Marciniszyn 25036a8f01cSMike Marciniszyn static struct bin_attribute cc_table_bin_attr = { 25136a8f01cSMike Marciniszyn .attr = {.name = "cc_table_bin", .mode = 0444}, 25236a8f01cSMike Marciniszyn .read = read_cc_table_bin, 25336a8f01cSMike Marciniszyn .size = PAGE_SIZE, 25436a8f01cSMike Marciniszyn }; 25536a8f01cSMike Marciniszyn 25636a8f01cSMike Marciniszyn /* 25736a8f01cSMike Marciniszyn * Congestion settings: port control, control map and an array of 16 25836a8f01cSMike Marciniszyn * entries for the congestion entries - increase, timer, event log 25936a8f01cSMike Marciniszyn * trigger threshold and the minimum injection rate delay. 26036a8f01cSMike Marciniszyn */ 26136a8f01cSMike Marciniszyn static ssize_t read_cc_setting_bin(struct file *filp, struct kobject *kobj, 26236a8f01cSMike Marciniszyn struct bin_attribute *bin_attr, 26336a8f01cSMike Marciniszyn char *buf, loff_t pos, size_t count) 26436a8f01cSMike Marciniszyn { 26536a8f01cSMike Marciniszyn int ret; 26636a8f01cSMike Marciniszyn struct qib_pportdata *ppd = 26736a8f01cSMike Marciniszyn container_of(kobj, struct qib_pportdata, pport_cc_kobj); 26836a8f01cSMike Marciniszyn 26936a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->congestion_entries_shadow) 27036a8f01cSMike Marciniszyn return -EINVAL; 27136a8f01cSMike Marciniszyn 27236a8f01cSMike Marciniszyn ret = sizeof(struct ib_cc_congestion_setting_attr_shadow); 27336a8f01cSMike Marciniszyn 27436a8f01cSMike Marciniszyn if (pos > ret) 27536a8f01cSMike Marciniszyn return -EINVAL; 27636a8f01cSMike Marciniszyn if (count > ret - pos) 27736a8f01cSMike Marciniszyn count = ret - pos; 27836a8f01cSMike Marciniszyn 27936a8f01cSMike Marciniszyn if (!count) 28036a8f01cSMike Marciniszyn return count; 28136a8f01cSMike Marciniszyn 28236a8f01cSMike Marciniszyn spin_lock(&ppd->cc_shadow_lock); 28336a8f01cSMike Marciniszyn memcpy(buf, ppd->congestion_entries_shadow, count); 28436a8f01cSMike Marciniszyn spin_unlock(&ppd->cc_shadow_lock); 28536a8f01cSMike Marciniszyn 28636a8f01cSMike Marciniszyn return count; 28736a8f01cSMike Marciniszyn } 28836a8f01cSMike Marciniszyn 28936a8f01cSMike Marciniszyn static struct bin_attribute cc_setting_bin_attr = { 29036a8f01cSMike Marciniszyn .attr = {.name = "cc_settings_bin", .mode = 0444}, 29136a8f01cSMike Marciniszyn .read = read_cc_setting_bin, 29236a8f01cSMike Marciniszyn .size = PAGE_SIZE, 29336a8f01cSMike Marciniszyn }; 29436a8f01cSMike Marciniszyn 29536a8f01cSMike Marciniszyn 296f931551bSRalph Campbell static ssize_t qib_portattr_show(struct kobject *kobj, 297f931551bSRalph Campbell struct attribute *attr, char *buf) 298f931551bSRalph Campbell { 299f931551bSRalph Campbell struct qib_port_attr *pattr = 300f931551bSRalph Campbell container_of(attr, struct qib_port_attr, attr); 301f931551bSRalph Campbell struct qib_pportdata *ppd = 302f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, pport_kobj); 303f931551bSRalph Campbell 304f931551bSRalph Campbell return pattr->show(ppd, buf); 305f931551bSRalph Campbell } 306f931551bSRalph Campbell 307f931551bSRalph Campbell static ssize_t qib_portattr_store(struct kobject *kobj, 308f931551bSRalph Campbell struct attribute *attr, const char *buf, size_t len) 309f931551bSRalph Campbell { 310f931551bSRalph Campbell struct qib_port_attr *pattr = 311f931551bSRalph Campbell container_of(attr, struct qib_port_attr, attr); 312f931551bSRalph Campbell struct qib_pportdata *ppd = 313f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, pport_kobj); 314f931551bSRalph Campbell 315f931551bSRalph Campbell return pattr->store(ppd, buf, len); 316f931551bSRalph Campbell } 317f931551bSRalph Campbell 318f931551bSRalph Campbell 319f931551bSRalph Campbell static const struct sysfs_ops qib_port_ops = { 320f931551bSRalph Campbell .show = qib_portattr_show, 321f931551bSRalph Campbell .store = qib_portattr_store, 322f931551bSRalph Campbell }; 323f931551bSRalph Campbell 324f931551bSRalph Campbell static struct kobj_type qib_port_ktype = { 325f931551bSRalph Campbell .release = qib_port_release, 326f931551bSRalph Campbell .sysfs_ops = &qib_port_ops, 327f931551bSRalph Campbell .default_attrs = port_default_attributes 328f931551bSRalph Campbell }; 329f931551bSRalph Campbell 330f931551bSRalph Campbell /* Start sl2vl */ 331f931551bSRalph Campbell 332f931551bSRalph Campbell #define QIB_SL2VL_ATTR(N) \ 333f931551bSRalph Campbell static struct qib_sl2vl_attr qib_sl2vl_attr_##N = { \ 334f931551bSRalph Campbell .attr = { .name = __stringify(N), .mode = 0444 }, \ 335f931551bSRalph Campbell .sl = N \ 336f931551bSRalph Campbell } 337f931551bSRalph Campbell 338f931551bSRalph Campbell struct qib_sl2vl_attr { 339f931551bSRalph Campbell struct attribute attr; 340f931551bSRalph Campbell int sl; 341f931551bSRalph Campbell }; 342f931551bSRalph Campbell 343f931551bSRalph Campbell QIB_SL2VL_ATTR(0); 344f931551bSRalph Campbell QIB_SL2VL_ATTR(1); 345f931551bSRalph Campbell QIB_SL2VL_ATTR(2); 346f931551bSRalph Campbell QIB_SL2VL_ATTR(3); 347f931551bSRalph Campbell QIB_SL2VL_ATTR(4); 348f931551bSRalph Campbell QIB_SL2VL_ATTR(5); 349f931551bSRalph Campbell QIB_SL2VL_ATTR(6); 350f931551bSRalph Campbell QIB_SL2VL_ATTR(7); 351f931551bSRalph Campbell QIB_SL2VL_ATTR(8); 352f931551bSRalph Campbell QIB_SL2VL_ATTR(9); 353f931551bSRalph Campbell QIB_SL2VL_ATTR(10); 354f931551bSRalph Campbell QIB_SL2VL_ATTR(11); 355f931551bSRalph Campbell QIB_SL2VL_ATTR(12); 356f931551bSRalph Campbell QIB_SL2VL_ATTR(13); 357f931551bSRalph Campbell QIB_SL2VL_ATTR(14); 358f931551bSRalph Campbell QIB_SL2VL_ATTR(15); 359f931551bSRalph Campbell 360f931551bSRalph Campbell static struct attribute *sl2vl_default_attributes[] = { 361f931551bSRalph Campbell &qib_sl2vl_attr_0.attr, 362f931551bSRalph Campbell &qib_sl2vl_attr_1.attr, 363f931551bSRalph Campbell &qib_sl2vl_attr_2.attr, 364f931551bSRalph Campbell &qib_sl2vl_attr_3.attr, 365f931551bSRalph Campbell &qib_sl2vl_attr_4.attr, 366f931551bSRalph Campbell &qib_sl2vl_attr_5.attr, 367f931551bSRalph Campbell &qib_sl2vl_attr_6.attr, 368f931551bSRalph Campbell &qib_sl2vl_attr_7.attr, 369f931551bSRalph Campbell &qib_sl2vl_attr_8.attr, 370f931551bSRalph Campbell &qib_sl2vl_attr_9.attr, 371f931551bSRalph Campbell &qib_sl2vl_attr_10.attr, 372f931551bSRalph Campbell &qib_sl2vl_attr_11.attr, 373f931551bSRalph Campbell &qib_sl2vl_attr_12.attr, 374f931551bSRalph Campbell &qib_sl2vl_attr_13.attr, 375f931551bSRalph Campbell &qib_sl2vl_attr_14.attr, 376f931551bSRalph Campbell &qib_sl2vl_attr_15.attr, 377f931551bSRalph Campbell NULL 378f931551bSRalph Campbell }; 379f931551bSRalph Campbell 380f931551bSRalph Campbell static ssize_t sl2vl_attr_show(struct kobject *kobj, struct attribute *attr, 381f931551bSRalph Campbell char *buf) 382f931551bSRalph Campbell { 383f931551bSRalph Campbell struct qib_sl2vl_attr *sattr = 384f931551bSRalph Campbell container_of(attr, struct qib_sl2vl_attr, attr); 385f931551bSRalph Campbell struct qib_pportdata *ppd = 386f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, sl2vl_kobj); 387f931551bSRalph Campbell struct qib_ibport *qibp = &ppd->ibport_data; 388f931551bSRalph Campbell 389f931551bSRalph Campbell return sprintf(buf, "%u\n", qibp->sl_to_vl[sattr->sl]); 390f931551bSRalph Campbell } 391f931551bSRalph Campbell 392f931551bSRalph Campbell static const struct sysfs_ops qib_sl2vl_ops = { 393f931551bSRalph Campbell .show = sl2vl_attr_show, 394f931551bSRalph Campbell }; 395f931551bSRalph Campbell 396f931551bSRalph Campbell static struct kobj_type qib_sl2vl_ktype = { 397f931551bSRalph Campbell .release = qib_port_release, 398f931551bSRalph Campbell .sysfs_ops = &qib_sl2vl_ops, 399f931551bSRalph Campbell .default_attrs = sl2vl_default_attributes 400f931551bSRalph Campbell }; 401f931551bSRalph Campbell 402f931551bSRalph Campbell /* End sl2vl */ 403f931551bSRalph Campbell 404f931551bSRalph Campbell /* Start diag_counters */ 405f931551bSRalph Campbell 406f931551bSRalph Campbell #define QIB_DIAGC_ATTR(N) \ 407f931551bSRalph Campbell static struct qib_diagc_attr qib_diagc_attr_##N = { \ 4084c6931f5SIra Weiny .attr = { .name = __stringify(N), .mode = 0664 }, \ 409f931551bSRalph Campbell .counter = offsetof(struct qib_ibport, n_##N) \ 410f931551bSRalph Campbell } 411f931551bSRalph Campbell 412f931551bSRalph Campbell struct qib_diagc_attr { 413f931551bSRalph Campbell struct attribute attr; 414f931551bSRalph Campbell size_t counter; 415f931551bSRalph Campbell }; 416f931551bSRalph Campbell 417f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_resends); 418f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_acks); 419f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_qacks); 420f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_delayed_comp); 421f931551bSRalph Campbell QIB_DIAGC_ATTR(seq_naks); 422f931551bSRalph Campbell QIB_DIAGC_ATTR(rdma_seq); 423f931551bSRalph Campbell QIB_DIAGC_ATTR(rnr_naks); 424f931551bSRalph Campbell QIB_DIAGC_ATTR(other_naks); 425f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_timeouts); 426f931551bSRalph Campbell QIB_DIAGC_ATTR(loop_pkts); 427f931551bSRalph Campbell QIB_DIAGC_ATTR(pkt_drops); 428f931551bSRalph Campbell QIB_DIAGC_ATTR(dmawait); 429f931551bSRalph Campbell QIB_DIAGC_ATTR(unaligned); 430f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_dupreq); 431f931551bSRalph Campbell QIB_DIAGC_ATTR(rc_seqnak); 432f931551bSRalph Campbell 433f931551bSRalph Campbell static struct attribute *diagc_default_attributes[] = { 434f931551bSRalph Campbell &qib_diagc_attr_rc_resends.attr, 435f931551bSRalph Campbell &qib_diagc_attr_rc_acks.attr, 436f931551bSRalph Campbell &qib_diagc_attr_rc_qacks.attr, 437f931551bSRalph Campbell &qib_diagc_attr_rc_delayed_comp.attr, 438f931551bSRalph Campbell &qib_diagc_attr_seq_naks.attr, 439f931551bSRalph Campbell &qib_diagc_attr_rdma_seq.attr, 440f931551bSRalph Campbell &qib_diagc_attr_rnr_naks.attr, 441f931551bSRalph Campbell &qib_diagc_attr_other_naks.attr, 442f931551bSRalph Campbell &qib_diagc_attr_rc_timeouts.attr, 443f931551bSRalph Campbell &qib_diagc_attr_loop_pkts.attr, 444f931551bSRalph Campbell &qib_diagc_attr_pkt_drops.attr, 445f931551bSRalph Campbell &qib_diagc_attr_dmawait.attr, 446f931551bSRalph Campbell &qib_diagc_attr_unaligned.attr, 447f931551bSRalph Campbell &qib_diagc_attr_rc_dupreq.attr, 448f931551bSRalph Campbell &qib_diagc_attr_rc_seqnak.attr, 449f931551bSRalph Campbell NULL 450f931551bSRalph Campbell }; 451f931551bSRalph Campbell 452f931551bSRalph Campbell static ssize_t diagc_attr_show(struct kobject *kobj, struct attribute *attr, 453f931551bSRalph Campbell char *buf) 454f931551bSRalph Campbell { 455f931551bSRalph Campbell struct qib_diagc_attr *dattr = 456f931551bSRalph Campbell container_of(attr, struct qib_diagc_attr, attr); 457f931551bSRalph Campbell struct qib_pportdata *ppd = 458f931551bSRalph Campbell container_of(kobj, struct qib_pportdata, diagc_kobj); 459f931551bSRalph Campbell struct qib_ibport *qibp = &ppd->ibport_data; 460f931551bSRalph Campbell 461f931551bSRalph Campbell return sprintf(buf, "%u\n", *(u32 *)((char *)qibp + dattr->counter)); 462f931551bSRalph Campbell } 463f931551bSRalph Campbell 4644c6931f5SIra Weiny static ssize_t diagc_attr_store(struct kobject *kobj, struct attribute *attr, 4654c6931f5SIra Weiny const char *buf, size_t size) 4664c6931f5SIra Weiny { 4674c6931f5SIra Weiny struct qib_diagc_attr *dattr = 4684c6931f5SIra Weiny container_of(attr, struct qib_diagc_attr, attr); 4694c6931f5SIra Weiny struct qib_pportdata *ppd = 4704c6931f5SIra Weiny container_of(kobj, struct qib_pportdata, diagc_kobj); 4714c6931f5SIra Weiny struct qib_ibport *qibp = &ppd->ibport_data; 472*7fac3301SMike Marciniszyn u32 val; 473*7fac3301SMike Marciniszyn int ret; 4744c6931f5SIra Weiny 475*7fac3301SMike Marciniszyn ret = kstrtou32(buf, 0, &val); 476*7fac3301SMike Marciniszyn if (ret) 477*7fac3301SMike Marciniszyn return ret; 4784c6931f5SIra Weiny *(u32 *)((char *) qibp + dattr->counter) = val; 4794c6931f5SIra Weiny return size; 4804c6931f5SIra Weiny } 4814c6931f5SIra Weiny 482f931551bSRalph Campbell static const struct sysfs_ops qib_diagc_ops = { 483f931551bSRalph Campbell .show = diagc_attr_show, 4844c6931f5SIra Weiny .store = diagc_attr_store, 485f931551bSRalph Campbell }; 486f931551bSRalph Campbell 487f931551bSRalph Campbell static struct kobj_type qib_diagc_ktype = { 488f931551bSRalph Campbell .release = qib_port_release, 489f931551bSRalph Campbell .sysfs_ops = &qib_diagc_ops, 490f931551bSRalph Campbell .default_attrs = diagc_default_attributes 491f931551bSRalph Campbell }; 492f931551bSRalph Campbell 493f931551bSRalph Campbell /* End diag_counters */ 494f931551bSRalph Campbell 495f931551bSRalph Campbell /* end of per-port file structures and support code */ 496f931551bSRalph Campbell 497f931551bSRalph Campbell /* 498f931551bSRalph Campbell * Start of per-unit (or driver, in some cases, but replicated 499f931551bSRalph Campbell * per unit) functions (these get a device *) 500f931551bSRalph Campbell */ 501f931551bSRalph Campbell static ssize_t show_rev(struct device *device, struct device_attribute *attr, 502f931551bSRalph Campbell char *buf) 503f931551bSRalph Campbell { 504f931551bSRalph Campbell struct qib_ibdev *dev = 505f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 506f931551bSRalph Campbell 507f931551bSRalph Campbell return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); 508f931551bSRalph Campbell } 509f931551bSRalph Campbell 510f931551bSRalph Campbell static ssize_t show_hca(struct device *device, struct device_attribute *attr, 511f931551bSRalph Campbell char *buf) 512f931551bSRalph Campbell { 513f931551bSRalph Campbell struct qib_ibdev *dev = 514f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 515f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 516f931551bSRalph Campbell int ret; 517f931551bSRalph Campbell 518f931551bSRalph Campbell if (!dd->boardname) 519f931551bSRalph Campbell ret = -EINVAL; 520f931551bSRalph Campbell else 521f931551bSRalph Campbell ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); 522f931551bSRalph Campbell return ret; 523f931551bSRalph Campbell } 524f931551bSRalph Campbell 525f931551bSRalph Campbell static ssize_t show_version(struct device *device, 526f931551bSRalph Campbell struct device_attribute *attr, char *buf) 527f931551bSRalph Campbell { 528f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 529f931551bSRalph Campbell return scnprintf(buf, PAGE_SIZE, "%s", (char *)ib_qib_version); 530f931551bSRalph Campbell } 531f931551bSRalph Campbell 532f931551bSRalph Campbell static ssize_t show_boardversion(struct device *device, 533f931551bSRalph Campbell struct device_attribute *attr, char *buf) 534f931551bSRalph Campbell { 535f931551bSRalph Campbell struct qib_ibdev *dev = 536f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 537f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 538f931551bSRalph Campbell 539f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 540f931551bSRalph Campbell return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); 541f931551bSRalph Campbell } 542f931551bSRalph Campbell 543f931551bSRalph Campbell 544f931551bSRalph Campbell static ssize_t show_localbus_info(struct device *device, 545f931551bSRalph Campbell struct device_attribute *attr, char *buf) 546f931551bSRalph Campbell { 547f931551bSRalph Campbell struct qib_ibdev *dev = 548f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 549f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 550f931551bSRalph Campbell 551f931551bSRalph Campbell /* The string printed here is already newline-terminated. */ 552f931551bSRalph Campbell return scnprintf(buf, PAGE_SIZE, "%s", dd->lbus_info); 553f931551bSRalph Campbell } 554f931551bSRalph Campbell 555f931551bSRalph Campbell 556f931551bSRalph Campbell static ssize_t show_nctxts(struct device *device, 557f931551bSRalph Campbell struct device_attribute *attr, char *buf) 558f931551bSRalph Campbell { 559f931551bSRalph Campbell struct qib_ibdev *dev = 560f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 561f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 562f931551bSRalph Campbell 563f931551bSRalph Campbell /* Return the number of user ports (contexts) available. */ 5646ceaadeeSMitko Haralanov /* The calculation below deals with a special case where 5656ceaadeeSMitko Haralanov * cfgctxts is set to 1 on a single-port board. */ 5666ceaadeeSMitko Haralanov return scnprintf(buf, PAGE_SIZE, "%u\n", 5676ceaadeeSMitko Haralanov (dd->first_user_ctxt > dd->cfgctxts) ? 0 : 5686ceaadeeSMitko Haralanov (dd->cfgctxts - dd->first_user_ctxt)); 569f931551bSRalph Campbell } 570f931551bSRalph Campbell 5712df4f757SRam Vepa static ssize_t show_nfreectxts(struct device *device, 5722df4f757SRam Vepa struct device_attribute *attr, char *buf) 5732df4f757SRam Vepa { 5742df4f757SRam Vepa struct qib_ibdev *dev = 5752df4f757SRam Vepa container_of(device, struct qib_ibdev, ibdev.dev); 5762df4f757SRam Vepa struct qib_devdata *dd = dd_from_dev(dev); 5772df4f757SRam Vepa 5782df4f757SRam Vepa /* Return the number of free user ports (contexts) available. */ 57953ab1c64SMike Marciniszyn return scnprintf(buf, PAGE_SIZE, "%u\n", dd->freectxts); 5802df4f757SRam Vepa } 5812df4f757SRam Vepa 582f931551bSRalph Campbell static ssize_t show_serial(struct device *device, 583f931551bSRalph Campbell struct device_attribute *attr, char *buf) 584f931551bSRalph Campbell { 585f931551bSRalph Campbell struct qib_ibdev *dev = 586f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 587f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 588f931551bSRalph Campbell 589f931551bSRalph Campbell buf[sizeof dd->serial] = '\0'; 590f931551bSRalph Campbell memcpy(buf, dd->serial, sizeof dd->serial); 591f931551bSRalph Campbell strcat(buf, "\n"); 592f931551bSRalph Campbell return strlen(buf); 593f931551bSRalph Campbell } 594f931551bSRalph Campbell 595f931551bSRalph Campbell static ssize_t store_chip_reset(struct device *device, 596f931551bSRalph Campbell struct device_attribute *attr, const char *buf, 597f931551bSRalph Campbell size_t count) 598f931551bSRalph Campbell { 599f931551bSRalph Campbell struct qib_ibdev *dev = 600f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 601f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 602f931551bSRalph Campbell int ret; 603f931551bSRalph Campbell 604f931551bSRalph Campbell if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { 605f931551bSRalph Campbell ret = -EINVAL; 606f931551bSRalph Campbell goto bail; 607f931551bSRalph Campbell } 608f931551bSRalph Campbell 609f931551bSRalph Campbell ret = qib_reset_device(dd->unit); 610f931551bSRalph Campbell bail: 611f931551bSRalph Campbell return ret < 0 ? ret : count; 612f931551bSRalph Campbell } 613f931551bSRalph Campbell 614f931551bSRalph Campbell static ssize_t show_logged_errs(struct device *device, 615f931551bSRalph Campbell struct device_attribute *attr, char *buf) 616f931551bSRalph Campbell { 617f931551bSRalph Campbell struct qib_ibdev *dev = 618f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 619f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 620f931551bSRalph Campbell int idx, count; 621f931551bSRalph Campbell 622f931551bSRalph Campbell /* force consistency with actual EEPROM */ 623f931551bSRalph Campbell if (qib_update_eeprom_log(dd) != 0) 624f931551bSRalph Campbell return -ENXIO; 625f931551bSRalph Campbell 626f931551bSRalph Campbell count = 0; 627f931551bSRalph Campbell for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { 628f931551bSRalph Campbell count += scnprintf(buf + count, PAGE_SIZE - count, "%d%c", 629f931551bSRalph Campbell dd->eep_st_errs[idx], 630f931551bSRalph Campbell idx == (QIB_EEP_LOG_CNT - 1) ? '\n' : ' '); 631f931551bSRalph Campbell } 632f931551bSRalph Campbell 633f931551bSRalph Campbell return count; 634f931551bSRalph Campbell } 635f931551bSRalph Campbell 636f931551bSRalph Campbell /* 637f931551bSRalph Campbell * Dump tempsense regs. in decimal, to ease shell-scripts. 638f931551bSRalph Campbell */ 639f931551bSRalph Campbell static ssize_t show_tempsense(struct device *device, 640f931551bSRalph Campbell struct device_attribute *attr, char *buf) 641f931551bSRalph Campbell { 642f931551bSRalph Campbell struct qib_ibdev *dev = 643f931551bSRalph Campbell container_of(device, struct qib_ibdev, ibdev.dev); 644f931551bSRalph Campbell struct qib_devdata *dd = dd_from_dev(dev); 645f931551bSRalph Campbell int ret; 646f931551bSRalph Campbell int idx; 647f931551bSRalph Campbell u8 regvals[8]; 648f931551bSRalph Campbell 649f931551bSRalph Campbell ret = -ENXIO; 650f931551bSRalph Campbell for (idx = 0; idx < 8; ++idx) { 651f931551bSRalph Campbell if (idx == 6) 652f931551bSRalph Campbell continue; 653f931551bSRalph Campbell ret = dd->f_tempsense_rd(dd, idx); 654f931551bSRalph Campbell if (ret < 0) 655f931551bSRalph Campbell break; 656f931551bSRalph Campbell regvals[idx] = ret; 657f931551bSRalph Campbell } 658f931551bSRalph Campbell if (idx == 8) 659f931551bSRalph Campbell ret = scnprintf(buf, PAGE_SIZE, "%d %d %02X %02X %d %d\n", 660f931551bSRalph Campbell *(signed char *)(regvals), 661f931551bSRalph Campbell *(signed char *)(regvals + 1), 662f931551bSRalph Campbell regvals[2], regvals[3], 663f931551bSRalph Campbell *(signed char *)(regvals + 5), 664f931551bSRalph Campbell *(signed char *)(regvals + 7)); 665f931551bSRalph Campbell return ret; 666f931551bSRalph Campbell } 667f931551bSRalph Campbell 668f931551bSRalph Campbell /* 669f931551bSRalph Campbell * end of per-unit (or driver, in some cases, but replicated 670f931551bSRalph Campbell * per unit) functions 671f931551bSRalph Campbell */ 672f931551bSRalph Campbell 673f931551bSRalph Campbell /* start of per-unit file structures and support code */ 674f931551bSRalph Campbell static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 675f931551bSRalph Campbell static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 676f931551bSRalph Campbell static DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL); 677f931551bSRalph Campbell static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 678f931551bSRalph Campbell static DEVICE_ATTR(nctxts, S_IRUGO, show_nctxts, NULL); 6792df4f757SRam Vepa static DEVICE_ATTR(nfreectxts, S_IRUGO, show_nfreectxts, NULL); 680f931551bSRalph Campbell static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); 681f931551bSRalph Campbell static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); 682f931551bSRalph Campbell static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); 683f931551bSRalph Campbell static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); 684f931551bSRalph Campbell static DEVICE_ATTR(localbus_info, S_IRUGO, show_localbus_info, NULL); 685f931551bSRalph Campbell static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); 686f931551bSRalph Campbell 687f931551bSRalph Campbell static struct device_attribute *qib_attributes[] = { 688f931551bSRalph Campbell &dev_attr_hw_rev, 689f931551bSRalph Campbell &dev_attr_hca_type, 690f931551bSRalph Campbell &dev_attr_board_id, 691f931551bSRalph Campbell &dev_attr_version, 692f931551bSRalph Campbell &dev_attr_nctxts, 6932df4f757SRam Vepa &dev_attr_nfreectxts, 694f931551bSRalph Campbell &dev_attr_serial, 695f931551bSRalph Campbell &dev_attr_boardversion, 696f931551bSRalph Campbell &dev_attr_logged_errors, 697f931551bSRalph Campbell &dev_attr_tempsense, 698f931551bSRalph Campbell &dev_attr_localbus_info, 699f931551bSRalph Campbell &dev_attr_chip_reset, 700f931551bSRalph Campbell }; 701f931551bSRalph Campbell 702f931551bSRalph Campbell int qib_create_port_files(struct ib_device *ibdev, u8 port_num, 703f931551bSRalph Campbell struct kobject *kobj) 704f931551bSRalph Campbell { 705f931551bSRalph Campbell struct qib_pportdata *ppd; 706f931551bSRalph Campbell struct qib_devdata *dd = dd_from_ibdev(ibdev); 707f931551bSRalph Campbell int ret; 708f931551bSRalph Campbell 709f931551bSRalph Campbell if (!port_num || port_num > dd->num_pports) { 710*7fac3301SMike Marciniszyn qib_dev_err(dd, 711*7fac3301SMike Marciniszyn "Skipping infiniband class with invalid port %u\n", 712*7fac3301SMike Marciniszyn port_num); 713f931551bSRalph Campbell ret = -ENODEV; 714f931551bSRalph Campbell goto bail; 715f931551bSRalph Campbell } 716f931551bSRalph Campbell ppd = &dd->pport[port_num - 1]; 717f931551bSRalph Campbell 718f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj, 719f931551bSRalph Campbell "linkcontrol"); 720f931551bSRalph Campbell if (ret) { 721*7fac3301SMike Marciniszyn qib_dev_err(dd, 722*7fac3301SMike Marciniszyn "Skipping linkcontrol sysfs info, (err %d) port %u\n", 723*7fac3301SMike Marciniszyn ret, port_num); 724f931551bSRalph Campbell goto bail; 725f931551bSRalph Campbell } 726f931551bSRalph Campbell kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); 727f931551bSRalph Campbell 728f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj, 729f931551bSRalph Campbell "sl2vl"); 730f931551bSRalph Campbell if (ret) { 731*7fac3301SMike Marciniszyn qib_dev_err(dd, 732*7fac3301SMike Marciniszyn "Skipping sl2vl sysfs info, (err %d) port %u\n", 733*7fac3301SMike Marciniszyn ret, port_num); 73436a8f01cSMike Marciniszyn goto bail_link; 735f931551bSRalph Campbell } 736f931551bSRalph Campbell kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); 737f931551bSRalph Campbell 738f931551bSRalph Campbell ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj, 739f931551bSRalph Campbell "diag_counters"); 740f931551bSRalph Campbell if (ret) { 741*7fac3301SMike Marciniszyn qib_dev_err(dd, 742*7fac3301SMike Marciniszyn "Skipping diag_counters sysfs info, (err %d) port %u\n", 743*7fac3301SMike Marciniszyn ret, port_num); 74436a8f01cSMike Marciniszyn goto bail_sl; 745f931551bSRalph Campbell } 746f931551bSRalph Campbell kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); 747f931551bSRalph Campbell 74836a8f01cSMike Marciniszyn if (!qib_cc_table_size || !ppd->congestion_entries_shadow) 749f931551bSRalph Campbell return 0; 750f931551bSRalph Campbell 75136a8f01cSMike Marciniszyn ret = kobject_init_and_add(&ppd->pport_cc_kobj, &qib_port_cc_ktype, 75236a8f01cSMike Marciniszyn kobj, "CCMgtA"); 75336a8f01cSMike Marciniszyn if (ret) { 75436a8f01cSMike Marciniszyn qib_dev_err(dd, 75536a8f01cSMike Marciniszyn "Skipping Congestion Control sysfs info, (err %d) port %u\n", 75636a8f01cSMike Marciniszyn ret, port_num); 75736a8f01cSMike Marciniszyn goto bail_diagc; 75836a8f01cSMike Marciniszyn } 75936a8f01cSMike Marciniszyn 76036a8f01cSMike Marciniszyn kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); 76136a8f01cSMike Marciniszyn 76236a8f01cSMike Marciniszyn ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, 76336a8f01cSMike Marciniszyn &cc_setting_bin_attr); 76436a8f01cSMike Marciniszyn if (ret) { 76536a8f01cSMike Marciniszyn qib_dev_err(dd, 76636a8f01cSMike Marciniszyn "Skipping Congestion Control setting sysfs info, (err %d) port %u\n", 76736a8f01cSMike Marciniszyn ret, port_num); 76836a8f01cSMike Marciniszyn goto bail_cc; 76936a8f01cSMike Marciniszyn } 77036a8f01cSMike Marciniszyn 77136a8f01cSMike Marciniszyn ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, 77236a8f01cSMike Marciniszyn &cc_table_bin_attr); 77336a8f01cSMike Marciniszyn if (ret) { 77436a8f01cSMike Marciniszyn qib_dev_err(dd, 77536a8f01cSMike Marciniszyn "Skipping Congestion Control table sysfs info, (err %d) port %u\n", 77636a8f01cSMike Marciniszyn ret, port_num); 77736a8f01cSMike Marciniszyn goto bail_cc_entry_bin; 77836a8f01cSMike Marciniszyn } 77936a8f01cSMike Marciniszyn 78036a8f01cSMike Marciniszyn qib_devinfo(dd->pcidev, 78136a8f01cSMike Marciniszyn "IB%u: Congestion Control Agent enabled for port %d\n", 78236a8f01cSMike Marciniszyn dd->unit, port_num); 78336a8f01cSMike Marciniszyn 78436a8f01cSMike Marciniszyn return 0; 78536a8f01cSMike Marciniszyn 78636a8f01cSMike Marciniszyn bail_cc_entry_bin: 78736a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr); 78836a8f01cSMike Marciniszyn bail_cc: 78936a8f01cSMike Marciniszyn kobject_put(&ppd->pport_cc_kobj); 790f931551bSRalph Campbell bail_diagc: 79136a8f01cSMike Marciniszyn kobject_put(&ppd->diagc_kobj); 792f931551bSRalph Campbell bail_sl: 79336a8f01cSMike Marciniszyn kobject_put(&ppd->sl2vl_kobj); 79436a8f01cSMike Marciniszyn bail_link: 795f931551bSRalph Campbell kobject_put(&ppd->pport_kobj); 796f931551bSRalph Campbell bail: 797f931551bSRalph Campbell return ret; 798f931551bSRalph Campbell } 799f931551bSRalph Campbell 800f931551bSRalph Campbell /* 801f931551bSRalph Campbell * Register and create our files in /sys/class/infiniband. 802f931551bSRalph Campbell */ 803f931551bSRalph Campbell int qib_verbs_register_sysfs(struct qib_devdata *dd) 804f931551bSRalph Campbell { 805f931551bSRalph Campbell struct ib_device *dev = &dd->verbs_dev.ibdev; 806f931551bSRalph Campbell int i, ret; 807f931551bSRalph Campbell 808f931551bSRalph Campbell for (i = 0; i < ARRAY_SIZE(qib_attributes); ++i) { 809f931551bSRalph Campbell ret = device_create_file(&dev->dev, qib_attributes[i]); 810f931551bSRalph Campbell if (ret) 811f931551bSRalph Campbell return ret; 812f931551bSRalph Campbell } 813f931551bSRalph Campbell 814f931551bSRalph Campbell return 0; 815f931551bSRalph Campbell } 816f931551bSRalph Campbell 817f931551bSRalph Campbell /* 818f931551bSRalph Campbell * Unregister and remove our files in /sys/class/infiniband. 819f931551bSRalph Campbell */ 820f931551bSRalph Campbell void qib_verbs_unregister_sysfs(struct qib_devdata *dd) 821f931551bSRalph Campbell { 822f931551bSRalph Campbell struct qib_pportdata *ppd; 823f931551bSRalph Campbell int i; 824f931551bSRalph Campbell 825f931551bSRalph Campbell for (i = 0; i < dd->num_pports; i++) { 826f931551bSRalph Campbell ppd = &dd->pport[i]; 82736a8f01cSMike Marciniszyn if (qib_cc_table_size && 82836a8f01cSMike Marciniszyn ppd->congestion_entries_shadow) { 82936a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, 83036a8f01cSMike Marciniszyn &cc_setting_bin_attr); 83136a8f01cSMike Marciniszyn sysfs_remove_bin_file(&ppd->pport_cc_kobj, 83236a8f01cSMike Marciniszyn &cc_table_bin_attr); 83336a8f01cSMike Marciniszyn kobject_put(&ppd->pport_cc_kobj); 83436a8f01cSMike Marciniszyn } 835f931551bSRalph Campbell kobject_put(&ppd->sl2vl_kobj); 83636a8f01cSMike Marciniszyn kobject_put(&ppd->pport_kobj); 837f931551bSRalph Campbell } 838f931551bSRalph Campbell } 839