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