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 ret = adf_dev_down(accel_dev, true); 56 if (ret < 0) 57 return -EINVAL; 58 59 break; 60 case DEV_UP: 61 dev_info(dev, "Starting device qat_dev%d\n", accel_id); 62 63 ret = adf_dev_up(accel_dev, true); 64 if (ret < 0) { 65 dev_err(dev, "Failed to start device qat_dev%d\n", 66 accel_id); 67 adf_dev_down(accel_dev, true); 68 return ret; 69 } 70 break; 71 default: 72 return -EINVAL; 73 } 74 75 return count; 76 } 77 78 static const char * const services_operations[] = { 79 ADF_CFG_CY, 80 ADF_CFG_DC, 81 ADF_CFG_SYM, 82 ADF_CFG_ASYM, 83 ADF_CFG_ASYM_SYM, 84 ADF_CFG_ASYM_DC, 85 ADF_CFG_DC_ASYM, 86 ADF_CFG_SYM_DC, 87 ADF_CFG_DC_SYM, 88 }; 89 90 static 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 109 static 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 117 static 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(services_operations, 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, services_operations[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 the 146 * moment, tied to configuration 147 */ 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 155 static DEVICE_ATTR_RW(state); 156 static DEVICE_ATTR_RW(cfg_services); 157 158 static struct attribute *qat_attrs[] = { 159 &dev_attr_state.attr, 160 &dev_attr_cfg_services.attr, 161 NULL, 162 }; 163 164 static struct attribute_group qat_group = { 165 .attrs = qat_attrs, 166 .name = "qat", 167 }; 168 169 int adf_sysfs_init(struct adf_accel_dev *accel_dev) 170 { 171 int ret; 172 173 ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_group); 174 if (ret) { 175 dev_err(&GET_DEV(accel_dev), 176 "Failed to create qat attribute group: %d\n", ret); 177 } 178 179 return ret; 180 } 181 EXPORT_SYMBOL_GPL(adf_sysfs_init); 182