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