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_common_drv.h" 9 10 static const char * const state_operations[] = { 11 [DEV_DOWN] = "down", 12 [DEV_UP] = "up", 13 }; 14 15 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 16 char *buf) 17 { 18 struct adf_accel_dev *accel_dev; 19 char *state; 20 21 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 22 if (!accel_dev) 23 return -EINVAL; 24 25 state = adf_dev_started(accel_dev) ? "up" : "down"; 26 return sysfs_emit(buf, "%s\n", state); 27 } 28 29 static ssize_t state_store(struct device *dev, struct device_attribute *attr, 30 const char *buf, size_t count) 31 { 32 struct adf_accel_dev *accel_dev; 33 u32 accel_id; 34 int ret; 35 36 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 37 if (!accel_dev) 38 return -EINVAL; 39 40 accel_id = accel_dev->accel_id; 41 42 if (adf_devmgr_in_reset(accel_dev) || adf_dev_in_use(accel_dev)) { 43 dev_info(dev, "Device qat_dev%d is busy\n", accel_id); 44 return -EBUSY; 45 } 46 47 ret = sysfs_match_string(state_operations, buf); 48 if (ret < 0) 49 return ret; 50 51 switch (ret) { 52 case DEV_DOWN: 53 dev_info(dev, "Stopping device qat_dev%d\n", accel_id); 54 55 if (!adf_dev_started(accel_dev)) { 56 dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n", 57 accel_id); 58 59 break; 60 } 61 62 ret = adf_dev_down(accel_dev, true); 63 if (ret < 0) 64 return -EINVAL; 65 66 break; 67 case DEV_UP: 68 dev_info(dev, "Starting device qat_dev%d\n", accel_id); 69 70 ret = adf_dev_up(accel_dev, true); 71 if (ret < 0) { 72 dev_err(dev, "Failed to start device qat_dev%d\n", 73 accel_id); 74 adf_dev_down(accel_dev, true); 75 return ret; 76 } 77 break; 78 default: 79 return -EINVAL; 80 } 81 82 return count; 83 } 84 85 static const char * const services_operations[] = { 86 ADF_CFG_CY, 87 ADF_CFG_DC, 88 ADF_CFG_SYM, 89 ADF_CFG_ASYM, 90 ADF_CFG_ASYM_SYM, 91 ADF_CFG_ASYM_DC, 92 ADF_CFG_DC_ASYM, 93 ADF_CFG_SYM_DC, 94 ADF_CFG_DC_SYM, 95 }; 96 97 static ssize_t cfg_services_show(struct device *dev, struct device_attribute *attr, 98 char *buf) 99 { 100 char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; 101 struct adf_accel_dev *accel_dev; 102 int ret; 103 104 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 105 if (!accel_dev) 106 return -EINVAL; 107 108 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, 109 ADF_SERVICES_ENABLED, services); 110 if (ret) 111 return ret; 112 113 return sysfs_emit(buf, "%s\n", services); 114 } 115 116 static int adf_sysfs_update_dev_config(struct adf_accel_dev *accel_dev, 117 const char *services) 118 { 119 return adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, 120 ADF_SERVICES_ENABLED, services, 121 ADF_STR); 122 } 123 124 static ssize_t cfg_services_store(struct device *dev, struct device_attribute *attr, 125 const char *buf, size_t count) 126 { 127 struct adf_hw_device_data *hw_data; 128 struct adf_accel_dev *accel_dev; 129 int ret; 130 131 ret = sysfs_match_string(services_operations, buf); 132 if (ret < 0) 133 return ret; 134 135 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 136 if (!accel_dev) 137 return -EINVAL; 138 139 if (adf_dev_started(accel_dev)) { 140 dev_info(dev, "Device qat_dev%d must be down to reconfigure the service.\n", 141 accel_dev->accel_id); 142 return -EINVAL; 143 } 144 145 ret = adf_sysfs_update_dev_config(accel_dev, services_operations[ret]); 146 if (ret < 0) 147 return ret; 148 149 hw_data = GET_HW_DATA(accel_dev); 150 151 /* Update capabilities mask after change in configuration. 152 * A call to this function is required as capabilities are, at the 153 * moment, tied to configuration 154 */ 155 hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev); 156 if (!hw_data->accel_capabilities_mask) 157 return -EINVAL; 158 159 return count; 160 } 161 162 static ssize_t pm_idle_enabled_show(struct device *dev, struct device_attribute *attr, 163 char *buf) 164 { 165 char pm_idle_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {}; 166 struct adf_accel_dev *accel_dev; 167 int ret; 168 169 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 170 if (!accel_dev) 171 return -EINVAL; 172 173 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, 174 ADF_PM_IDLE_SUPPORT, pm_idle_enabled); 175 if (ret) 176 return sysfs_emit(buf, "1\n"); 177 178 return sysfs_emit(buf, "%s\n", pm_idle_enabled); 179 } 180 181 static ssize_t pm_idle_enabled_store(struct device *dev, struct device_attribute *attr, 182 const char *buf, size_t count) 183 { 184 unsigned long pm_idle_enabled_cfg_val; 185 struct adf_accel_dev *accel_dev; 186 bool pm_idle_enabled; 187 int ret; 188 189 ret = kstrtobool(buf, &pm_idle_enabled); 190 if (ret) 191 return ret; 192 193 pm_idle_enabled_cfg_val = pm_idle_enabled; 194 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 195 if (!accel_dev) 196 return -EINVAL; 197 198 if (adf_dev_started(accel_dev)) { 199 dev_info(dev, "Device qat_dev%d must be down to set pm_idle_enabled.\n", 200 accel_dev->accel_id); 201 return -EINVAL; 202 } 203 204 ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, 205 ADF_PM_IDLE_SUPPORT, &pm_idle_enabled_cfg_val, 206 ADF_DEC); 207 if (ret) 208 return ret; 209 210 return count; 211 } 212 static DEVICE_ATTR_RW(pm_idle_enabled); 213 214 static DEVICE_ATTR_RW(state); 215 static DEVICE_ATTR_RW(cfg_services); 216 217 static struct attribute *qat_attrs[] = { 218 &dev_attr_state.attr, 219 &dev_attr_cfg_services.attr, 220 &dev_attr_pm_idle_enabled.attr, 221 NULL, 222 }; 223 224 static struct attribute_group qat_group = { 225 .attrs = qat_attrs, 226 .name = "qat", 227 }; 228 229 int adf_sysfs_init(struct adf_accel_dev *accel_dev) 230 { 231 int ret; 232 233 ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_group); 234 if (ret) { 235 dev_err(&GET_DEV(accel_dev), 236 "Failed to create qat attribute group: %d\n", ret); 237 } 238 239 return ret; 240 } 241 EXPORT_SYMBOL_GPL(adf_sysfs_init); 242