xref: /linux/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c (revision 6eae2aeb60b6f1cfa97e6e8f296027f15173a67a)
1a0285236SJedrzej Jagielski // SPDX-License-Identifier: GPL-2.0
2a0285236SJedrzej Jagielski /* Copyright (c) 2025, Intel Corporation. */
3a0285236SJedrzej Jagielski 
4a0285236SJedrzej Jagielski #include "ixgbe.h"
5a0285236SJedrzej Jagielski #include "devlink.h"
6a0285236SJedrzej Jagielski 
7f6b588afSJedrzej Jagielski struct ixgbe_info_ctx {
8f6b588afSJedrzej Jagielski 	char buf[128];
9*6eae2aebSJedrzej Jagielski 	struct ixgbe_orom_info pending_orom;
10*6eae2aebSJedrzej Jagielski 	struct ixgbe_nvm_info pending_nvm;
11*6eae2aebSJedrzej Jagielski 	struct ixgbe_netlist_info pending_netlist;
12*6eae2aebSJedrzej Jagielski 	struct ixgbe_hw_dev_caps dev_caps;
13*6eae2aebSJedrzej Jagielski };
14*6eae2aebSJedrzej Jagielski 
15*6eae2aebSJedrzej Jagielski enum ixgbe_devlink_version_type {
16*6eae2aebSJedrzej Jagielski 	IXGBE_DL_VERSION_RUNNING,
17*6eae2aebSJedrzej Jagielski 	IXGBE_DL_VERSION_STORED
18f6b588afSJedrzej Jagielski };
19f6b588afSJedrzej Jagielski 
20f6b588afSJedrzej Jagielski static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
21f6b588afSJedrzej Jagielski 			       struct ixgbe_info_ctx *ctx)
22f6b588afSJedrzej Jagielski {
23f6b588afSJedrzej Jagielski 	u8 dsn[8];
24f6b588afSJedrzej Jagielski 
25f6b588afSJedrzej Jagielski 	/* Copy the DSN into an array in Big Endian format */
26f6b588afSJedrzej Jagielski 	put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn);
27f6b588afSJedrzej Jagielski 
28f6b588afSJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
29f6b588afSJedrzej Jagielski }
30f6b588afSJedrzej Jagielski 
318210ff73SJedrzej Jagielski static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter,
32*6eae2aebSJedrzej Jagielski 				struct ixgbe_info_ctx *ctx,
33*6eae2aebSJedrzej Jagielski 				enum ixgbe_devlink_version_type type)
34f6b588afSJedrzej Jagielski {
35f6b588afSJedrzej Jagielski 	struct ixgbe_hw *hw = &adapter->hw;
36f6b588afSJedrzej Jagielski 	struct ixgbe_nvm_version nvm_ver;
37f6b588afSJedrzej Jagielski 
38f6b588afSJedrzej Jagielski 	ctx->buf[0] = '\0';
39f6b588afSJedrzej Jagielski 
408210ff73SJedrzej Jagielski 	if (hw->mac.type == ixgbe_mac_e610) {
418210ff73SJedrzej Jagielski 		struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
428210ff73SJedrzej Jagielski 
43*6eae2aebSJedrzej Jagielski 		if (type == IXGBE_DL_VERSION_STORED &&
44*6eae2aebSJedrzej Jagielski 		    ctx->dev_caps.common_cap.nvm_update_pending_orom)
45*6eae2aebSJedrzej Jagielski 			orom = &ctx->pending_orom;
46*6eae2aebSJedrzej Jagielski 
478210ff73SJedrzej Jagielski 		snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
488210ff73SJedrzej Jagielski 			 orom->major, orom->build, orom->patch);
498210ff73SJedrzej Jagielski 		return;
508210ff73SJedrzej Jagielski 	}
518210ff73SJedrzej Jagielski 
52f6b588afSJedrzej Jagielski 	ixgbe_get_oem_prod_version(hw, &nvm_ver);
53f6b588afSJedrzej Jagielski 	if (nvm_ver.oem_valid) {
54f6b588afSJedrzej Jagielski 		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",
55f6b588afSJedrzej Jagielski 			 nvm_ver.oem_major, nvm_ver.oem_minor,
56f6b588afSJedrzej Jagielski 			 nvm_ver.oem_release);
57f6b588afSJedrzej Jagielski 
58f6b588afSJedrzej Jagielski 		return;
59f6b588afSJedrzej Jagielski 	}
60f6b588afSJedrzej Jagielski 
61f6b588afSJedrzej Jagielski 	ixgbe_get_orom_version(hw, &nvm_ver);
62f6b588afSJedrzej Jagielski 	if (nvm_ver.or_valid)
63f6b588afSJedrzej Jagielski 		snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
64f6b588afSJedrzej Jagielski 			 nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
65f6b588afSJedrzej Jagielski }
66f6b588afSJedrzej Jagielski 
67f6b588afSJedrzej Jagielski static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
68*6eae2aebSJedrzej Jagielski 			       struct ixgbe_info_ctx *ctx,
69*6eae2aebSJedrzej Jagielski 			       enum ixgbe_devlink_version_type type)
70f6b588afSJedrzej Jagielski {
71f6b588afSJedrzej Jagielski 	struct ixgbe_hw *hw = &adapter->hw;
72f6b588afSJedrzej Jagielski 	struct ixgbe_nvm_version nvm_ver;
73f6b588afSJedrzej Jagielski 
748210ff73SJedrzej Jagielski 	if (hw->mac.type == ixgbe_mac_e610) {
75*6eae2aebSJedrzej Jagielski 		u32 eetrack = hw->flash.nvm.eetrack;
76*6eae2aebSJedrzej Jagielski 
77*6eae2aebSJedrzej Jagielski 		if (type == IXGBE_DL_VERSION_STORED &&
78*6eae2aebSJedrzej Jagielski 		    ctx->dev_caps.common_cap.nvm_update_pending_nvm)
79*6eae2aebSJedrzej Jagielski 			eetrack = ctx->pending_nvm.eetrack;
80*6eae2aebSJedrzej Jagielski 
81*6eae2aebSJedrzej Jagielski 		snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack);
828210ff73SJedrzej Jagielski 		return;
838210ff73SJedrzej Jagielski 	}
848210ff73SJedrzej Jagielski 
85f6b588afSJedrzej Jagielski 	ixgbe_get_oem_prod_version(hw, &nvm_ver);
86f6b588afSJedrzej Jagielski 
87f6b588afSJedrzej Jagielski 	/* No ETRACK version for OEM */
88f6b588afSJedrzej Jagielski 	if (nvm_ver.oem_valid) {
89f6b588afSJedrzej Jagielski 		ctx->buf[0] = '\0';
90f6b588afSJedrzej Jagielski 		return;
91f6b588afSJedrzej Jagielski 	}
92f6b588afSJedrzej Jagielski 
93f6b588afSJedrzej Jagielski 	ixgbe_get_etk_id(hw, &nvm_ver);
94f6b588afSJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id);
95f6b588afSJedrzej Jagielski }
96f6b588afSJedrzej Jagielski 
978210ff73SJedrzej Jagielski static void ixgbe_info_fw_api(struct ixgbe_adapter *adapter,
988210ff73SJedrzej Jagielski 			      struct ixgbe_info_ctx *ctx)
998210ff73SJedrzej Jagielski {
1008210ff73SJedrzej Jagielski 	struct ixgbe_hw *hw = &adapter->hw;
1018210ff73SJedrzej Jagielski 
1028210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
1038210ff73SJedrzej Jagielski 		 hw->api_maj_ver, hw->api_min_ver, hw->api_patch);
1048210ff73SJedrzej Jagielski }
1058210ff73SJedrzej Jagielski 
1068210ff73SJedrzej Jagielski static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter,
1078210ff73SJedrzej Jagielski 				struct ixgbe_info_ctx *ctx)
1088210ff73SJedrzej Jagielski {
1098210ff73SJedrzej Jagielski 	struct ixgbe_hw *hw = &adapter->hw;
1108210ff73SJedrzej Jagielski 
1118210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);
1128210ff73SJedrzej Jagielski }
1138210ff73SJedrzej Jagielski 
1148210ff73SJedrzej Jagielski static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter,
115*6eae2aebSJedrzej Jagielski 			       struct ixgbe_info_ctx *ctx,
116*6eae2aebSJedrzej Jagielski 			       enum ixgbe_devlink_version_type type)
1178210ff73SJedrzej Jagielski {
1188210ff73SJedrzej Jagielski 	struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
1198210ff73SJedrzej Jagielski 
120*6eae2aebSJedrzej Jagielski 	if (type == IXGBE_DL_VERSION_STORED &&
121*6eae2aebSJedrzej Jagielski 	    ctx->dev_caps.common_cap.nvm_update_pending_nvm)
122*6eae2aebSJedrzej Jagielski 		nvm = &ctx->pending_nvm;
123*6eae2aebSJedrzej Jagielski 
1248210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
1258210ff73SJedrzej Jagielski }
1268210ff73SJedrzej Jagielski 
1278210ff73SJedrzej Jagielski static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter,
128*6eae2aebSJedrzej Jagielski 				 struct ixgbe_info_ctx *ctx,
129*6eae2aebSJedrzej Jagielski 				 enum ixgbe_devlink_version_type type)
1308210ff73SJedrzej Jagielski {
1318210ff73SJedrzej Jagielski 	struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
1328210ff73SJedrzej Jagielski 
133*6eae2aebSJedrzej Jagielski 	if (type == IXGBE_DL_VERSION_STORED &&
134*6eae2aebSJedrzej Jagielski 	    ctx->dev_caps.common_cap.nvm_update_pending_orom)
135*6eae2aebSJedrzej Jagielski 		orom = &ctx->pending_orom;
136*6eae2aebSJedrzej Jagielski 
1378210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev);
1388210ff73SJedrzej Jagielski }
1398210ff73SJedrzej Jagielski 
1408210ff73SJedrzej Jagielski static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
141*6eae2aebSJedrzej Jagielski 			       struct ixgbe_info_ctx *ctx,
142*6eae2aebSJedrzej Jagielski 			       enum ixgbe_devlink_version_type type)
1438210ff73SJedrzej Jagielski {
1448210ff73SJedrzej Jagielski 	struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
1458210ff73SJedrzej Jagielski 
146*6eae2aebSJedrzej Jagielski 	if (type == IXGBE_DL_VERSION_STORED &&
147*6eae2aebSJedrzej Jagielski 	    ctx->dev_caps.common_cap.nvm_update_pending_nvm)
148*6eae2aebSJedrzej Jagielski 		nvm = &ctx->pending_nvm;
149*6eae2aebSJedrzej Jagielski 
1508210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);
1518210ff73SJedrzej Jagielski }
1528210ff73SJedrzej Jagielski 
1538210ff73SJedrzej Jagielski static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter,
154*6eae2aebSJedrzej Jagielski 				   struct ixgbe_info_ctx *ctx,
155*6eae2aebSJedrzej Jagielski 				   enum ixgbe_devlink_version_type type)
1568210ff73SJedrzej Jagielski {
1578210ff73SJedrzej Jagielski 	struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
1588210ff73SJedrzej Jagielski 
159*6eae2aebSJedrzej Jagielski 	if (type == IXGBE_DL_VERSION_STORED &&
160*6eae2aebSJedrzej Jagielski 	    ctx->dev_caps.common_cap.nvm_update_pending_netlist)
161*6eae2aebSJedrzej Jagielski 		netlist = &ctx->pending_netlist;
162*6eae2aebSJedrzej Jagielski 
1638210ff73SJedrzej Jagielski 	/* The netlist version fields are BCD formatted */
1648210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",
1658210ff73SJedrzej Jagielski 		 netlist->major, netlist->minor,
1668210ff73SJedrzej Jagielski 		 netlist->type >> 16, netlist->type & 0xFFFF,
1678210ff73SJedrzej Jagielski 		 netlist->rev, netlist->cust_ver);
1688210ff73SJedrzej Jagielski }
1698210ff73SJedrzej Jagielski 
1708210ff73SJedrzej Jagielski static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter,
171*6eae2aebSJedrzej Jagielski 				     struct ixgbe_info_ctx *ctx,
172*6eae2aebSJedrzej Jagielski 				     enum ixgbe_devlink_version_type type)
1738210ff73SJedrzej Jagielski {
1748210ff73SJedrzej Jagielski 	struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist;
1758210ff73SJedrzej Jagielski 
176*6eae2aebSJedrzej Jagielski 	if (type == IXGBE_DL_VERSION_STORED &&
177*6eae2aebSJedrzej Jagielski 	    ctx->dev_caps.common_cap.nvm_update_pending_netlist)
178*6eae2aebSJedrzej Jagielski 		netlist = &ctx->pending_netlist;
179*6eae2aebSJedrzej Jagielski 
1808210ff73SJedrzej Jagielski 	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);
1818210ff73SJedrzej Jagielski }
1828210ff73SJedrzej Jagielski 
183*6eae2aebSJedrzej Jagielski static int ixgbe_set_ctx_dev_caps(struct ixgbe_hw *hw,
184*6eae2aebSJedrzej Jagielski 				  struct ixgbe_info_ctx *ctx,
185*6eae2aebSJedrzej Jagielski 				  struct netlink_ext_ack *extack)
186*6eae2aebSJedrzej Jagielski {
187*6eae2aebSJedrzej Jagielski 	bool *pending_orom, *pending_nvm, *pending_netlist;
188*6eae2aebSJedrzej Jagielski 	int err;
189*6eae2aebSJedrzej Jagielski 
190*6eae2aebSJedrzej Jagielski 	err = ixgbe_discover_dev_caps(hw, &ctx->dev_caps);
191*6eae2aebSJedrzej Jagielski 	if (err) {
192*6eae2aebSJedrzej Jagielski 		NL_SET_ERR_MSG_MOD(extack,
193*6eae2aebSJedrzej Jagielski 				   "Unable to discover device capabilities");
194*6eae2aebSJedrzej Jagielski 		return err;
195*6eae2aebSJedrzej Jagielski 	}
196*6eae2aebSJedrzej Jagielski 
197*6eae2aebSJedrzej Jagielski 	pending_orom = &ctx->dev_caps.common_cap.nvm_update_pending_orom;
198*6eae2aebSJedrzej Jagielski 	pending_nvm = &ctx->dev_caps.common_cap.nvm_update_pending_nvm;
199*6eae2aebSJedrzej Jagielski 	pending_netlist = &ctx->dev_caps.common_cap.nvm_update_pending_netlist;
200*6eae2aebSJedrzej Jagielski 
201*6eae2aebSJedrzej Jagielski 	if (*pending_orom) {
202*6eae2aebSJedrzej Jagielski 		err = ixgbe_get_inactive_orom_ver(hw, &ctx->pending_orom);
203*6eae2aebSJedrzej Jagielski 		if (err)
204*6eae2aebSJedrzej Jagielski 			*pending_orom = false;
205*6eae2aebSJedrzej Jagielski 	}
206*6eae2aebSJedrzej Jagielski 
207*6eae2aebSJedrzej Jagielski 	if (*pending_nvm) {
208*6eae2aebSJedrzej Jagielski 		err = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm);
209*6eae2aebSJedrzej Jagielski 		if (err)
210*6eae2aebSJedrzej Jagielski 			*pending_nvm = false;
211*6eae2aebSJedrzej Jagielski 	}
212*6eae2aebSJedrzej Jagielski 
213*6eae2aebSJedrzej Jagielski 	if (*pending_netlist) {
214*6eae2aebSJedrzej Jagielski 		err = ixgbe_get_inactive_netlist_ver(hw, &ctx->pending_netlist);
215*6eae2aebSJedrzej Jagielski 		if (err)
216*6eae2aebSJedrzej Jagielski 			*pending_netlist = false;
217*6eae2aebSJedrzej Jagielski 	}
218*6eae2aebSJedrzej Jagielski 
219*6eae2aebSJedrzej Jagielski 	return 0;
220*6eae2aebSJedrzej Jagielski }
221*6eae2aebSJedrzej Jagielski 
2228210ff73SJedrzej Jagielski static int ixgbe_devlink_info_get_e610(struct ixgbe_adapter *adapter,
2238210ff73SJedrzej Jagielski 				       struct devlink_info_req *req,
2248210ff73SJedrzej Jagielski 				       struct ixgbe_info_ctx *ctx)
2258210ff73SJedrzej Jagielski {
2268210ff73SJedrzej Jagielski 	int err;
2278210ff73SJedrzej Jagielski 
2288210ff73SJedrzej Jagielski 	ixgbe_info_fw_api(adapter, ctx);
2298210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req,
2308210ff73SJedrzej Jagielski 					       DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
2318210ff73SJedrzej Jagielski 					       ctx->buf);
2328210ff73SJedrzej Jagielski 	if (err)
2338210ff73SJedrzej Jagielski 		return err;
2348210ff73SJedrzej Jagielski 
2358210ff73SJedrzej Jagielski 	ixgbe_info_fw_build(adapter, ctx);
2368210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req, "fw.mgmt.build", ctx->buf);
2378210ff73SJedrzej Jagielski 	if (err)
2388210ff73SJedrzej Jagielski 		return err;
2398210ff73SJedrzej Jagielski 
240*6eae2aebSJedrzej Jagielski 	ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
2418210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req, "fw.mgmt.srev", ctx->buf);
2428210ff73SJedrzej Jagielski 	if (err)
2438210ff73SJedrzej Jagielski 		return err;
2448210ff73SJedrzej Jagielski 
245*6eae2aebSJedrzej Jagielski 	ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
2468210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req, "fw.undi.srev", ctx->buf);
2478210ff73SJedrzej Jagielski 	if (err)
2488210ff73SJedrzej Jagielski 		return err;
2498210ff73SJedrzej Jagielski 
250*6eae2aebSJedrzej Jagielski 	ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
2518210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req, "fw.psid.api", ctx->buf);
2528210ff73SJedrzej Jagielski 	if (err)
2538210ff73SJedrzej Jagielski 		return err;
2548210ff73SJedrzej Jagielski 
255*6eae2aebSJedrzej Jagielski 	ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
2568210ff73SJedrzej Jagielski 	err = devlink_info_version_running_put(req, "fw.netlist", ctx->buf);
2578210ff73SJedrzej Jagielski 	if (err)
2588210ff73SJedrzej Jagielski 		return err;
2598210ff73SJedrzej Jagielski 
260*6eae2aebSJedrzej Jagielski 	ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
2618210ff73SJedrzej Jagielski 	return devlink_info_version_running_put(req, "fw.netlist.build",
2628210ff73SJedrzej Jagielski 						ctx->buf);
2638210ff73SJedrzej Jagielski }
2648210ff73SJedrzej Jagielski 
265*6eae2aebSJedrzej Jagielski static int
266*6eae2aebSJedrzej Jagielski ixgbe_devlink_pending_info_get_e610(struct ixgbe_adapter *adapter,
267*6eae2aebSJedrzej Jagielski 				    struct devlink_info_req *req,
268*6eae2aebSJedrzej Jagielski 				    struct ixgbe_info_ctx *ctx)
269*6eae2aebSJedrzej Jagielski {
270*6eae2aebSJedrzej Jagielski 	int err;
271*6eae2aebSJedrzej Jagielski 
272*6eae2aebSJedrzej Jagielski 	ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
273*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req,
274*6eae2aebSJedrzej Jagielski 					      DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
275*6eae2aebSJedrzej Jagielski 					      ctx->buf);
276*6eae2aebSJedrzej Jagielski 	if (err)
277*6eae2aebSJedrzej Jagielski 		return err;
278*6eae2aebSJedrzej Jagielski 
279*6eae2aebSJedrzej Jagielski 	ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_STORED);
280*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req,
281*6eae2aebSJedrzej Jagielski 					      DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
282*6eae2aebSJedrzej Jagielski 					      ctx->buf);
283*6eae2aebSJedrzej Jagielski 	if (err)
284*6eae2aebSJedrzej Jagielski 		return err;
285*6eae2aebSJedrzej Jagielski 
286*6eae2aebSJedrzej Jagielski 	ixgbe_info_fw_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
287*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req, "fw.mgmt.srev", ctx->buf);
288*6eae2aebSJedrzej Jagielski 	if (err)
289*6eae2aebSJedrzej Jagielski 		return err;
290*6eae2aebSJedrzej Jagielski 
291*6eae2aebSJedrzej Jagielski 	ixgbe_info_orom_srev(adapter, ctx, IXGBE_DL_VERSION_STORED);
292*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req, "fw.undi.srev", ctx->buf);
293*6eae2aebSJedrzej Jagielski 	if (err)
294*6eae2aebSJedrzej Jagielski 		return err;
295*6eae2aebSJedrzej Jagielski 
296*6eae2aebSJedrzej Jagielski 	ixgbe_info_nvm_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
297*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req, "fw.psid.api", ctx->buf);
298*6eae2aebSJedrzej Jagielski 	if (err)
299*6eae2aebSJedrzej Jagielski 		return err;
300*6eae2aebSJedrzej Jagielski 
301*6eae2aebSJedrzej Jagielski 	ixgbe_info_netlist_ver(adapter, ctx, IXGBE_DL_VERSION_STORED);
302*6eae2aebSJedrzej Jagielski 	err = devlink_info_version_stored_put(req, "fw.netlist", ctx->buf);
303*6eae2aebSJedrzej Jagielski 	if (err)
304*6eae2aebSJedrzej Jagielski 		return err;
305*6eae2aebSJedrzej Jagielski 
306*6eae2aebSJedrzej Jagielski 	ixgbe_info_netlist_build(adapter, ctx, IXGBE_DL_VERSION_STORED);
307*6eae2aebSJedrzej Jagielski 	return devlink_info_version_stored_put(req, "fw.netlist.build",
308*6eae2aebSJedrzej Jagielski 					       ctx->buf);
309*6eae2aebSJedrzej Jagielski }
310*6eae2aebSJedrzej Jagielski 
311f6b588afSJedrzej Jagielski static int ixgbe_devlink_info_get(struct devlink *devlink,
312f6b588afSJedrzej Jagielski 				  struct devlink_info_req *req,
313f6b588afSJedrzej Jagielski 				  struct netlink_ext_ack *extack)
314f6b588afSJedrzej Jagielski {
315f6b588afSJedrzej Jagielski 	struct ixgbe_adapter *adapter = devlink_priv(devlink);
316f6b588afSJedrzej Jagielski 	struct ixgbe_hw *hw = &adapter->hw;
317f6b588afSJedrzej Jagielski 	struct ixgbe_info_ctx *ctx;
318f6b588afSJedrzej Jagielski 	int err;
319f6b588afSJedrzej Jagielski 
320f6b588afSJedrzej Jagielski 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
321f6b588afSJedrzej Jagielski 	if (!ctx)
322f6b588afSJedrzej Jagielski 		return -ENOMEM;
323f6b588afSJedrzej Jagielski 
324f6b588afSJedrzej Jagielski 	ixgbe_info_get_dsn(adapter, ctx);
325f6b588afSJedrzej Jagielski 	err = devlink_info_serial_number_put(req, ctx->buf);
326f6b588afSJedrzej Jagielski 	if (err)
327f6b588afSJedrzej Jagielski 		goto free_ctx;
328f6b588afSJedrzej Jagielski 
3294654ec61SJedrzej Jagielski 	err = hw->eeprom.ops.read_pba_string(hw, ctx->buf, sizeof(ctx->buf));
330f6b588afSJedrzej Jagielski 	if (err)
331f6b588afSJedrzej Jagielski 		goto free_ctx;
332f6b588afSJedrzej Jagielski 
333f6b588afSJedrzej Jagielski 	err = devlink_info_version_fixed_put(req,
334f6b588afSJedrzej Jagielski 					     DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
335f6b588afSJedrzej Jagielski 					     ctx->buf);
336f6b588afSJedrzej Jagielski 	if (err)
337f6b588afSJedrzej Jagielski 		goto free_ctx;
338f6b588afSJedrzej Jagielski 
339*6eae2aebSJedrzej Jagielski 	ixgbe_info_orom_ver(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
340f6b588afSJedrzej Jagielski 	err = devlink_info_version_running_put(req,
341f6b588afSJedrzej Jagielski 					       DEVLINK_INFO_VERSION_GENERIC_FW_UNDI,
342f6b588afSJedrzej Jagielski 					       ctx->buf);
343f6b588afSJedrzej Jagielski 	if (err)
344f6b588afSJedrzej Jagielski 		goto free_ctx;
345f6b588afSJedrzej Jagielski 
346*6eae2aebSJedrzej Jagielski 	ixgbe_info_eetrack(adapter, ctx, IXGBE_DL_VERSION_RUNNING);
347f6b588afSJedrzej Jagielski 	err = devlink_info_version_running_put(req,
348f6b588afSJedrzej Jagielski 					       DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
349f6b588afSJedrzej Jagielski 					       ctx->buf);
3508210ff73SJedrzej Jagielski 	if (err || hw->mac.type != ixgbe_mac_e610)
3518210ff73SJedrzej Jagielski 		goto free_ctx;
3528210ff73SJedrzej Jagielski 
353*6eae2aebSJedrzej Jagielski 	err = ixgbe_set_ctx_dev_caps(hw, ctx, extack);
354*6eae2aebSJedrzej Jagielski 	if (err)
355*6eae2aebSJedrzej Jagielski 		goto free_ctx;
356*6eae2aebSJedrzej Jagielski 
3578210ff73SJedrzej Jagielski 	err = ixgbe_devlink_info_get_e610(adapter, req, ctx);
358*6eae2aebSJedrzej Jagielski 	if (err)
359*6eae2aebSJedrzej Jagielski 		goto free_ctx;
360*6eae2aebSJedrzej Jagielski 
361*6eae2aebSJedrzej Jagielski 	err = ixgbe_devlink_pending_info_get_e610(adapter, req, ctx);
362f6b588afSJedrzej Jagielski free_ctx:
363f6b588afSJedrzej Jagielski 	kfree(ctx);
364f6b588afSJedrzej Jagielski 	return err;
365f6b588afSJedrzej Jagielski }
366f6b588afSJedrzej Jagielski 
367a0285236SJedrzej Jagielski static const struct devlink_ops ixgbe_devlink_ops = {
368f6b588afSJedrzej Jagielski 	.info_get = ixgbe_devlink_info_get,
369a0285236SJedrzej Jagielski };
370a0285236SJedrzej Jagielski 
371a0285236SJedrzej Jagielski /**
372a0285236SJedrzej Jagielski  * ixgbe_allocate_devlink - Allocate devlink instance
373a0285236SJedrzej Jagielski  * @dev: device to allocate devlink for
374a0285236SJedrzej Jagielski  *
375a0285236SJedrzej Jagielski  * Allocate a devlink instance for this physical function.
376a0285236SJedrzej Jagielski  *
377a0285236SJedrzej Jagielski  * Return: pointer to the device adapter structure on success,
378a0285236SJedrzej Jagielski  * ERR_PTR(-ENOMEM) when allocation failed.
379a0285236SJedrzej Jagielski  */
380a0285236SJedrzej Jagielski struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev)
381a0285236SJedrzej Jagielski {
382a0285236SJedrzej Jagielski 	struct ixgbe_adapter *adapter;
383a0285236SJedrzej Jagielski 	struct devlink *devlink;
384a0285236SJedrzej Jagielski 
385a0285236SJedrzej Jagielski 	devlink = devlink_alloc(&ixgbe_devlink_ops, sizeof(*adapter), dev);
386a0285236SJedrzej Jagielski 	if (!devlink)
387a0285236SJedrzej Jagielski 		return ERR_PTR(-ENOMEM);
388a0285236SJedrzej Jagielski 
389a0285236SJedrzej Jagielski 	adapter = devlink_priv(devlink);
390a0285236SJedrzej Jagielski 	adapter->devlink = devlink;
391a0285236SJedrzej Jagielski 
392a0285236SJedrzej Jagielski 	return adapter;
393a0285236SJedrzej Jagielski }
394a0285236SJedrzej Jagielski 
395a0285236SJedrzej Jagielski /**
396a0285236SJedrzej Jagielski  * ixgbe_devlink_set_switch_id - Set unique switch ID based on PCI DSN
397a0285236SJedrzej Jagielski  * @adapter: pointer to the device adapter structure
398a0285236SJedrzej Jagielski  * @ppid: struct with switch id information
399a0285236SJedrzej Jagielski  */
400a0285236SJedrzej Jagielski static void ixgbe_devlink_set_switch_id(struct ixgbe_adapter *adapter,
401a0285236SJedrzej Jagielski 					struct netdev_phys_item_id *ppid)
402a0285236SJedrzej Jagielski {
403a0285236SJedrzej Jagielski 	u64 id = pci_get_dsn(adapter->pdev);
404a0285236SJedrzej Jagielski 
405a0285236SJedrzej Jagielski 	ppid->id_len = sizeof(id);
406a0285236SJedrzej Jagielski 	put_unaligned_be64(id, &ppid->id);
407a0285236SJedrzej Jagielski }
408a0285236SJedrzej Jagielski 
409a0285236SJedrzej Jagielski /**
410a0285236SJedrzej Jagielski  * ixgbe_devlink_register_port - Register devlink port
411a0285236SJedrzej Jagielski  * @adapter: pointer to the device adapter structure
412a0285236SJedrzej Jagielski  *
413a0285236SJedrzej Jagielski  * Create and register a devlink_port for this physical function.
414a0285236SJedrzej Jagielski  *
415a0285236SJedrzej Jagielski  * Return: 0 on success, error code on failure.
416a0285236SJedrzej Jagielski  */
417a0285236SJedrzej Jagielski int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter)
418a0285236SJedrzej Jagielski {
419a0285236SJedrzej Jagielski 	struct devlink_port *devlink_port = &adapter->devlink_port;
420a0285236SJedrzej Jagielski 	struct devlink *devlink = adapter->devlink;
421a0285236SJedrzej Jagielski 	struct device *dev = &adapter->pdev->dev;
422a0285236SJedrzej Jagielski 	struct devlink_port_attrs attrs = {};
423a0285236SJedrzej Jagielski 	int err;
424a0285236SJedrzej Jagielski 
425a0285236SJedrzej Jagielski 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
426a0285236SJedrzej Jagielski 	attrs.phys.port_number = adapter->hw.bus.func;
427a0285236SJedrzej Jagielski 	ixgbe_devlink_set_switch_id(adapter, &attrs.switch_id);
428a0285236SJedrzej Jagielski 
429a0285236SJedrzej Jagielski 	devlink_port_attrs_set(devlink_port, &attrs);
430a0285236SJedrzej Jagielski 
431a0285236SJedrzej Jagielski 	err = devl_port_register(devlink, devlink_port, 0);
432a0285236SJedrzej Jagielski 	if (err) {
433a0285236SJedrzej Jagielski 		dev_err(dev,
434a0285236SJedrzej Jagielski 			"devlink port registration failed, err %d\n", err);
435a0285236SJedrzej Jagielski 	}
436a0285236SJedrzej Jagielski 
437a0285236SJedrzej Jagielski 	return err;
438a0285236SJedrzej Jagielski }
439