1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2021 Marvell. */ 3 4 #include "otx2_cpt_devlink.h" 5 6 static int otx2_cpt_dl_egrp_create(struct devlink *dl, u32 id, 7 struct devlink_param_gset_ctx *ctx) 8 { 9 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 10 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; 11 12 return otx2_cpt_dl_custom_egrp_create(cptpf, ctx); 13 } 14 15 static int otx2_cpt_dl_egrp_delete(struct devlink *dl, u32 id, 16 struct devlink_param_gset_ctx *ctx) 17 { 18 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 19 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; 20 21 return otx2_cpt_dl_custom_egrp_delete(cptpf, ctx); 22 } 23 24 static int otx2_cpt_dl_uc_info(struct devlink *dl, u32 id, 25 struct devlink_param_gset_ctx *ctx) 26 { 27 ctx->val.vstr[0] = '\0'; 28 29 return 0; 30 } 31 32 static int otx2_cpt_dl_t106_mode_get(struct devlink *dl, u32 id, 33 struct devlink_param_gset_ctx *ctx) 34 { 35 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 36 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; 37 struct pci_dev *pdev = cptpf->pdev; 38 u64 reg_val = 0; 39 40 otx2_cpt_read_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTL, ®_val, 41 BLKADDR_CPT0); 42 ctx->val.vu8 = (reg_val >> 18) & 0x1; 43 44 return 0; 45 } 46 47 static int otx2_cpt_dl_t106_mode_set(struct devlink *dl, u32 id, 48 struct devlink_param_gset_ctx *ctx) 49 { 50 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 51 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; 52 struct pci_dev *pdev = cptpf->pdev; 53 u64 reg_val = 0; 54 55 if (cptpf->enabled_vfs != 0 || cptpf->eng_grps.is_grps_created) 56 return -EPERM; 57 58 if (cpt_feature_sgv2(pdev)) { 59 otx2_cpt_read_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTL, 60 ®_val, BLKADDR_CPT0); 61 reg_val &= ~(0x1ULL << 18); 62 reg_val |= ((u64)ctx->val.vu8 & 0x1) << 18; 63 return otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, 64 CPT_AF_CTL, reg_val, BLKADDR_CPT0); 65 } 66 67 return 0; 68 } 69 70 enum otx2_cpt_dl_param_id { 71 OTX2_CPT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 72 OTX2_CPT_DEVLINK_PARAM_ID_EGRP_CREATE, 73 OTX2_CPT_DEVLINK_PARAM_ID_EGRP_DELETE, 74 OTX2_CPT_DEVLINK_PARAM_ID_T106_MODE, 75 }; 76 77 static const struct devlink_param otx2_cpt_dl_params[] = { 78 DEVLINK_PARAM_DRIVER(OTX2_CPT_DEVLINK_PARAM_ID_EGRP_CREATE, 79 "egrp_create", DEVLINK_PARAM_TYPE_STRING, 80 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 81 otx2_cpt_dl_uc_info, otx2_cpt_dl_egrp_create, 82 NULL), 83 DEVLINK_PARAM_DRIVER(OTX2_CPT_DEVLINK_PARAM_ID_EGRP_DELETE, 84 "egrp_delete", DEVLINK_PARAM_TYPE_STRING, 85 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 86 otx2_cpt_dl_uc_info, otx2_cpt_dl_egrp_delete, 87 NULL), 88 DEVLINK_PARAM_DRIVER(OTX2_CPT_DEVLINK_PARAM_ID_T106_MODE, 89 "t106_mode", DEVLINK_PARAM_TYPE_U8, 90 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 91 otx2_cpt_dl_t106_mode_get, otx2_cpt_dl_t106_mode_set, 92 NULL), 93 }; 94 95 static int otx2_cpt_dl_info_firmware_version_put(struct devlink_info_req *req, 96 struct otx2_cpt_eng_grp_info grp[], 97 const char *ver_name, int eng_type) 98 { 99 struct otx2_cpt_engs_rsvd *eng; 100 int i; 101 102 for (i = 0; i < OTX2_CPT_MAX_ENGINE_GROUPS; i++) { 103 eng = find_engines_by_type(&grp[i], eng_type); 104 if (eng) 105 return devlink_info_version_running_put(req, ver_name, 106 eng->ucode->ver_str); 107 } 108 109 return 0; 110 } 111 112 static int otx2_cpt_devlink_info_get(struct devlink *dl, 113 struct devlink_info_req *req, 114 struct netlink_ext_ack *extack) 115 { 116 struct otx2_cpt_devlink *cpt_dl = devlink_priv(dl); 117 struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; 118 int err; 119 120 err = otx2_cpt_dl_info_firmware_version_put(req, cptpf->eng_grps.grp, 121 "fw.ae", OTX2_CPT_AE_TYPES); 122 if (err) 123 return err; 124 125 err = otx2_cpt_dl_info_firmware_version_put(req, cptpf->eng_grps.grp, 126 "fw.se", OTX2_CPT_SE_TYPES); 127 if (err) 128 return err; 129 130 return otx2_cpt_dl_info_firmware_version_put(req, cptpf->eng_grps.grp, 131 "fw.ie", OTX2_CPT_IE_TYPES); 132 } 133 134 static const struct devlink_ops otx2_cpt_devlink_ops = { 135 .info_get = otx2_cpt_devlink_info_get, 136 }; 137 138 int otx2_cpt_register_dl(struct otx2_cptpf_dev *cptpf) 139 { 140 struct device *dev = &cptpf->pdev->dev; 141 struct otx2_cpt_devlink *cpt_dl; 142 struct devlink *dl; 143 int ret; 144 145 dl = devlink_alloc(&otx2_cpt_devlink_ops, 146 sizeof(struct otx2_cpt_devlink), dev); 147 if (!dl) { 148 dev_warn(dev, "devlink_alloc failed\n"); 149 return -ENOMEM; 150 } 151 152 cpt_dl = devlink_priv(dl); 153 cpt_dl->dl = dl; 154 cpt_dl->cptpf = cptpf; 155 cptpf->dl = dl; 156 ret = devlink_params_register(dl, otx2_cpt_dl_params, 157 ARRAY_SIZE(otx2_cpt_dl_params)); 158 if (ret) { 159 dev_err(dev, "devlink params register failed with error %d", 160 ret); 161 devlink_free(dl); 162 return ret; 163 } 164 devlink_register(dl); 165 166 return 0; 167 } 168 169 void otx2_cpt_unregister_dl(struct otx2_cptpf_dev *cptpf) 170 { 171 struct devlink *dl = cptpf->dl; 172 173 if (!dl) 174 return; 175 176 devlink_unregister(dl); 177 devlink_params_unregister(dl, otx2_cpt_dl_params, 178 ARRAY_SIZE(otx2_cpt_dl_params)); 179 devlink_free(dl); 180 } 181