xref: /linux/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c (revision 63467137ecc0ff6f804d53903ad87a2f0397a18b)
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 
ixgbe_info_get_dsn(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx)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(pci_get_dsn(adapter->pdev), dsn);
28 
29 	snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
30 }
31 
ixgbe_info_orom_ver(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
49 			 orom->major, orom->build, orom->patch);
50 		return;
51 	}
52 
53 	ixgbe_get_oem_prod_version(hw, &nvm_ver);
54 	if (nvm_ver.oem_valid) {
55 		snprintf(ctx->buf, sizeof(ctx->buf), "%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);
63 	if (nvm_ver.or_valid)
64 		snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
65 			 nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
66 }
67 
ixgbe_info_eetrack(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack);
83 		return;
84 	}
85 
86 	ixgbe_get_oem_prod_version(hw, &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);
95 	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id);
96 }
97 
ixgbe_info_fw_api(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx)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(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
104 		 hw->api_maj_ver, hw->api_min_ver, hw->api_patch);
105 }
106 
ixgbe_info_fw_build(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx)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(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);
113 }
114 
ixgbe_info_fw_srev(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
126 }
127 
ixgbe_info_orom_srev(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "%u", orom->srev);
139 }
140 
ixgbe_info_nvm_ver(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);
152 }
153 
ixgbe_info_netlist_ver(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "%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 
ixgbe_info_netlist_build(struct ixgbe_adapter * adapter,struct ixgbe_info_ctx * ctx,enum ixgbe_devlink_version_type type)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(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);
182 }
183 
ixgbe_set_ctx_dev_caps(struct ixgbe_hw * hw,struct ixgbe_info_ctx * ctx,struct netlink_ext_ack * extack)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, &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, &ctx->pending_orom);
204 		if (err)
205 			*pending_orom = false;
206 	}
207 
208 	if (*pending_nvm) {
209 		err = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm);
210 		if (err)
211 			*pending_nvm = false;
212 	}
213 
214 	if (*pending_netlist) {
215 		err = ixgbe_get_inactive_netlist_ver(hw, &ctx->pending_netlist);
216 		if (err)
217 			*pending_netlist = false;
218 	}
219 
220 	return 0;
221 }
222 
ixgbe_devlink_info_get_e610(struct ixgbe_adapter * adapter,struct devlink_info_req * req,struct ixgbe_info_ctx * ctx)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 					       ctx->buf);
233 	if (err)
234 		return err;
235 
236 	ixgbe_info_fw_build(adapter, ctx);
237 	err = devlink_info_version_running_put(req, "fw.mgmt.build", ctx->buf);
238 	if (err)
239 		return err;
240 
241 	ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
242 	err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf);
243 	if (err)
244 		return err;
245 
246 	ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
247 	err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf);
248 	if (err)
249 		return err;
250 
251 	ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
252 	err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf);
253 	if (err)
254 		return err;
255 
256 	ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
257 	err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf);
258 	if (err)
259 		return err;
260 
261 	ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
262 	return devlink_info_version_running_put(req, "fw.netlist.build",
263 						ctx->buf);
264 }
265 
266 static int
ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter * adapter,struct devlink_info_req * req,struct ixgbe_info_ctx * ctx)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, IXGBE_DL_VERSION_STORED);
274 	err = devlink_info_version_stored_put(req,
275 					      DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
276 					      ctx->buf);
277 	if (err)
278 		return err;
279 
280 	ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_STORED);
281 	err = devlink_info_version_stored_put(req,
282 					      DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
283 					      ctx->buf);
284 	if (err)
285 		return err;
286 
287 	ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
288 	err = devlink_info_version_stored_put(req, "fw.mgmt.srev", ctx->buf);
289 	if (err)
290 		return err;
291 
292 	ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
293 	err = devlink_info_version_stored_put(req, "fw.undi.srev", ctx->buf);
294 	if (err)
295 		return err;
296 
297 	ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
298 	err = devlink_info_version_stored_put(req, "fw.psid.api", ctx->buf);
299 	if (err)
300 		return err;
301 
302 	ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
303 	err = devlink_info_version_stored_put(req, "fw.netlist", ctx->buf);
304 	if (err)
305 		return err;
306 
307 	ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_STORED);
308 	return devlink_info_version_stored_put(req, "fw.netlist.build",
309 					       ctx->buf);
310 }
311 
ixgbe_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)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, 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 					     ctx->buf);
340 	if (err)
341 		goto free_ctx;
342 
343 	ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
344 	err = devlink_info_version_running_put(req,
345 					       DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
346 					       ctx->buf);
347 	if (err)
348 		goto free_ctx;
349 
350 	ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
351 	err = devlink_info_version_running_put(req,
352 					       DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
353 					       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(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  */
ixgbe_devlink_reload_empr_start(struct devlink * devlink,bool netns_change,enum devlink_reload_action action,enum devlink_reload_limit limit,struct netlink_ext_ack * extack)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, 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  */
ixgbe_devlink_reload_empr_finish(struct devlink * devlink,enum devlink_reload_action action,enum devlink_reload_limit limit,u32 * actions_performed,struct netlink_ext_ack * extack)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  */
ixgbe_allocate_devlink(struct device * dev)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(&ixgbe_devlink_ops, sizeof(*adapter), dev);
505 	if (!devlink)
506 		return ERR_PTR(-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  */
ixgbe_devlink_set_switch_id(struct ixgbe_adapter * adapter,struct netdev_phys_item_id * ppid)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(adapter->pdev);
523 
524 	ppid->id_len = sizeof(id);
525 	put_unaligned_be64(id, &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  */
ixgbe_devlink_register_port(struct ixgbe_adapter * adapter)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 	attrs.no_phys_port_name = 1;
547 	ixgbe_devlink_set_switch_id(adapter, &attrs.switch_id);
548 
549 	devlink_port_attrs_set(devlink_port, &attrs);
550 
551 	err = devl_port_register(devlink, devlink_port, 0);
552 	if (err) {
553 		dev_err(dev,
554 			"devlink port registration failed, err %d\n", err);
555 	}
556 
557 	return err;
558 }
559