1*fb98254aSJunyuan Wang // SPDX-License-Identifier: GPL-2.0-only 2*fb98254aSJunyuan Wang /* Copyright(c) 2026 Intel Corporation */ 3*fb98254aSJunyuan Wang #include <linux/sysfs.h> 4*fb98254aSJunyuan Wang #include <linux/types.h> 5*fb98254aSJunyuan Wang 6*fb98254aSJunyuan Wang #include "adf_cfg.h" 7*fb98254aSJunyuan Wang #include "adf_cfg_services.h" 8*fb98254aSJunyuan Wang #include "adf_common_drv.h" 9*fb98254aSJunyuan Wang #include "adf_kpt.h" 10*fb98254aSJunyuan Wang #include "adf_sysfs_kpt.h" 11*fb98254aSJunyuan Wang 12*fb98254aSJunyuan Wang static ssize_t enable_show(struct device *dev, struct device_attribute *attr, 13*fb98254aSJunyuan Wang char *buf) 14*fb98254aSJunyuan Wang { 15*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 16*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 17*fb98254aSJunyuan Wang 18*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 19*fb98254aSJunyuan Wang if (!accel_dev) 20*fb98254aSJunyuan Wang return -EINVAL; 21*fb98254aSJunyuan Wang 22*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 23*fb98254aSJunyuan Wang 24*fb98254aSJunyuan Wang return sysfs_emit(buf, "%d\n", user_data->enable); 25*fb98254aSJunyuan Wang } 26*fb98254aSJunyuan Wang 27*fb98254aSJunyuan Wang static ssize_t enable_store(struct device *dev, struct device_attribute *attr, 28*fb98254aSJunyuan Wang const char *buf, size_t count) 29*fb98254aSJunyuan Wang { 30*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 31*fb98254aSJunyuan Wang struct adf_hw_device_data *hw_data; 32*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 33*fb98254aSJunyuan Wang bool enable; 34*fb98254aSJunyuan Wang int ret; 35*fb98254aSJunyuan Wang 36*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 37*fb98254aSJunyuan Wang if (!accel_dev) 38*fb98254aSJunyuan Wang return -EINVAL; 39*fb98254aSJunyuan Wang 40*fb98254aSJunyuan Wang if (adf_dev_started(accel_dev)) { 41*fb98254aSJunyuan Wang dev_info(dev, "Device qat_dev%d must be down before enabling KPT\n", 42*fb98254aSJunyuan Wang accel_dev->accel_id); 43*fb98254aSJunyuan Wang return -EINVAL; 44*fb98254aSJunyuan Wang } 45*fb98254aSJunyuan Wang 46*fb98254aSJunyuan Wang if (adf_get_service_enabled(accel_dev) != SVC_ASYM) { 47*fb98254aSJunyuan Wang dev_info(dev, "KPT can only be enabled when the asymmetric service is enabled\n"); 48*fb98254aSJunyuan Wang return -EINVAL; 49*fb98254aSJunyuan Wang } 50*fb98254aSJunyuan Wang 51*fb98254aSJunyuan Wang hw_data = GET_HW_DATA(accel_dev); 52*fb98254aSJunyuan Wang 53*fb98254aSJunyuan Wang /* 54*fb98254aSJunyuan Wang * Restore the KPT capability bit in the device's capabilities mask 55*fb98254aSJunyuan Wang * before processing user input, as the bit may have been cleared if 56*fb98254aSJunyuan Wang * KPT was previously disabled by the user. 57*fb98254aSJunyuan Wang */ 58*fb98254aSJunyuan Wang hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev); 59*fb98254aSJunyuan Wang if (!hw_data->accel_capabilities_mask) 60*fb98254aSJunyuan Wang return -EINVAL; 61*fb98254aSJunyuan Wang 62*fb98254aSJunyuan Wang ret = kstrtobool(buf, &enable); 63*fb98254aSJunyuan Wang if (ret) 64*fb98254aSJunyuan Wang return ret; 65*fb98254aSJunyuan Wang 66*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 67*fb98254aSJunyuan Wang user_data->enable = enable; 68*fb98254aSJunyuan Wang 69*fb98254aSJunyuan Wang return count; 70*fb98254aSJunyuan Wang } 71*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(enable); 72*fb98254aSJunyuan Wang 73*fb98254aSJunyuan Wang static ssize_t swk_shared_show(struct device *dev, 74*fb98254aSJunyuan Wang struct device_attribute *attr, char *buf) 75*fb98254aSJunyuan Wang { 76*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 77*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 78*fb98254aSJunyuan Wang 79*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 80*fb98254aSJunyuan Wang if (!accel_dev) 81*fb98254aSJunyuan Wang return -EINVAL; 82*fb98254aSJunyuan Wang 83*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 84*fb98254aSJunyuan Wang 85*fb98254aSJunyuan Wang return sysfs_emit(buf, "%d\n", user_data->swk_shared); 86*fb98254aSJunyuan Wang } 87*fb98254aSJunyuan Wang 88*fb98254aSJunyuan Wang static ssize_t swk_shared_store(struct device *dev, struct device_attribute *attr, 89*fb98254aSJunyuan Wang const char *buf, size_t count) 90*fb98254aSJunyuan Wang { 91*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 92*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 93*fb98254aSJunyuan Wang bool swk_shared; 94*fb98254aSJunyuan Wang int ret; 95*fb98254aSJunyuan Wang 96*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 97*fb98254aSJunyuan Wang if (!accel_dev) 98*fb98254aSJunyuan Wang return -EINVAL; 99*fb98254aSJunyuan Wang 100*fb98254aSJunyuan Wang if (adf_dev_started(accel_dev)) { 101*fb98254aSJunyuan Wang dev_info(dev, "Device qat_dev%d must be down before setting swk_shared\n", 102*fb98254aSJunyuan Wang accel_dev->accel_id); 103*fb98254aSJunyuan Wang return -EINVAL; 104*fb98254aSJunyuan Wang } 105*fb98254aSJunyuan Wang 106*fb98254aSJunyuan Wang ret = kstrtobool(buf, &swk_shared); 107*fb98254aSJunyuan Wang if (ret) 108*fb98254aSJunyuan Wang return ret; 109*fb98254aSJunyuan Wang 110*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 111*fb98254aSJunyuan Wang user_data->swk_shared = swk_shared; 112*fb98254aSJunyuan Wang 113*fb98254aSJunyuan Wang return count; 114*fb98254aSJunyuan Wang } 115*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_shared); 116*fb98254aSJunyuan Wang 117*fb98254aSJunyuan Wang static ssize_t swk_max_ttl_show(struct device *dev, struct device_attribute *attr, 118*fb98254aSJunyuan Wang char *buf) 119*fb98254aSJunyuan Wang { 120*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 121*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 122*fb98254aSJunyuan Wang 123*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 124*fb98254aSJunyuan Wang if (!accel_dev) 125*fb98254aSJunyuan Wang return -EINVAL; 126*fb98254aSJunyuan Wang 127*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 128*fb98254aSJunyuan Wang 129*fb98254aSJunyuan Wang return sysfs_emit(buf, "%u\n", user_data->swk_max_ttl); 130*fb98254aSJunyuan Wang } 131*fb98254aSJunyuan Wang 132*fb98254aSJunyuan Wang static ssize_t swk_max_ttl_store(struct device *dev, struct device_attribute *attr, 133*fb98254aSJunyuan Wang const char *buf, size_t count) 134*fb98254aSJunyuan Wang { 135*fb98254aSJunyuan Wang struct adf_kpt_hw_data *kpt_data; 136*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 137*fb98254aSJunyuan Wang unsigned int swk_max_ttl; 138*fb98254aSJunyuan Wang int ret; 139*fb98254aSJunyuan Wang 140*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 141*fb98254aSJunyuan Wang if (!accel_dev) 142*fb98254aSJunyuan Wang return -EINVAL; 143*fb98254aSJunyuan Wang 144*fb98254aSJunyuan Wang if (adf_dev_started(accel_dev)) { 145*fb98254aSJunyuan Wang dev_info(dev, "Device qat_dev%d must be down before setting swk_max_ttl\n", 146*fb98254aSJunyuan Wang accel_dev->accel_id); 147*fb98254aSJunyuan Wang return -EINVAL; 148*fb98254aSJunyuan Wang } 149*fb98254aSJunyuan Wang 150*fb98254aSJunyuan Wang ret = kstrtouint(buf, 10, &swk_max_ttl); 151*fb98254aSJunyuan Wang if (ret) 152*fb98254aSJunyuan Wang return ret; 153*fb98254aSJunyuan Wang 154*fb98254aSJunyuan Wang kpt_data = GET_KPT_CFG_DATA(accel_dev); 155*fb98254aSJunyuan Wang 156*fb98254aSJunyuan Wang if (swk_max_ttl > kpt_data->max_swk_ttl) { 157*fb98254aSJunyuan Wang dev_info(dev, "Configuration value is out of range (%u - %u)\n", 158*fb98254aSJunyuan Wang 0, kpt_data->max_swk_ttl); 159*fb98254aSJunyuan Wang return -EINVAL; 160*fb98254aSJunyuan Wang } 161*fb98254aSJunyuan Wang 162*fb98254aSJunyuan Wang kpt_data->user_input.swk_max_ttl = swk_max_ttl; 163*fb98254aSJunyuan Wang 164*fb98254aSJunyuan Wang return count; 165*fb98254aSJunyuan Wang } 166*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_max_ttl); 167*fb98254aSJunyuan Wang 168*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_fn_show(struct device *dev, struct device_attribute *attr, 169*fb98254aSJunyuan Wang char *buf) 170*fb98254aSJunyuan Wang { 171*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 172*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 173*fb98254aSJunyuan Wang 174*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 175*fb98254aSJunyuan Wang if (!accel_dev) 176*fb98254aSJunyuan Wang return -EINVAL; 177*fb98254aSJunyuan Wang 178*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 179*fb98254aSJunyuan Wang 180*fb98254aSJunyuan Wang return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_fn); 181*fb98254aSJunyuan Wang } 182*fb98254aSJunyuan Wang 183*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_fn_store(struct device *dev, struct device_attribute *attr, 184*fb98254aSJunyuan Wang const char *buf, size_t count) 185*fb98254aSJunyuan Wang { 186*fb98254aSJunyuan Wang struct adf_kpt_hw_data *kpt_data; 187*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 188*fb98254aSJunyuan Wang unsigned int swk_cnt_per_fn; 189*fb98254aSJunyuan Wang int ret; 190*fb98254aSJunyuan Wang 191*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 192*fb98254aSJunyuan Wang if (!accel_dev) 193*fb98254aSJunyuan Wang return -EINVAL; 194*fb98254aSJunyuan Wang 195*fb98254aSJunyuan Wang if (adf_dev_started(accel_dev)) { 196*fb98254aSJunyuan Wang dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_fn\n", 197*fb98254aSJunyuan Wang accel_dev->accel_id); 198*fb98254aSJunyuan Wang return -EINVAL; 199*fb98254aSJunyuan Wang } 200*fb98254aSJunyuan Wang 201*fb98254aSJunyuan Wang ret = kstrtouint(buf, 10, &swk_cnt_per_fn); 202*fb98254aSJunyuan Wang if (ret) 203*fb98254aSJunyuan Wang return ret; 204*fb98254aSJunyuan Wang 205*fb98254aSJunyuan Wang kpt_data = GET_KPT_CFG_DATA(accel_dev); 206*fb98254aSJunyuan Wang 207*fb98254aSJunyuan Wang if (swk_cnt_per_fn > kpt_data->max_swk_cnt_per_fn_pasid) { 208*fb98254aSJunyuan Wang dev_info(dev, "swk_cnt_per_fn: value out of range (0 - %u)\n", 209*fb98254aSJunyuan Wang kpt_data->max_swk_cnt_per_fn_pasid); 210*fb98254aSJunyuan Wang return -EINVAL; 211*fb98254aSJunyuan Wang } 212*fb98254aSJunyuan Wang 213*fb98254aSJunyuan Wang kpt_data->user_input.swk_cnt_per_fn = swk_cnt_per_fn; 214*fb98254aSJunyuan Wang 215*fb98254aSJunyuan Wang return count; 216*fb98254aSJunyuan Wang } 217*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_cnt_per_fn); 218*fb98254aSJunyuan Wang 219*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_pasid_show(struct device *dev, struct device_attribute *attr, 220*fb98254aSJunyuan Wang char *buf) 221*fb98254aSJunyuan Wang { 222*fb98254aSJunyuan Wang struct adf_kpt_interface_data *user_data; 223*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 224*fb98254aSJunyuan Wang 225*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 226*fb98254aSJunyuan Wang if (!accel_dev) 227*fb98254aSJunyuan Wang return -EINVAL; 228*fb98254aSJunyuan Wang 229*fb98254aSJunyuan Wang user_data = GET_KPT_USER_DATA(accel_dev); 230*fb98254aSJunyuan Wang 231*fb98254aSJunyuan Wang return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_pasid); 232*fb98254aSJunyuan Wang } 233*fb98254aSJunyuan Wang 234*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_pasid_store(struct device *dev, struct device_attribute *attr, 235*fb98254aSJunyuan Wang const char *buf, size_t count) 236*fb98254aSJunyuan Wang { 237*fb98254aSJunyuan Wang struct adf_kpt_hw_data *kpt_data; 238*fb98254aSJunyuan Wang struct adf_accel_dev *accel_dev; 239*fb98254aSJunyuan Wang unsigned int swk_cnt_per_pasid; 240*fb98254aSJunyuan Wang int ret; 241*fb98254aSJunyuan Wang 242*fb98254aSJunyuan Wang accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); 243*fb98254aSJunyuan Wang if (!accel_dev) 244*fb98254aSJunyuan Wang return -EINVAL; 245*fb98254aSJunyuan Wang 246*fb98254aSJunyuan Wang if (adf_dev_started(accel_dev)) { 247*fb98254aSJunyuan Wang dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_pasid\n", 248*fb98254aSJunyuan Wang accel_dev->accel_id); 249*fb98254aSJunyuan Wang return -EINVAL; 250*fb98254aSJunyuan Wang } 251*fb98254aSJunyuan Wang 252*fb98254aSJunyuan Wang ret = kstrtouint(buf, 10, &swk_cnt_per_pasid); 253*fb98254aSJunyuan Wang if (ret) 254*fb98254aSJunyuan Wang return ret; 255*fb98254aSJunyuan Wang 256*fb98254aSJunyuan Wang kpt_data = GET_KPT_CFG_DATA(accel_dev); 257*fb98254aSJunyuan Wang 258*fb98254aSJunyuan Wang if (swk_cnt_per_pasid > kpt_data->max_swk_cnt_per_fn_pasid) { 259*fb98254aSJunyuan Wang dev_info(dev, "swk_cnt_per_pasid: value out of range (0 - %u)\n", 260*fb98254aSJunyuan Wang kpt_data->max_swk_cnt_per_fn_pasid); 261*fb98254aSJunyuan Wang return -EINVAL; 262*fb98254aSJunyuan Wang } 263*fb98254aSJunyuan Wang 264*fb98254aSJunyuan Wang kpt_data->user_input.swk_cnt_per_pasid = swk_cnt_per_pasid; 265*fb98254aSJunyuan Wang 266*fb98254aSJunyuan Wang return count; 267*fb98254aSJunyuan Wang } 268*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_cnt_per_pasid); 269*fb98254aSJunyuan Wang 270*fb98254aSJunyuan Wang static struct attribute *qat_kpt_attrs[] = { 271*fb98254aSJunyuan Wang &dev_attr_enable.attr, 272*fb98254aSJunyuan Wang &dev_attr_swk_shared.attr, 273*fb98254aSJunyuan Wang &dev_attr_swk_max_ttl.attr, 274*fb98254aSJunyuan Wang &dev_attr_swk_cnt_per_fn.attr, 275*fb98254aSJunyuan Wang &dev_attr_swk_cnt_per_pasid.attr, 276*fb98254aSJunyuan Wang NULL, 277*fb98254aSJunyuan Wang }; 278*fb98254aSJunyuan Wang 279*fb98254aSJunyuan Wang static const struct attribute_group qat_kpt_group = { 280*fb98254aSJunyuan Wang .attrs = qat_kpt_attrs, 281*fb98254aSJunyuan Wang .name = "qat_kpt", 282*fb98254aSJunyuan Wang }; 283*fb98254aSJunyuan Wang 284*fb98254aSJunyuan Wang int adf_sysfs_init_kpt(struct adf_accel_dev *accel_dev) 285*fb98254aSJunyuan Wang { 286*fb98254aSJunyuan Wang int ret; 287*fb98254aSJunyuan Wang 288*fb98254aSJunyuan Wang ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_kpt_group); 289*fb98254aSJunyuan Wang if (ret) { 290*fb98254aSJunyuan Wang dev_err(&GET_DEV(accel_dev), "Failed to create qat_kpt attribute group\n"); 291*fb98254aSJunyuan Wang return ret; 292*fb98254aSJunyuan Wang } 293*fb98254aSJunyuan Wang 294*fb98254aSJunyuan Wang return 0; 295*fb98254aSJunyuan Wang } 296*fb98254aSJunyuan Wang EXPORT_SYMBOL_GPL(adf_sysfs_init_kpt); 297