card_sysfs.c (7671B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * IBM Accelerator Family 'GenWQE' 4 * 5 * (C) Copyright IBM Corp. 2013 6 * 7 * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> 8 * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> 9 * Author: Michael Jung <mijung@gmx.net> 10 * Author: Michael Ruettger <michael@ibmra.de> 11 */ 12 13/* 14 * Sysfs interfaces for the GenWQE card. There are attributes to query 15 * the version of the bitstream as well as some for the driver. For 16 * debugging, please also see the debugfs interfaces of this driver. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/types.h> 21#include <linux/module.h> 22#include <linux/pci.h> 23#include <linux/string.h> 24#include <linux/fs.h> 25#include <linux/sysfs.h> 26#include <linux/ctype.h> 27#include <linux/device.h> 28 29#include "card_base.h" 30#include "card_ddcb.h" 31 32static const char * const genwqe_types[] = { 33 [GENWQE_TYPE_ALTERA_230] = "GenWQE4-230", 34 [GENWQE_TYPE_ALTERA_530] = "GenWQE4-530", 35 [GENWQE_TYPE_ALTERA_A4] = "GenWQE5-A4", 36 [GENWQE_TYPE_ALTERA_A7] = "GenWQE5-A7", 37}; 38 39static ssize_t status_show(struct device *dev, struct device_attribute *attr, 40 char *buf) 41{ 42 struct genwqe_dev *cd = dev_get_drvdata(dev); 43 const char *cs[GENWQE_CARD_STATE_MAX] = { "unused", "used", "error" }; 44 45 return sprintf(buf, "%s\n", cs[cd->card_state]); 46} 47static DEVICE_ATTR_RO(status); 48 49static ssize_t appid_show(struct device *dev, struct device_attribute *attr, 50 char *buf) 51{ 52 char app_name[5]; 53 struct genwqe_dev *cd = dev_get_drvdata(dev); 54 55 genwqe_read_app_id(cd, app_name, sizeof(app_name)); 56 return sprintf(buf, "%s\n", app_name); 57} 58static DEVICE_ATTR_RO(appid); 59 60static ssize_t version_show(struct device *dev, struct device_attribute *attr, 61 char *buf) 62{ 63 u64 slu_id, app_id; 64 struct genwqe_dev *cd = dev_get_drvdata(dev); 65 66 slu_id = __genwqe_readq(cd, IO_SLU_UNITCFG); 67 app_id = __genwqe_readq(cd, IO_APP_UNITCFG); 68 69 return sprintf(buf, "%016llx.%016llx\n", slu_id, app_id); 70} 71static DEVICE_ATTR_RO(version); 72 73static ssize_t type_show(struct device *dev, struct device_attribute *attr, 74 char *buf) 75{ 76 u8 card_type; 77 struct genwqe_dev *cd = dev_get_drvdata(dev); 78 79 card_type = genwqe_card_type(cd); 80 return sprintf(buf, "%s\n", (card_type >= ARRAY_SIZE(genwqe_types)) ? 81 "invalid" : genwqe_types[card_type]); 82} 83static DEVICE_ATTR_RO(type); 84 85static ssize_t tempsens_show(struct device *dev, struct device_attribute *attr, 86 char *buf) 87{ 88 u64 tempsens; 89 struct genwqe_dev *cd = dev_get_drvdata(dev); 90 91 tempsens = __genwqe_readq(cd, IO_SLU_TEMPERATURE_SENSOR); 92 return sprintf(buf, "%016llx\n", tempsens); 93} 94static DEVICE_ATTR_RO(tempsens); 95 96static ssize_t freerunning_timer_show(struct device *dev, 97 struct device_attribute *attr, 98 char *buf) 99{ 100 u64 t; 101 struct genwqe_dev *cd = dev_get_drvdata(dev); 102 103 t = __genwqe_readq(cd, IO_SLC_FREE_RUNNING_TIMER); 104 return sprintf(buf, "%016llx\n", t); 105} 106static DEVICE_ATTR_RO(freerunning_timer); 107 108static ssize_t queue_working_time_show(struct device *dev, 109 struct device_attribute *attr, 110 char *buf) 111{ 112 u64 t; 113 struct genwqe_dev *cd = dev_get_drvdata(dev); 114 115 t = __genwqe_readq(cd, IO_SLC_QUEUE_WTIME); 116 return sprintf(buf, "%016llx\n", t); 117} 118static DEVICE_ATTR_RO(queue_working_time); 119 120static ssize_t base_clock_show(struct device *dev, 121 struct device_attribute *attr, 122 char *buf) 123{ 124 u64 base_clock; 125 struct genwqe_dev *cd = dev_get_drvdata(dev); 126 127 base_clock = genwqe_base_clock_frequency(cd); 128 return sprintf(buf, "%lld\n", base_clock); 129} 130static DEVICE_ATTR_RO(base_clock); 131 132/* 133 * curr_bitstream_show() - Show the current bitstream id 134 * 135 * There is a bug in some old versions of the CPLD which selects the 136 * bitstream, which causes the IO_SLU_BITSTREAM register to report 137 * unreliable data in very rare cases. This makes this sysfs 138 * unreliable up to the point were a new CPLD version is being used. 139 * 140 * Unfortunately there is no automatic way yet to query the CPLD 141 * version, such that you need to manually ensure via programming 142 * tools that you have a recent version of the CPLD software. 143 * 144 * The proposed circumvention is to use a special recovery bitstream 145 * on the backup partition (0) to identify problems while loading the 146 * image. 147 */ 148static ssize_t curr_bitstream_show(struct device *dev, 149 struct device_attribute *attr, char *buf) 150{ 151 int curr_bitstream; 152 struct genwqe_dev *cd = dev_get_drvdata(dev); 153 154 curr_bitstream = __genwqe_readq(cd, IO_SLU_BITSTREAM) & 0x1; 155 return sprintf(buf, "%d\n", curr_bitstream); 156} 157static DEVICE_ATTR_RO(curr_bitstream); 158 159/* 160 * next_bitstream_show() - Show the next activated bitstream 161 * 162 * IO_SLC_CFGREG_SOFTRESET: This register can only be accessed by the PF. 163 */ 164static ssize_t next_bitstream_show(struct device *dev, 165 struct device_attribute *attr, char *buf) 166{ 167 int next_bitstream; 168 struct genwqe_dev *cd = dev_get_drvdata(dev); 169 170 switch ((cd->softreset & 0xc) >> 2) { 171 case 0x2: 172 next_bitstream = 0; 173 break; 174 case 0x3: 175 next_bitstream = 1; 176 break; 177 default: 178 next_bitstream = -1; 179 break; /* error */ 180 } 181 return sprintf(buf, "%d\n", next_bitstream); 182} 183 184static ssize_t next_bitstream_store(struct device *dev, 185 struct device_attribute *attr, 186 const char *buf, size_t count) 187{ 188 int partition; 189 struct genwqe_dev *cd = dev_get_drvdata(dev); 190 191 if (kstrtoint(buf, 0, &partition) < 0) 192 return -EINVAL; 193 194 switch (partition) { 195 case 0x0: 196 cd->softreset = 0x78; 197 break; 198 case 0x1: 199 cd->softreset = 0x7c; 200 break; 201 default: 202 return -EINVAL; 203 } 204 205 __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, cd->softreset); 206 return count; 207} 208static DEVICE_ATTR_RW(next_bitstream); 209 210static ssize_t reload_bitstream_store(struct device *dev, 211 struct device_attribute *attr, 212 const char *buf, size_t count) 213{ 214 int reload; 215 struct genwqe_dev *cd = dev_get_drvdata(dev); 216 217 if (kstrtoint(buf, 0, &reload) < 0) 218 return -EINVAL; 219 220 if (reload == 0x1) { 221 if (cd->card_state == GENWQE_CARD_UNUSED || 222 cd->card_state == GENWQE_CARD_USED) 223 cd->card_state = GENWQE_CARD_RELOAD_BITSTREAM; 224 else 225 return -EIO; 226 } else { 227 return -EINVAL; 228 } 229 230 return count; 231} 232static DEVICE_ATTR_WO(reload_bitstream); 233 234/* 235 * Create device_attribute structures / params: name, mode, show, store 236 * additional flag if valid in VF 237 */ 238static struct attribute *genwqe_attributes[] = { 239 &dev_attr_tempsens.attr, 240 &dev_attr_next_bitstream.attr, 241 &dev_attr_curr_bitstream.attr, 242 &dev_attr_base_clock.attr, 243 &dev_attr_type.attr, 244 &dev_attr_version.attr, 245 &dev_attr_appid.attr, 246 &dev_attr_status.attr, 247 &dev_attr_freerunning_timer.attr, 248 &dev_attr_queue_working_time.attr, 249 &dev_attr_reload_bitstream.attr, 250 NULL, 251}; 252 253static struct attribute *genwqe_normal_attributes[] = { 254 &dev_attr_type.attr, 255 &dev_attr_version.attr, 256 &dev_attr_appid.attr, 257 &dev_attr_status.attr, 258 &dev_attr_freerunning_timer.attr, 259 &dev_attr_queue_working_time.attr, 260 NULL, 261}; 262 263/* 264 * genwqe_is_visible() - Determine if sysfs attribute should be visible or not 265 * 266 * VFs have restricted mmio capabilities, so not all sysfs entries 267 * are allowed in VFs. 268 */ 269static umode_t genwqe_is_visible(struct kobject *kobj, 270 struct attribute *attr, int n) 271{ 272 unsigned int j; 273 struct device *dev = kobj_to_dev(kobj); 274 struct genwqe_dev *cd = dev_get_drvdata(dev); 275 umode_t mode = attr->mode; 276 277 if (genwqe_is_privileged(cd)) 278 return mode; 279 280 for (j = 0; genwqe_normal_attributes[j] != NULL; j++) 281 if (genwqe_normal_attributes[j] == attr) 282 return mode; 283 284 return 0; 285} 286 287static struct attribute_group genwqe_attribute_group = { 288 .is_visible = genwqe_is_visible, 289 .attrs = genwqe_attributes, 290}; 291 292const struct attribute_group *genwqe_attribute_groups[] = { 293 &genwqe_attribute_group, 294 NULL, 295};