1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* Copyright (c) 2025, Intel Corporation. */ |
3 | |
4 | #include "ixgbe.h" |
5 | #include "devlink.h" |
6 | #include "ixgbe_fw_update.h" |
7 | |
8 | struct ixgbe_info_ctx { |
9 | char buf[128]; |
10 | struct ixgbe_orom_info pending_orom; |
11 | struct ixgbe_nvm_info pending_nvm; |
12 | struct ixgbe_netlist_info pending_netlist; |
13 | struct ixgbe_hw_dev_caps dev_caps; |
14 | }; |
15 | |
16 | enum ixgbe_devlink_version_type { |
17 | IXGBE_DL_VERSION_RUNNING, |
18 | IXGBE_DL_VERSION_STORED |
19 | }; |
20 | |
21 | static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter, |
22 | struct ixgbe_info_ctx *ctx) |
23 | { |
24 | u8 dsn[8]; |
25 | |
26 | /* Copy the DSN into an array in Big Endian format */ |
27 | put_unaligned_be64(val: pci_get_dsn(dev: adapter->pdev), p: dsn); |
28 | |
29 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%8phD", dsn); |
30 | } |
31 | |
32 | static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, |
33 | struct ixgbe_info_ctx *ctx, |
34 | enum ixgbe_devlink_version_type type) |
35 | { |
36 | struct ixgbe_hw *hw = &adapter->hw; |
37 | struct ixgbe_nvm_version nvm_ver; |
38 | |
39 | ctx->buf[0] = '\0'; |
40 | |
41 | if (hw->mac.type == ixgbe_mac_e610) { |
42 | struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; |
43 | |
44 | if (type == IXGBE_DL_VERSION_STORED && |
45 | ctx->dev_caps.common_cap.nvm_update_pending_orom) |
46 | orom = &ctx->pending_orom; |
47 | |
48 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%u.%u.%u", |
49 | orom->major, orom->build, orom->patch); |
50 | return; |
51 | } |
52 | |
53 | ixgbe_get_oem_prod_version(hw, nvm_ver: &nvm_ver); |
54 | if (nvm_ver.oem_valid) { |
55 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%x.%x.%x", |
56 | nvm_ver.oem_major, nvm_ver.oem_minor, |
57 | nvm_ver.oem_release); |
58 | |
59 | return; |
60 | } |
61 | |
62 | ixgbe_get_orom_version(hw, nvm_ver: &nvm_ver); |
63 | if (nvm_ver.or_valid) |
64 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%d.%d.%d", |
65 | nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch); |
66 | } |
67 | |
68 | static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter, |
69 | struct ixgbe_info_ctx *ctx, |
70 | enum ixgbe_devlink_version_type type) |
71 | { |
72 | struct ixgbe_hw *hw = &adapter->hw; |
73 | struct ixgbe_nvm_version nvm_ver; |
74 | |
75 | if (hw->mac.type == ixgbe_mac_e610) { |
76 | u32 eetrack = hw->flash.nvm.eetrack; |
77 | |
78 | if (type == IXGBE_DL_VERSION_STORED && |
79 | ctx->dev_caps.common_cap.nvm_update_pending_nvm) |
80 | eetrack = ctx->pending_nvm.eetrack; |
81 | |
82 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "0x%08x", eetrack); |
83 | return; |
84 | } |
85 | |
86 | ixgbe_get_oem_prod_version(hw, nvm_ver: &nvm_ver); |
87 | |
88 | /* No ETRACK version for OEM */ |
89 | if (nvm_ver.oem_valid) { |
90 | ctx->buf[0] = '\0'; |
91 | return; |
92 | } |
93 | |
94 | ixgbe_get_etk_id(hw, nvm_ver: &nvm_ver); |
95 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "0x%08x", nvm_ver.etk_id); |
96 | } |
97 | |
98 | static void ixgbe_info_fw_api(struct ixgbe_adapter *adapter, |
99 | struct ixgbe_info_ctx *ctx) |
100 | { |
101 | struct ixgbe_hw *hw = &adapter->hw; |
102 | |
103 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%u.%u.%u", |
104 | hw->api_maj_ver, hw->api_min_ver, hw->api_patch); |
105 | } |
106 | |
107 | static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter, |
108 | struct ixgbe_info_ctx *ctx) |
109 | { |
110 | struct ixgbe_hw *hw = &adapter->hw; |
111 | |
112 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "0x%08x", hw->fw_build); |
113 | } |
114 | |
115 | static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter, |
116 | struct ixgbe_info_ctx *ctx, |
117 | enum ixgbe_devlink_version_type type) |
118 | { |
119 | struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; |
120 | |
121 | if (type == IXGBE_DL_VERSION_STORED && |
122 | ctx->dev_caps.common_cap.nvm_update_pending_nvm) |
123 | nvm = &ctx->pending_nvm; |
124 | |
125 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%u", nvm->srev); |
126 | } |
127 | |
128 | static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter, |
129 | struct ixgbe_info_ctx *ctx, |
130 | enum ixgbe_devlink_version_type type) |
131 | { |
132 | struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; |
133 | |
134 | if (type == IXGBE_DL_VERSION_STORED && |
135 | ctx->dev_caps.common_cap.nvm_update_pending_orom) |
136 | orom = &ctx->pending_orom; |
137 | |
138 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%u", orom->srev); |
139 | } |
140 | |
141 | static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter, |
142 | struct ixgbe_info_ctx *ctx, |
143 | enum ixgbe_devlink_version_type type) |
144 | { |
145 | struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; |
146 | |
147 | if (type == IXGBE_DL_VERSION_STORED && |
148 | ctx->dev_caps.common_cap.nvm_update_pending_nvm) |
149 | nvm = &ctx->pending_nvm; |
150 | |
151 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%x.%02x", nvm->major, nvm->minor); |
152 | } |
153 | |
154 | static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter, |
155 | struct ixgbe_info_ctx *ctx, |
156 | enum ixgbe_devlink_version_type type) |
157 | { |
158 | struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; |
159 | |
160 | if (type == IXGBE_DL_VERSION_STORED && |
161 | ctx->dev_caps.common_cap.nvm_update_pending_netlist) |
162 | netlist = &ctx->pending_netlist; |
163 | |
164 | /* The netlist version fields are BCD formatted */ |
165 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "%x.%x.%x-%x.%x.%x", |
166 | netlist->major, netlist->minor, |
167 | netlist->type >> 16, netlist->type & 0xFFFF, |
168 | netlist->rev, netlist->cust_ver); |
169 | } |
170 | |
171 | static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter, |
172 | struct ixgbe_info_ctx *ctx, |
173 | enum ixgbe_devlink_version_type type) |
174 | { |
175 | struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; |
176 | |
177 | if (type == IXGBE_DL_VERSION_STORED && |
178 | ctx->dev_caps.common_cap.nvm_update_pending_netlist) |
179 | netlist = &ctx->pending_netlist; |
180 | |
181 | snprintf(buf: ctx->buf, size: sizeof(ctx->buf), fmt: "0x%08x", netlist->hash); |
182 | } |
183 | |
184 | static int ixgbe_set_ctx_dev_caps(struct ixgbe_hw *hw, |
185 | struct ixgbe_info_ctx *ctx, |
186 | struct netlink_ext_ack *extack) |
187 | { |
188 | bool *pending_orom, *pending_nvm, *pending_netlist; |
189 | int err; |
190 | |
191 | err = ixgbe_discover_dev_caps(hw, dev_caps: &ctx->dev_caps); |
192 | if (err) { |
193 | NL_SET_ERR_MSG_MOD(extack, |
194 | "Unable to discover device capabilities"); |
195 | return err; |
196 | } |
197 | |
198 | pending_orom = &ctx->dev_caps.common_cap.nvm_update_pending_orom; |
199 | pending_nvm = &ctx->dev_caps.common_cap.nvm_update_pending_nvm; |
200 | pending_netlist = &ctx->dev_caps.common_cap.nvm_update_pending_netlist; |
201 | |
202 | if (*pending_orom) { |
203 | err = ixgbe_get_inactive_orom_ver(hw, orom: &ctx->pending_orom); |
204 | if (err) |
205 | *pending_orom = false; |
206 | } |
207 | |
208 | if (*pending_nvm) { |
209 | err = ixgbe_get_inactive_nvm_ver(hw, nvm: &ctx->pending_nvm); |
210 | if (err) |
211 | *pending_nvm = false; |
212 | } |
213 | |
214 | if (*pending_netlist) { |
215 | err = ixgbe_get_inactive_netlist_ver(hw, netlist: &ctx->pending_netlist); |
216 | if (err) |
217 | *pending_netlist = false; |
218 | } |
219 | |
220 | return 0; |
221 | } |
222 | |
223 | static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter, |
224 | struct devlink_info_req *req, |
225 | struct ixgbe_info_ctx *ctx) |
226 | { |
227 | int err; |
228 | |
229 | ixgbe_info_fw_api(adapter, ctx); |
230 | err = devlink_info_version_running_put(req, |
231 | DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API, |
232 | version_value: ctx->buf); |
233 | if (err) |
234 | return err; |
235 | |
236 | ixgbe_info_fw_build(adapter, ctx); |
237 | err = devlink_info_version_running_put(req, version_name: "fw.mgmt.build", version_value: ctx->buf); |
238 | if (err) |
239 | return err; |
240 | |
241 | ixgbe_info_fw_srev(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
242 | err = devlink_info_version_running_put(req, version_name: "fw.mgmt.srev", version_value: ctx->buf); |
243 | if (err) |
244 | return err; |
245 | |
246 | ixgbe_info_orom_srev(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
247 | err = devlink_info_version_running_put(req, version_name: "fw.undi.srev", version_value: ctx->buf); |
248 | if (err) |
249 | return err; |
250 | |
251 | ixgbe_info_nvm_ver(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
252 | err = devlink_info_version_running_put(req, version_name: "fw.psid.api", version_value: ctx->buf); |
253 | if (err) |
254 | return err; |
255 | |
256 | ixgbe_info_netlist_ver(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
257 | err = devlink_info_version_running_put(req, version_name: "fw.netlist", version_value: ctx->buf); |
258 | if (err) |
259 | return err; |
260 | |
261 | ixgbe_info_netlist_build(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
262 | return devlink_info_version_running_put(req, version_name: "fw.netlist.build", |
263 | version_value: ctx->buf); |
264 | } |
265 | |
266 | static int |
267 | ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter *adapter, |
268 | struct devlink_info_req *req, |
269 | struct ixgbe_info_ctx *ctx) |
270 | { |
271 | int err; |
272 | |
273 | ixgbe_info_orom_ver(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
274 | err = devlink_info_version_stored_put(req, |
275 | DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, |
276 | version_value: ctx->buf); |
277 | if (err) |
278 | return err; |
279 | |
280 | ixgbe_info_eetrack(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
281 | err = devlink_info_version_stored_put(req, |
282 | DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, |
283 | version_value: ctx->buf); |
284 | if (err) |
285 | return err; |
286 | |
287 | ixgbe_info_fw_srev(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
288 | err = devlink_info_version_stored_put(req, version_name: "fw.mgmt.srev", version_value: ctx->buf); |
289 | if (err) |
290 | return err; |
291 | |
292 | ixgbe_info_orom_srev(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
293 | err = devlink_info_version_stored_put(req, version_name: "fw.undi.srev", version_value: ctx->buf); |
294 | if (err) |
295 | return err; |
296 | |
297 | ixgbe_info_nvm_ver(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
298 | err = devlink_info_version_stored_put(req, version_name: "fw.psid.api", version_value: ctx->buf); |
299 | if (err) |
300 | return err; |
301 | |
302 | ixgbe_info_netlist_ver(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
303 | err = devlink_info_version_stored_put(req, version_name: "fw.netlist", version_value: ctx->buf); |
304 | if (err) |
305 | return err; |
306 | |
307 | ixgbe_info_netlist_build(adapter, ctx, type: IXGBE_DL_VERSION_STORED); |
308 | return devlink_info_version_stored_put(req, version_name: "fw.netlist.build", |
309 | version_value: ctx->buf); |
310 | } |
311 | |
312 | static int ixgbe_devlink_info_get(struct devlink *devlink, |
313 | struct devlink_info_req *req, |
314 | struct netlink_ext_ack *extack) |
315 | { |
316 | struct ixgbe_adapter *adapter = devlink_priv(devlink); |
317 | struct ixgbe_hw *hw = &adapter->hw; |
318 | struct ixgbe_info_ctx *ctx; |
319 | int err; |
320 | |
321 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
322 | if (!ctx) |
323 | return -ENOMEM; |
324 | |
325 | if (hw->mac.type == ixgbe_mac_e610) |
326 | ixgbe_refresh_fw_version(adapter); |
327 | |
328 | ixgbe_info_get_dsn(adapter, ctx); |
329 | err = devlink_info_serial_number_put(req, sn: ctx->buf); |
330 | if (err) |
331 | goto free_ctx; |
332 | |
333 | err = hw->eeprom.ops.read_pba_string(hw, ctx->buf, sizeof(ctx->buf)); |
334 | if (err) |
335 | goto free_ctx; |
336 | |
337 | err = devlink_info_version_fixed_put(req, |
338 | DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, |
339 | version_value: ctx->buf); |
340 | if (err) |
341 | goto free_ctx; |
342 | |
343 | ixgbe_info_orom_ver(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
344 | err = devlink_info_version_running_put(req, |
345 | DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, |
346 | version_value: ctx->buf); |
347 | if (err) |
348 | goto free_ctx; |
349 | |
350 | ixgbe_info_eetrack(adapter, ctx, type: IXGBE_DL_VERSION_RUNNING); |
351 | err = devlink_info_version_running_put(req, |
352 | DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, |
353 | version_value: ctx->buf); |
354 | if (err || hw->mac.type != ixgbe_mac_e610) |
355 | goto free_ctx; |
356 | |
357 | err = ixgbe_set_ctx_dev_caps(hw, ctx, extack); |
358 | if (err) |
359 | goto free_ctx; |
360 | |
361 | err = ixgbe_devlink_info_get_e610(adapter, req, ctx); |
362 | if (err) |
363 | goto free_ctx; |
364 | |
365 | err = ixgbe_devlink_pending_info_get_e610(adapter, req, ctx); |
366 | free_ctx: |
367 | kfree(objp: ctx); |
368 | return err; |
369 | } |
370 | |
371 | /** |
372 | * ixgbe_devlink_reload_empr_start - Start EMP reset to activate new firmware |
373 | * @devlink: pointer to the devlink instance to reload |
374 | * @netns_change: if true, the network namespace is changing |
375 | * @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE |
376 | * @limit: limits on what reload should do, such as not resetting |
377 | * @extack: netlink extended ACK structure |
378 | * |
379 | * Allow user to activate new Embedded Management Processor firmware by |
380 | * issuing device specific EMP reset. Called in response to |
381 | * a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE. |
382 | * |
383 | * Note that teardown and rebuild of the driver state happens automatically as |
384 | * part of an interrupt and watchdog task. This is because all physical |
385 | * functions on the device must be able to reset when an EMP reset occurs from |
386 | * any source. |
387 | * |
388 | * Return: the exit code of the operation. |
389 | */ |
390 | static int ixgbe_devlink_reload_empr_start(struct devlink *devlink, |
391 | bool netns_change, |
392 | enum devlink_reload_action action, |
393 | enum devlink_reload_limit limit, |
394 | struct netlink_ext_ack *extack) |
395 | { |
396 | struct ixgbe_adapter *adapter = devlink_priv(devlink); |
397 | struct ixgbe_hw *hw = &adapter->hw; |
398 | u8 pending; |
399 | int err; |
400 | |
401 | if (hw->mac.type != ixgbe_mac_e610) |
402 | return -EOPNOTSUPP; |
403 | |
404 | err = ixgbe_get_pending_updates(adapter, pending: &pending, extack); |
405 | if (err) |
406 | return err; |
407 | |
408 | /* Pending is a bitmask of which flash banks have a pending update, |
409 | * including the main NVM bank, the Option ROM bank, and the netlist |
410 | * bank. If any of these bits are set, then there is a pending update |
411 | * waiting to be activated. |
412 | */ |
413 | if (!pending) { |
414 | NL_SET_ERR_MSG_MOD(extack, "No pending firmware update"); |
415 | return -ECANCELED; |
416 | } |
417 | |
418 | if (adapter->fw_emp_reset_disabled) { |
419 | NL_SET_ERR_MSG_MOD(extack, |
420 | "EMP reset is not available. To activate firmware, a reboot or power cycle is needed"); |
421 | return -ECANCELED; |
422 | } |
423 | |
424 | err = ixgbe_aci_nvm_update_empr(hw); |
425 | if (err) |
426 | NL_SET_ERR_MSG_MOD(extack, |
427 | "Failed to trigger EMP device reset to reload firmware"); |
428 | |
429 | return err; |
430 | } |
431 | |
432 | /*Wait for 10 sec with 0.5 sec tic. EMPR takes no less than half of a sec */ |
433 | #define IXGBE_DEVLINK_RELOAD_TIMEOUT_SEC 20 |
434 | |
435 | /** |
436 | * ixgbe_devlink_reload_empr_finish - finishes EMP reset |
437 | * @devlink: pointer to the devlink instance |
438 | * @action: the action to perform. |
439 | * @limit: limits on what reload should do |
440 | * @actions_performed: actions performed |
441 | * @extack: netlink extended ACK structure |
442 | * |
443 | * Wait for new NVM to be loaded during EMP reset. |
444 | * |
445 | * Return: -ETIME when timer is exceeded, 0 on success. |
446 | */ |
447 | static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink, |
448 | enum devlink_reload_action action, |
449 | enum devlink_reload_limit limit, |
450 | u32 *actions_performed, |
451 | struct netlink_ext_ack *extack) |
452 | { |
453 | struct ixgbe_adapter *adapter = devlink_priv(devlink); |
454 | struct ixgbe_hw *hw = &adapter->hw; |
455 | int i = 0; |
456 | u32 fwsm; |
457 | |
458 | do { |
459 | /* Just right away after triggering EMP reset the FWSM register |
460 | * may be not cleared yet, so begin the loop with the delay |
461 | * in order to not check the not updated register. |
462 | */ |
463 | mdelay(500); |
464 | |
465 | fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw)); |
466 | |
467 | if (i++ >= IXGBE_DEVLINK_RELOAD_TIMEOUT_SEC) |
468 | return -ETIME; |
469 | |
470 | } while (!(fwsm & IXGBE_FWSM_FW_VAL_BIT)); |
471 | |
472 | *actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE); |
473 | |
474 | adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH | |
475 | IXGBE_FLAG2_FW_ROLLBACK); |
476 | |
477 | return 0; |
478 | } |
479 | |
480 | static const struct devlink_ops ixgbe_devlink_ops = { |
481 | .info_get = ixgbe_devlink_info_get, |
482 | .supported_flash_update_params = |
483 | DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, |
484 | .flash_update = ixgbe_flash_pldm_image, |
485 | .reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), |
486 | .reload_down = ixgbe_devlink_reload_empr_start, |
487 | .reload_up = ixgbe_devlink_reload_empr_finish, |
488 | }; |
489 | |
490 | /** |
491 | * ixgbe_allocate_devlink - Allocate devlink instance |
492 | * @dev: device to allocate devlink for |
493 | * |
494 | * Allocate a devlink instance for this physical function. |
495 | * |
496 | * Return: pointer to the device adapter structure on success, |
497 | * ERR_PTR(-ENOMEM) when allocation failed. |
498 | */ |
499 | struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev) |
500 | { |
501 | struct ixgbe_adapter *adapter; |
502 | struct devlink *devlink; |
503 | |
504 | devlink = devlink_alloc(ops: &ixgbe_devlink_ops, priv_size: sizeof(*adapter), dev); |
505 | if (!devlink) |
506 | return ERR_PTR(error: -ENOMEM); |
507 | |
508 | adapter = devlink_priv(devlink); |
509 | adapter->devlink = devlink; |
510 | |
511 | return adapter; |
512 | } |
513 | |
514 | /** |
515 | * ixgbe_devlink_set_switch_id - Set unique switch ID based on PCI DSN |
516 | * @adapter: pointer to the device adapter structure |
517 | * @ppid: struct with switch id information |
518 | */ |
519 | static void ixgbe_devlink_set_switch_id(struct ixgbe_adapter *adapter, |
520 | struct netdev_phys_item_id *ppid) |
521 | { |
522 | u64 id = pci_get_dsn(dev: adapter->pdev); |
523 | |
524 | ppid->id_len = sizeof(id); |
525 | put_unaligned_be64(val: id, p: &ppid->id); |
526 | } |
527 | |
528 | /** |
529 | * ixgbe_devlink_register_port - Register devlink port |
530 | * @adapter: pointer to the device adapter structure |
531 | * |
532 | * Create and register a devlink_port for this physical function. |
533 | * |
534 | * Return: 0 on success, error code on failure. |
535 | */ |
536 | int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter) |
537 | { |
538 | struct devlink_port *devlink_port = &adapter->devlink_port; |
539 | struct devlink *devlink = adapter->devlink; |
540 | struct device *dev = &adapter->pdev->dev; |
541 | struct devlink_port_attrs attrs = {}; |
542 | int err; |
543 | |
544 | attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; |
545 | attrs.phys.port_number = adapter->hw.bus.func; |
546 | ixgbe_devlink_set_switch_id(adapter, ppid: &attrs.switch_id); |
547 | |
548 | devlink_port_attrs_set(devlink_port, devlink_port_attrs: &attrs); |
549 | |
550 | err = devl_port_register(devlink, devlink_port, port_index: 0); |
551 | if (err) { |
552 | dev_err(dev, |
553 | "devlink port registration failed, err %d\n", err); |
554 | } |
555 | |
556 | return err; |
557 | } |
558 |
Definitions
- ixgbe_info_ctx
- ixgbe_devlink_version_type
- ixgbe_info_get_dsn
- ixgbe_info_orom_ver
- ixgbe_info_eetrack
- ixgbe_info_fw_api
- ixgbe_info_fw_build
- ixgbe_info_fw_srev
- ixgbe_info_orom_srev
- ixgbe_info_nvm_ver
- ixgbe_info_netlist_ver
- ixgbe_info_netlist_build
- ixgbe_set_ctx_dev_caps
- ixgbe_devlink_info_get_e610
- ixgbe_devlink_pending_info_get_e610
- ixgbe_devlink_info_get
- ixgbe_devlink_reload_empr_start
- ixgbe_devlink_reload_empr_finish
- ixgbe_devlink_ops
- ixgbe_allocate_devlink
- ixgbe_devlink_set_switch_id
Improve your Profiling and Debugging skills
Find out more