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