devlink.c (4654ec6194b22af73c797508c72710e2e2bba4ad) devlink.c (6eae2aeb60b6f1cfa97e6e8f296027f15173a67a)
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2025, Intel Corporation. */
3
4#include "ixgbe.h"
5#include "devlink.h"
6
7struct ixgbe_info_ctx {
8 char buf[128];
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2025, Intel Corporation. */
3
4#include "ixgbe.h"
5#include "devlink.h"
6
7struct ixgbe_info_ctx {
8 char buf[128];
9 struct ixgbe_orom_info pending_orom;
10 struct ixgbe_nvm_info pending_nvm;
11 struct ixgbe_netlist_info pending_netlist;
12 struct ixgbe_hw_dev_caps dev_caps;
9};
10
13};
14
15enum ixgbe_devlink_version_type {
16 IXGBE_DL_VERSION_RUNNING,
17 IXGBE_DL_VERSION_STORED
18};
19
11static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
12 struct ixgbe_info_ctx *ctx)
13{
14 u8 dsn[8];
15
16 /* Copy the DSN into an array in Big Endian format */
17 put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn);
18
19 snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
20}
21
22static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter,
20static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
21 struct ixgbe_info_ctx *ctx)
22{
23 u8 dsn[8];
24
25 /* Copy the DSN into an array in Big Endian format */
26 put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn);
27
28 snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
29}
30
31static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter,
23 struct ixgbe_info_ctx *ctx)
32 struct ixgbe_info_ctx *ctx,
33 enum ixgbe_devlink_version_type type)
24{
25 struct ixgbe_hw *hw = &adapter->hw;
26 struct ixgbe_nvm_version nvm_ver;
27
28 ctx->buf[0] = '\0';
29
30 if (hw->mac.type == ixgbe_mac_e610) {
31 struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
32
34{
35 struct ixgbe_hw *hw = &adapter->hw;
36 struct ixgbe_nvm_version nvm_ver;
37
38 ctx->buf[0] = '\0';
39
40 if (hw->mac.type == ixgbe_mac_e610) {
41 struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
42
43 if (type == IXGBE_DL_VERSION_STORED &&
44 ctx->dev_caps.common_cap.nvm_update_pending_orom)
45 orom = &ctx->pending_orom;
46
33 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
34 orom->major, orom->build, orom->patch);
35 return;
36 }
37
38 ixgbe_get_oem_prod_version(hw, &nvm_ver);
39 if (nvm_ver.oem_valid) {
40 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",

--- 5 unchanged lines hidden (view full) ---

46
47 ixgbe_get_orom_version(hw, &nvm_ver);
48 if (nvm_ver.or_valid)
49 snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
50 nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
51}
52
53static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
47 snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
48 orom->major, orom->build, orom->patch);
49 return;
50 }
51
52 ixgbe_get_oem_prod_version(hw, &nvm_ver);
53 if (nvm_ver.oem_valid) {
54 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",

--- 5 unchanged lines hidden (view full) ---

60
61 ixgbe_get_orom_version(hw, &nvm_ver);
62 if (nvm_ver.or_valid)
63 snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
64 nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
65}
66
67static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
54 struct ixgbe_info_ctx *ctx)
68 struct ixgbe_info_ctx *ctx,
69 enum ixgbe_devlink_version_type type)
55{
56 struct ixgbe_hw *hw = &adapter->hw;
57 struct ixgbe_nvm_version nvm_ver;
58
59 if (hw->mac.type == ixgbe_mac_e610) {
70{
71 struct ixgbe_hw *hw = &adapter->hw;
72 struct ixgbe_nvm_version nvm_ver;
73
74 if (hw->mac.type == ixgbe_mac_e610) {
60 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x",
61 hw->flash.nvm.eetrack);
75 u32 eetrack = hw->flash.nvm.eetrack;
76
77 if (type == IXGBE_DL_VERSION_STORED &&
78 ctx->dev_caps.common_cap.nvm_update_pending_nvm)
79 eetrack = ctx->pending_nvm.eetrack;
80
81 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack);
62 return;
63 }
64
65 ixgbe_get_oem_prod_version(hw, &nvm_ver);
66
67 /* No ETRACK version for OEM */
68 if (nvm_ver.oem_valid) {
69 ctx->buf[0] = '\0';

--- 17 unchanged lines hidden (view full) ---

87 struct ixgbe_info_ctx *ctx)
88{
89 struct ixgbe_hw *hw = &adapter->hw;
90
91 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);
92}
93
94static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter,
82 return;
83 }
84
85 ixgbe_get_oem_prod_version(hw, &nvm_ver);
86
87 /* No ETRACK version for OEM */
88 if (nvm_ver.oem_valid) {
89 ctx->buf[0] = '\0';

--- 17 unchanged lines hidden (view full) ---

107 struct ixgbe_info_ctx *ctx)
108{
109 struct ixgbe_hw *hw = &adapter->hw;
110
111 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);
112}
113
114static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter,
95 struct ixgbe_info_ctx *ctx)
115 struct ixgbe_info_ctx *ctx,
116 enum ixgbe_devlink_version_type type)
96{
97 struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
98
117{
118 struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
119
120 if (type == IXGBE_DL_VERSION_STORED &&
121 ctx->dev_caps.common_cap.nvm_update_pending_nvm)
122 nvm = &ctx->pending_nvm;
123
99 snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
100}
101
102static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter,
124 snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
125}
126
127static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter,
103 struct ixgbe_info_ctx *ctx)
128 struct ixgbe_info_ctx *ctx,
129 enum ixgbe_devlink_version_type type)
104{
105 struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
106
130{
131 struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
132
133 if (type == IXGBE_DL_VERSION_STORED &&
134 ctx->dev_caps.common_cap.nvm_update_pending_orom)
135 orom = &ctx->pending_orom;
136
107 snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev);
108}
109
110static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
137 snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev);
138}
139
140static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
111 struct ixgbe_info_ctx *ctx)
141 struct ixgbe_info_ctx *ctx,
142 enum ixgbe_devlink_version_type type)
112{
113 struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
114
143{
144 struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
145
146 if (type == IXGBE_DL_VERSION_STORED &&
147 ctx->dev_caps.common_cap.nvm_update_pending_nvm)
148 nvm = &ctx->pending_nvm;
149
115 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);
116}
117
118static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter,
150 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);
151}
152
153static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter,
119 struct ixgbe_info_ctx *ctx)
154 struct ixgbe_info_ctx *ctx,
155 enum ixgbe_devlink_version_type type)
120{
121 struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
122
156{
157 struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
158
159 if (type == IXGBE_DL_VERSION_STORED &&
160 ctx->dev_caps.common_cap.nvm_update_pending_netlist)
161 netlist = &ctx->pending_netlist;
162
123 /* The netlist version fields are BCD formatted */
124 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",
125 netlist->major, netlist->minor,
126 netlist->type >> 16, netlist->type & 0xFFFF,
127 netlist->rev, netlist->cust_ver);
128}
129
130static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter,
163 /* The netlist version fields are BCD formatted */
164 snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",
165 netlist->major, netlist->minor,
166 netlist->type >> 16, netlist->type & 0xFFFF,
167 netlist->rev, netlist->cust_ver);
168}
169
170static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter,
131 struct ixgbe_info_ctx *ctx)
171 struct ixgbe_info_ctx *ctx,
172 enum ixgbe_devlink_version_type type)
132{
133 struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
134
173{
174 struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
175
176 if (type == IXGBE_DL_VERSION_STORED &&
177 ctx->dev_caps.common_cap.nvm_update_pending_netlist)
178 netlist = &ctx->pending_netlist;
179
135 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);
136}
137
180 snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);
181}
182
183static int ixgbe_set_ctx_dev_caps(struct ixgbe_hw *hw,
184 struct ixgbe_info_ctx *ctx,
185 struct netlink_ext_ack *extack)
186{
187 bool *pending_orom, *pending_nvm, *pending_netlist;
188 int err;
189
190 err = ixgbe_discover_dev_caps(hw, &ctx->dev_caps);
191 if (err) {
192 NL_SET_ERR_MSG_MOD(extack,
193 "Unable to discover device capabilities");
194 return err;
195 }
196
197 pending_orom = &ctx->dev_caps.common_cap.nvm_update_pending_orom;
198 pending_nvm = &ctx->dev_caps.common_cap.nvm_update_pending_nvm;
199 pending_netlist = &ctx->dev_caps.common_cap.nvm_update_pending_netlist;
200
201 if (*pending_orom) {
202 err = ixgbe_get_inactive_orom_ver(hw, &ctx->pending_orom);
203 if (err)
204 *pending_orom = false;
205 }
206
207 if (*pending_nvm) {
208 err = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm);
209 if (err)
210 *pending_nvm = false;
211 }
212
213 if (*pending_netlist) {
214 err = ixgbe_get_inactive_netlist_ver(hw, &ctx->pending_netlist);
215 if (err)
216 *pending_netlist = false;
217 }
218
219 return 0;
220}
221
138static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter,
139 struct devlink_info_req *req,
140 struct ixgbe_info_ctx *ctx)
141{
142 int err;
143
144 ixgbe_info_fw_api(adapter, ctx);
145 err = devlink_info_version_running_put(req,
146 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
147 ctx->buf);
148 if (err)
149 return err;
150
151 ixgbe_info_fw_build(adapter, ctx);
152 err = devlink_info_version_running_put(req, "fw.mgmt.build", ctx->buf);
153 if (err)
154 return err;
155
222static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter,
223 struct devlink_info_req *req,
224 struct ixgbe_info_ctx *ctx)
225{
226 int err;
227
228 ixgbe_info_fw_api(adapter, ctx);
229 err = devlink_info_version_running_put(req,
230 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
231 ctx->buf);
232 if (err)
233 return err;
234
235 ixgbe_info_fw_build(adapter, ctx);
236 err = devlink_info_version_running_put(req, "fw.mgmt.build", ctx->buf);
237 if (err)
238 return err;
239
156 ixgbe_info_fw_srev(adapter, ctx);
240 ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
157 err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf);
158 if (err)
159 return err;
160
241 err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf);
242 if (err)
243 return err;
244
161 ixgbe_info_orom_srev(adapter, ctx);
245 ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
162 err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf);
163 if (err)
164 return err;
165
246 err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf);
247 if (err)
248 return err;
249
166 ixgbe_info_nvm_ver(adapter, ctx);
250 ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
167 err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf);
168 if (err)
169 return err;
170
251 err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf);
252 if (err)
253 return err;
254
171 ixgbe_info_netlist_ver(adapter, ctx);
255 ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
172 err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf);
173 if (err)
174 return err;
175
256 err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf);
257 if (err)
258 return err;
259
176 ixgbe_info_netlist_build(adapter, ctx);
260 ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
177 return devlink_info_version_running_put(req, "fw.netlist.build",
178 ctx->buf);
179}
180
261 return devlink_info_version_running_put(req, "fw.netlist.build",
262 ctx->buf);
263}
264
265static int
266ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter *adapter,
267 struct devlink_info_req *req,
268 struct ixgbe_info_ctx *ctx)
269{
270 int err;
271
272 ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
273 err = devlink_info_version_stored_put(req,
274 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
275 ctx->buf);
276 if (err)
277 return err;
278
279 ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_STORED);
280 err = devlink_info_version_stored_put(req,
281 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
282 ctx->buf);
283 if (err)
284 return err;
285
286 ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
287 err = devlink_info_version_stored_put(req, "fw.mgmt.srev", ctx->buf);
288 if (err)
289 return err;
290
291 ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
292 err = devlink_info_version_stored_put(req, "fw.undi.srev", ctx->buf);
293 if (err)
294 return err;
295
296 ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
297 err = devlink_info_version_stored_put(req, "fw.psid.api", ctx->buf);
298 if (err)
299 return err;
300
301 ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
302 err = devlink_info_version_stored_put(req, "fw.netlist", ctx->buf);
303 if (err)
304 return err;
305
306 ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_STORED);
307 return devlink_info_version_stored_put(req, "fw.netlist.build",
308 ctx->buf);
309}
310
181static int ixgbe_devlink_info_get(struct devlink *devlink,
182 struct devlink_info_req *req,
183 struct netlink_ext_ack *extack)
184{
185 struct ixgbe_adapter *adapter = devlink_priv(devlink);
186 struct ixgbe_hw *hw = &adapter->hw;
187 struct ixgbe_info_ctx *ctx;
188 int err;

--- 12 unchanged lines hidden (view full) ---

201 goto free_ctx;
202
203 err = devlink_info_version_fixed_put(req,
204 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
205 ctx->buf);
206 if (err)
207 goto free_ctx;
208
311static int ixgbe_devlink_info_get(struct devlink *devlink,
312 struct devlink_info_req *req,
313 struct netlink_ext_ack *extack)
314{
315 struct ixgbe_adapter *adapter = devlink_priv(devlink);
316 struct ixgbe_hw *hw = &adapter->hw;
317 struct ixgbe_info_ctx *ctx;
318 int err;

--- 12 unchanged lines hidden (view full) ---

331 goto free_ctx;
332
333 err = devlink_info_version_fixed_put(req,
334 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
335 ctx->buf);
336 if (err)
337 goto free_ctx;
338
209 ixgbe_info_orom_ver(adapter, ctx);
339 ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
210 err = devlink_info_version_running_put(req,
211 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
212 ctx->buf);
213 if (err)
214 goto free_ctx;
215
340 err = devlink_info_version_running_put(req,
341 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
342 ctx->buf);
343 if (err)
344 goto free_ctx;
345
216 ixgbe_info_eetrack(adapter, ctx);
346 ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
217 err = devlink_info_version_running_put(req,
218 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
219 ctx->buf);
220 if (err || hw->mac.type != ixgbe_mac_e610)
221 goto free_ctx;
222
347 err = devlink_info_version_running_put(req,
348 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
349 ctx->buf);
350 if (err || hw->mac.type != ixgbe_mac_e610)
351 goto free_ctx;
352
353 err = ixgbe_set_ctx_dev_caps(hw, ctx, extack);
354 if (err)
355 goto free_ctx;
356
223 err = ixgbe_devlink_info_get_e610(adapter, req, ctx);
357 err = ixgbe_devlink_info_get_e610(adapter, req, ctx);
358 if (err)
359 goto free_ctx;
360
361 err = ixgbe_devlink_pending_info_get_e610(adapter, req, ctx);
224free_ctx:
225 kfree(ctx);
226 return err;
227}
228
229static const struct devlink_ops ixgbe_devlink_ops = {
230 .info_get = ixgbe_devlink_info_get,
231};

--- 69 unchanged lines hidden ---
362free_ctx:
363 kfree(ctx);
364 return err;
365}
366
367static const struct devlink_ops ixgbe_devlink_ops = {
368 .info_get = ixgbe_devlink_info_get,
369};

--- 69 unchanged lines hidden ---