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(devlink: 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(devlink: 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(devlink: 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(mbox: &cptpf->afpf_mbox, pdev, CPT_AF_CTL, val: ®_val, |
41 | blkaddr: 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(devlink: 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(mbox: &cptpf->afpf_mbox, pdev, CPT_AF_CTL, |
60 | val: ®_val, blkaddr: BLKADDR_CPT0); |
61 | reg_val &= ~(0x1ULL << 18); |
62 | reg_val |= ((u64)ctx->val.vu8 & 0x1) << 18; |
63 | return otx2_cpt_write_af_reg(mbox: &cptpf->afpf_mbox, pdev, |
64 | CPT_AF_CTL, val: reg_val, blkaddr: 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(eng_grp: &grp[i], eng_type); |
104 | if (eng) |
105 | return devlink_info_version_running_put(req, version_name: ver_name, |
106 | version_value: 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(devlink: dl); |
117 | struct otx2_cptpf_dev *cptpf = cpt_dl->cptpf; |
118 | int err; |
119 | |
120 | err = otx2_cpt_dl_info_firmware_version_put(req, grp: cptpf->eng_grps.grp, |
121 | ver_name: "fw.ae" , eng_type: OTX2_CPT_AE_TYPES); |
122 | if (err) |
123 | return err; |
124 | |
125 | err = otx2_cpt_dl_info_firmware_version_put(req, grp: cptpf->eng_grps.grp, |
126 | ver_name: "fw.se" , eng_type: OTX2_CPT_SE_TYPES); |
127 | if (err) |
128 | return err; |
129 | |
130 | return otx2_cpt_dl_info_firmware_version_put(req, grp: cptpf->eng_grps.grp, |
131 | ver_name: "fw.ie" , eng_type: 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(ops: &otx2_cpt_devlink_ops, |
146 | priv_size: 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(devlink: dl); |
153 | cpt_dl->dl = dl; |
154 | cpt_dl->cptpf = cptpf; |
155 | cptpf->dl = dl; |
156 | ret = devlink_params_register(devlink: dl, params: 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(devlink: dl); |
162 | return ret; |
163 | } |
164 | devlink_register(devlink: 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(devlink: dl); |
177 | devlink_params_unregister(devlink: dl, params: otx2_cpt_dl_params, |
178 | ARRAY_SIZE(otx2_cpt_dl_params)); |
179 | devlink_free(devlink: dl); |
180 | } |
181 | |