354 lines · c
1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)2/* Copyright(c) 2022 Intel Corporation */3#include <linux/device.h>4#include <linux/errno.h>5#include <linux/pci.h>6#include "adf_accel_devices.h"7#include "adf_cfg.h"8#include "adf_cfg_services.h"9#include "adf_common_drv.h"10 11#define UNSET_RING_NUM -112 13static const char * const state_operations[] = {14 [DEV_DOWN] = "down",15 [DEV_UP] = "up",16};17 18static ssize_t state_show(struct device *dev, struct device_attribute *attr,19 char *buf)20{21 struct adf_accel_dev *accel_dev;22 char *state;23 24 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));25 if (!accel_dev)26 return -EINVAL;27 28 state = adf_dev_started(accel_dev) ? "up" : "down";29 return sysfs_emit(buf, "%s\n", state);30}31 32static ssize_t state_store(struct device *dev, struct device_attribute *attr,33 const char *buf, size_t count)34{35 struct adf_accel_dev *accel_dev;36 u32 accel_id;37 int ret;38 39 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));40 if (!accel_dev)41 return -EINVAL;42 43 accel_id = accel_dev->accel_id;44 45 if (adf_devmgr_in_reset(accel_dev) || adf_dev_in_use(accel_dev)) {46 dev_info(dev, "Device qat_dev%d is busy\n", accel_id);47 return -EBUSY;48 }49 50 ret = sysfs_match_string(state_operations, buf);51 if (ret < 0)52 return ret;53 54 switch (ret) {55 case DEV_DOWN:56 dev_info(dev, "Stopping device qat_dev%d\n", accel_id);57 58 if (!adf_dev_started(accel_dev)) {59 dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n",60 accel_id);61 62 break;63 }64 65 ret = adf_dev_down(accel_dev);66 if (ret)67 return ret;68 69 break;70 case DEV_UP:71 dev_info(dev, "Starting device qat_dev%d\n", accel_id);72 73 ret = adf_dev_up(accel_dev, true);74 if (ret == -EALREADY) {75 break;76 } else if (ret) {77 dev_err(dev, "Failed to start device qat_dev%d\n",78 accel_id);79 adf_dev_down(accel_dev);80 return ret;81 }82 break;83 default:84 return -EINVAL;85 }86 87 return count;88}89 90static ssize_t cfg_services_show(struct device *dev, struct device_attribute *attr,91 char *buf)92{93 char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};94 struct adf_accel_dev *accel_dev;95 int ret;96 97 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));98 if (!accel_dev)99 return -EINVAL;100 101 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,102 ADF_SERVICES_ENABLED, services);103 if (ret)104 return ret;105 106 return sysfs_emit(buf, "%s\n", services);107}108 109static int adf_sysfs_update_dev_config(struct adf_accel_dev *accel_dev,110 const char *services)111{112 return adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,113 ADF_SERVICES_ENABLED, services,114 ADF_STR);115}116 117static ssize_t cfg_services_store(struct device *dev, struct device_attribute *attr,118 const char *buf, size_t count)119{120 struct adf_hw_device_data *hw_data;121 struct adf_accel_dev *accel_dev;122 int ret;123 124 ret = sysfs_match_string(adf_cfg_services, buf);125 if (ret < 0)126 return ret;127 128 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));129 if (!accel_dev)130 return -EINVAL;131 132 if (adf_dev_started(accel_dev)) {133 dev_info(dev, "Device qat_dev%d must be down to reconfigure the service.\n",134 accel_dev->accel_id);135 return -EINVAL;136 }137 138 ret = adf_sysfs_update_dev_config(accel_dev, adf_cfg_services[ret]);139 if (ret < 0)140 return ret;141 142 hw_data = GET_HW_DATA(accel_dev);143 144 /* Update capabilities mask after change in configuration.145 * A call to this function is required as capabilities are, at the146 * moment, tied to configuration147 */148 hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);149 if (!hw_data->accel_capabilities_mask)150 return -EINVAL;151 152 return count;153}154 155static ssize_t pm_idle_enabled_show(struct device *dev, struct device_attribute *attr,156 char *buf)157{158 char pm_idle_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {};159 struct adf_accel_dev *accel_dev;160 int ret;161 162 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));163 if (!accel_dev)164 return -EINVAL;165 166 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,167 ADF_PM_IDLE_SUPPORT, pm_idle_enabled);168 if (ret)169 return sysfs_emit(buf, "1\n");170 171 return sysfs_emit(buf, "%s\n", pm_idle_enabled);172}173 174static ssize_t pm_idle_enabled_store(struct device *dev, struct device_attribute *attr,175 const char *buf, size_t count)176{177 unsigned long pm_idle_enabled_cfg_val;178 struct adf_accel_dev *accel_dev;179 bool pm_idle_enabled;180 int ret;181 182 ret = kstrtobool(buf, &pm_idle_enabled);183 if (ret)184 return ret;185 186 pm_idle_enabled_cfg_val = pm_idle_enabled;187 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));188 if (!accel_dev)189 return -EINVAL;190 191 if (adf_dev_started(accel_dev)) {192 dev_info(dev, "Device qat_dev%d must be down to set pm_idle_enabled.\n",193 accel_dev->accel_id);194 return -EINVAL;195 }196 197 ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,198 ADF_PM_IDLE_SUPPORT, &pm_idle_enabled_cfg_val,199 ADF_DEC);200 if (ret)201 return ret;202 203 return count;204}205static DEVICE_ATTR_RW(pm_idle_enabled);206 207static ssize_t auto_reset_show(struct device *dev, struct device_attribute *attr,208 char *buf)209{210 char *auto_reset;211 struct adf_accel_dev *accel_dev;212 213 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));214 if (!accel_dev)215 return -EINVAL;216 217 auto_reset = accel_dev->autoreset_on_error ? "on" : "off";218 219 return sysfs_emit(buf, "%s\n", auto_reset);220}221 222static ssize_t auto_reset_store(struct device *dev, struct device_attribute *attr,223 const char *buf, size_t count)224{225 struct adf_accel_dev *accel_dev;226 bool enabled = false;227 int ret;228 229 ret = kstrtobool(buf, &enabled);230 if (ret)231 return ret;232 233 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));234 if (!accel_dev)235 return -EINVAL;236 237 accel_dev->autoreset_on_error = enabled;238 239 return count;240}241static DEVICE_ATTR_RW(auto_reset);242 243static DEVICE_ATTR_RW(state);244static DEVICE_ATTR_RW(cfg_services);245 246static ssize_t rp2srv_show(struct device *dev, struct device_attribute *attr,247 char *buf)248{249 struct adf_hw_device_data *hw_data;250 struct adf_accel_dev *accel_dev;251 enum adf_cfg_service_type svc;252 253 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));254 if (!accel_dev)255 return -EINVAL;256 257 hw_data = GET_HW_DATA(accel_dev);258 259 if (accel_dev->sysfs.ring_num == UNSET_RING_NUM)260 return -EINVAL;261 262 down_read(&accel_dev->sysfs.lock);263 svc = GET_SRV_TYPE(accel_dev, accel_dev->sysfs.ring_num %264 hw_data->num_banks_per_vf);265 up_read(&accel_dev->sysfs.lock);266 267 switch (svc) {268 case COMP:269 return sysfs_emit(buf, "%s\n", ADF_CFG_DC);270 case SYM:271 return sysfs_emit(buf, "%s\n", ADF_CFG_SYM);272 case ASYM:273 return sysfs_emit(buf, "%s\n", ADF_CFG_ASYM);274 default:275 break;276 }277 return -EINVAL;278}279 280static ssize_t rp2srv_store(struct device *dev, struct device_attribute *attr,281 const char *buf, size_t count)282{283 struct adf_accel_dev *accel_dev;284 int num_rings, ret;285 unsigned int ring;286 287 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));288 if (!accel_dev)289 return -EINVAL;290 291 ret = kstrtouint(buf, 10, &ring);292 if (ret)293 return ret;294 295 num_rings = GET_MAX_BANKS(accel_dev);296 if (ring >= num_rings) {297 dev_err(&GET_DEV(accel_dev),298 "Device does not support more than %u ring pairs\n",299 num_rings);300 return -EINVAL;301 }302 303 down_write(&accel_dev->sysfs.lock);304 accel_dev->sysfs.ring_num = ring;305 up_write(&accel_dev->sysfs.lock);306 307 return count;308}309static DEVICE_ATTR_RW(rp2srv);310 311static ssize_t num_rps_show(struct device *dev, struct device_attribute *attr,312 char *buf)313{314 struct adf_accel_dev *accel_dev;315 316 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));317 if (!accel_dev)318 return -EINVAL;319 320 return sysfs_emit(buf, "%u\n", GET_MAX_BANKS(accel_dev));321}322static DEVICE_ATTR_RO(num_rps);323 324static struct attribute *qat_attrs[] = {325 &dev_attr_state.attr,326 &dev_attr_cfg_services.attr,327 &dev_attr_pm_idle_enabled.attr,328 &dev_attr_rp2srv.attr,329 &dev_attr_num_rps.attr,330 &dev_attr_auto_reset.attr,331 NULL,332};333 334static struct attribute_group qat_group = {335 .attrs = qat_attrs,336 .name = "qat",337};338 339int adf_sysfs_init(struct adf_accel_dev *accel_dev)340{341 int ret;342 343 ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_group);344 if (ret) {345 dev_err(&GET_DEV(accel_dev),346 "Failed to create qat attribute group: %d\n", ret);347 }348 349 accel_dev->sysfs.ring_num = UNSET_RING_NUM;350 351 return ret;352}353EXPORT_SYMBOL_GPL(adf_sysfs_init);354