xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/netronome/nfp/nfp_devlink.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2*4882a593Smuzhiyun /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/rtnetlink.h>
5*4882a593Smuzhiyun #include <net/devlink.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include "nfpcore/nfp.h"
8*4882a593Smuzhiyun #include "nfpcore/nfp_nsp.h"
9*4882a593Smuzhiyun #include "nfp_app.h"
10*4882a593Smuzhiyun #include "nfp_main.h"
11*4882a593Smuzhiyun #include "nfp_port.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun static int
nfp_devlink_fill_eth_port(struct nfp_port * port,struct nfp_eth_table_port * copy)14*4882a593Smuzhiyun nfp_devlink_fill_eth_port(struct nfp_port *port,
15*4882a593Smuzhiyun 			  struct nfp_eth_table_port *copy)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	struct nfp_eth_table_port *eth_port;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 	eth_port = __nfp_port_get_eth_port(port);
20*4882a593Smuzhiyun 	if (!eth_port)
21*4882a593Smuzhiyun 		return -EINVAL;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	memcpy(copy, eth_port, sizeof(*eth_port));
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	return 0;
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun static int
nfp_devlink_fill_eth_port_from_id(struct nfp_pf * pf,unsigned int port_index,struct nfp_eth_table_port * copy)29*4882a593Smuzhiyun nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf, unsigned int port_index,
30*4882a593Smuzhiyun 				  struct nfp_eth_table_port *copy)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	struct nfp_port *port;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	port = nfp_port_from_id(pf, NFP_PORT_PHYS_PORT, port_index);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	return nfp_devlink_fill_eth_port(port, copy);
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static int
nfp_devlink_set_lanes(struct nfp_pf * pf,unsigned int idx,unsigned int lanes)40*4882a593Smuzhiyun nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	struct nfp_nsp *nsp;
43*4882a593Smuzhiyun 	int ret;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	nsp = nfp_eth_config_start(pf->cpp, idx);
46*4882a593Smuzhiyun 	if (IS_ERR(nsp))
47*4882a593Smuzhiyun 		return PTR_ERR(nsp);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	ret = __nfp_eth_set_split(nsp, lanes);
50*4882a593Smuzhiyun 	if (ret) {
51*4882a593Smuzhiyun 		nfp_eth_config_cleanup_end(nsp);
52*4882a593Smuzhiyun 		return ret;
53*4882a593Smuzhiyun 	}
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	ret = nfp_eth_config_commit_end(nsp);
56*4882a593Smuzhiyun 	if (ret < 0)
57*4882a593Smuzhiyun 		return ret;
58*4882a593Smuzhiyun 	if (ret) /* no change */
59*4882a593Smuzhiyun 		return 0;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	return nfp_net_refresh_port_table_sync(pf);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun static int
nfp_devlink_port_split(struct devlink * devlink,unsigned int port_index,unsigned int count,struct netlink_ext_ack * extack)65*4882a593Smuzhiyun nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
66*4882a593Smuzhiyun 		       unsigned int count, struct netlink_ext_ack *extack)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
69*4882a593Smuzhiyun 	struct nfp_eth_table_port eth_port;
70*4882a593Smuzhiyun 	unsigned int lanes;
71*4882a593Smuzhiyun 	int ret;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	mutex_lock(&pf->lock);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	rtnl_lock();
76*4882a593Smuzhiyun 	ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port);
77*4882a593Smuzhiyun 	rtnl_unlock();
78*4882a593Smuzhiyun 	if (ret)
79*4882a593Smuzhiyun 		goto out;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	if (eth_port.port_lanes % count) {
82*4882a593Smuzhiyun 		ret = -EINVAL;
83*4882a593Smuzhiyun 		goto out;
84*4882a593Smuzhiyun 	}
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	/* Special case the 100G CXP -> 2x40G split */
87*4882a593Smuzhiyun 	lanes = eth_port.port_lanes / count;
88*4882a593Smuzhiyun 	if (eth_port.lanes == 10 && count == 2)
89*4882a593Smuzhiyun 		lanes = 8 / count;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	ret = nfp_devlink_set_lanes(pf, eth_port.index, lanes);
92*4882a593Smuzhiyun out:
93*4882a593Smuzhiyun 	mutex_unlock(&pf->lock);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	return ret;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun static int
nfp_devlink_port_unsplit(struct devlink * devlink,unsigned int port_index,struct netlink_ext_ack * extack)99*4882a593Smuzhiyun nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
100*4882a593Smuzhiyun 			 struct netlink_ext_ack *extack)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
103*4882a593Smuzhiyun 	struct nfp_eth_table_port eth_port;
104*4882a593Smuzhiyun 	unsigned int lanes;
105*4882a593Smuzhiyun 	int ret;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	mutex_lock(&pf->lock);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	rtnl_lock();
110*4882a593Smuzhiyun 	ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port);
111*4882a593Smuzhiyun 	rtnl_unlock();
112*4882a593Smuzhiyun 	if (ret)
113*4882a593Smuzhiyun 		goto out;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	if (!eth_port.is_split) {
116*4882a593Smuzhiyun 		ret = -EINVAL;
117*4882a593Smuzhiyun 		goto out;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	/* Special case the 100G CXP -> 2x40G unsplit */
121*4882a593Smuzhiyun 	lanes = eth_port.port_lanes;
122*4882a593Smuzhiyun 	if (eth_port.port_lanes == 8)
123*4882a593Smuzhiyun 		lanes = 10;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	ret = nfp_devlink_set_lanes(pf, eth_port.index, lanes);
126*4882a593Smuzhiyun out:
127*4882a593Smuzhiyun 	mutex_unlock(&pf->lock);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	return ret;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun static int
nfp_devlink_sb_pool_get(struct devlink * devlink,unsigned int sb_index,u16 pool_index,struct devlink_sb_pool_info * pool_info)133*4882a593Smuzhiyun nfp_devlink_sb_pool_get(struct devlink *devlink, unsigned int sb_index,
134*4882a593Smuzhiyun 			u16 pool_index, struct devlink_sb_pool_info *pool_info)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	return nfp_shared_buf_pool_get(pf, sb_index, pool_index, pool_info);
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun static int
nfp_devlink_sb_pool_set(struct devlink * devlink,unsigned int sb_index,u16 pool_index,u32 size,enum devlink_sb_threshold_type threshold_type,struct netlink_ext_ack * extack)142*4882a593Smuzhiyun nfp_devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
143*4882a593Smuzhiyun 			u16 pool_index,
144*4882a593Smuzhiyun 			u32 size, enum devlink_sb_threshold_type threshold_type,
145*4882a593Smuzhiyun 			struct netlink_ext_ack *extack)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	return nfp_shared_buf_pool_set(pf, sb_index, pool_index,
150*4882a593Smuzhiyun 				       size, threshold_type);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
nfp_devlink_eswitch_mode_get(struct devlink * devlink,u16 * mode)153*4882a593Smuzhiyun static int nfp_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	return nfp_app_eswitch_mode_get(pf->app, mode);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
nfp_devlink_eswitch_mode_set(struct devlink * devlink,u16 mode,struct netlink_ext_ack * extack)160*4882a593Smuzhiyun static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
161*4882a593Smuzhiyun 					struct netlink_ext_ack *extack)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
164*4882a593Smuzhiyun 	int ret;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	mutex_lock(&pf->lock);
167*4882a593Smuzhiyun 	ret = nfp_app_eswitch_mode_set(pf->app, mode);
168*4882a593Smuzhiyun 	mutex_unlock(&pf->lock);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	return ret;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static const struct nfp_devlink_versions_simple {
174*4882a593Smuzhiyun 	const char *key;
175*4882a593Smuzhiyun 	const char *hwinfo;
176*4882a593Smuzhiyun } nfp_devlink_versions_hwinfo[] = {
177*4882a593Smuzhiyun 	{ DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,	"assembly.partno", },
178*4882a593Smuzhiyun 	{ DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,	"assembly.revision", },
179*4882a593Smuzhiyun 	{ DEVLINK_INFO_VERSION_GENERIC_BOARD_MANUFACTURE, "assembly.vendor", },
180*4882a593Smuzhiyun 	{ "board.model", /* code name */		"assembly.model", },
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun static int
nfp_devlink_versions_get_hwinfo(struct nfp_pf * pf,struct devlink_info_req * req)184*4882a593Smuzhiyun nfp_devlink_versions_get_hwinfo(struct nfp_pf *pf, struct devlink_info_req *req)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	unsigned int i;
187*4882a593Smuzhiyun 	int err;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_hwinfo); i++) {
190*4882a593Smuzhiyun 		const struct nfp_devlink_versions_simple *info;
191*4882a593Smuzhiyun 		const char *val;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 		info = &nfp_devlink_versions_hwinfo[i];
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 		val = nfp_hwinfo_lookup(pf->hwinfo, info->hwinfo);
196*4882a593Smuzhiyun 		if (!val)
197*4882a593Smuzhiyun 			continue;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		err = devlink_info_version_fixed_put(req, info->key, val);
200*4882a593Smuzhiyun 		if (err)
201*4882a593Smuzhiyun 			return err;
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	return 0;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun static const struct nfp_devlink_versions {
208*4882a593Smuzhiyun 	enum nfp_nsp_versions id;
209*4882a593Smuzhiyun 	const char *key;
210*4882a593Smuzhiyun } nfp_devlink_versions_nsp[] = {
211*4882a593Smuzhiyun 	{ NFP_VERSIONS_BUNDLE,	DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, },
212*4882a593Smuzhiyun 	{ NFP_VERSIONS_BSP,	DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, },
213*4882a593Smuzhiyun 	{ NFP_VERSIONS_CPLD,	"fw.cpld", },
214*4882a593Smuzhiyun 	{ NFP_VERSIONS_APP,	DEVLINK_INFO_VERSION_GENERIC_FW_APP, },
215*4882a593Smuzhiyun 	{ NFP_VERSIONS_UNDI,	DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, },
216*4882a593Smuzhiyun 	{ NFP_VERSIONS_NCSI,	DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, },
217*4882a593Smuzhiyun 	{ NFP_VERSIONS_CFGR,	"chip.init", },
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun static int
nfp_devlink_versions_get_nsp(struct devlink_info_req * req,bool flash,const u8 * buf,unsigned int size)221*4882a593Smuzhiyun nfp_devlink_versions_get_nsp(struct devlink_info_req *req, bool flash,
222*4882a593Smuzhiyun 			     const u8 *buf, unsigned int size)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun 	unsigned int i;
225*4882a593Smuzhiyun 	int err;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_nsp); i++) {
228*4882a593Smuzhiyun 		const struct nfp_devlink_versions *info;
229*4882a593Smuzhiyun 		const char *version;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 		info = &nfp_devlink_versions_nsp[i];
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 		version = nfp_nsp_versions_get(info->id, flash, buf, size);
234*4882a593Smuzhiyun 		if (IS_ERR(version)) {
235*4882a593Smuzhiyun 			if (PTR_ERR(version) == -ENOENT)
236*4882a593Smuzhiyun 				continue;
237*4882a593Smuzhiyun 			else
238*4882a593Smuzhiyun 				return PTR_ERR(version);
239*4882a593Smuzhiyun 		}
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 		if (flash)
242*4882a593Smuzhiyun 			err = devlink_info_version_stored_put(req, info->key,
243*4882a593Smuzhiyun 							      version);
244*4882a593Smuzhiyun 		else
245*4882a593Smuzhiyun 			err = devlink_info_version_running_put(req, info->key,
246*4882a593Smuzhiyun 							       version);
247*4882a593Smuzhiyun 		if (err)
248*4882a593Smuzhiyun 			return err;
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	return 0;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun static int
nfp_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)255*4882a593Smuzhiyun nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
256*4882a593Smuzhiyun 		     struct netlink_ext_ack *extack)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	struct nfp_pf *pf = devlink_priv(devlink);
259*4882a593Smuzhiyun 	const char *sn, *vendor, *part;
260*4882a593Smuzhiyun 	struct nfp_nsp *nsp;
261*4882a593Smuzhiyun 	char *buf = NULL;
262*4882a593Smuzhiyun 	int err;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	err = devlink_info_driver_name_put(req, "nfp");
265*4882a593Smuzhiyun 	if (err)
266*4882a593Smuzhiyun 		return err;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	vendor = nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor");
269*4882a593Smuzhiyun 	part = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno");
270*4882a593Smuzhiyun 	sn = nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial");
271*4882a593Smuzhiyun 	if (vendor && part && sn) {
272*4882a593Smuzhiyun 		char *buf;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		buf = kmalloc(strlen(vendor) + strlen(part) + strlen(sn) + 1,
275*4882a593Smuzhiyun 			      GFP_KERNEL);
276*4882a593Smuzhiyun 		if (!buf)
277*4882a593Smuzhiyun 			return -ENOMEM;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 		buf[0] = '\0';
280*4882a593Smuzhiyun 		strcat(buf, vendor);
281*4882a593Smuzhiyun 		strcat(buf, part);
282*4882a593Smuzhiyun 		strcat(buf, sn);
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 		err = devlink_info_serial_number_put(req, buf);
285*4882a593Smuzhiyun 		kfree(buf);
286*4882a593Smuzhiyun 		if (err)
287*4882a593Smuzhiyun 			return err;
288*4882a593Smuzhiyun 	}
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	nsp = nfp_nsp_open(pf->cpp);
291*4882a593Smuzhiyun 	if (IS_ERR(nsp)) {
292*4882a593Smuzhiyun 		NL_SET_ERR_MSG_MOD(extack, "can't access NSP");
293*4882a593Smuzhiyun 		return PTR_ERR(nsp);
294*4882a593Smuzhiyun 	}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	if (nfp_nsp_has_versions(nsp)) {
297*4882a593Smuzhiyun 		buf = kzalloc(NFP_NSP_VERSION_BUFSZ, GFP_KERNEL);
298*4882a593Smuzhiyun 		if (!buf) {
299*4882a593Smuzhiyun 			err = -ENOMEM;
300*4882a593Smuzhiyun 			goto err_close_nsp;
301*4882a593Smuzhiyun 		}
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 		err = nfp_nsp_versions(nsp, buf, NFP_NSP_VERSION_BUFSZ);
304*4882a593Smuzhiyun 		if (err)
305*4882a593Smuzhiyun 			goto err_free_buf;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 		err = nfp_devlink_versions_get_nsp(req, false,
308*4882a593Smuzhiyun 						   buf, NFP_NSP_VERSION_BUFSZ);
309*4882a593Smuzhiyun 		if (err)
310*4882a593Smuzhiyun 			goto err_free_buf;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 		err = nfp_devlink_versions_get_nsp(req, true,
313*4882a593Smuzhiyun 						   buf, NFP_NSP_VERSION_BUFSZ);
314*4882a593Smuzhiyun 		if (err)
315*4882a593Smuzhiyun 			goto err_free_buf;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 		kfree(buf);
318*4882a593Smuzhiyun 	}
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	nfp_nsp_close(nsp);
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	return nfp_devlink_versions_get_hwinfo(pf, req);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun err_free_buf:
325*4882a593Smuzhiyun 	kfree(buf);
326*4882a593Smuzhiyun err_close_nsp:
327*4882a593Smuzhiyun 	nfp_nsp_close(nsp);
328*4882a593Smuzhiyun 	return err;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun static int
nfp_devlink_flash_update(struct devlink * devlink,struct devlink_flash_update_params * params,struct netlink_ext_ack * extack)332*4882a593Smuzhiyun nfp_devlink_flash_update(struct devlink *devlink,
333*4882a593Smuzhiyun 			 struct devlink_flash_update_params *params,
334*4882a593Smuzhiyun 			 struct netlink_ext_ack *extack)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun const struct devlink_ops nfp_devlink_ops = {
340*4882a593Smuzhiyun 	.port_split		= nfp_devlink_port_split,
341*4882a593Smuzhiyun 	.port_unsplit		= nfp_devlink_port_unsplit,
342*4882a593Smuzhiyun 	.sb_pool_get		= nfp_devlink_sb_pool_get,
343*4882a593Smuzhiyun 	.sb_pool_set		= nfp_devlink_sb_pool_set,
344*4882a593Smuzhiyun 	.eswitch_mode_get	= nfp_devlink_eswitch_mode_get,
345*4882a593Smuzhiyun 	.eswitch_mode_set	= nfp_devlink_eswitch_mode_set,
346*4882a593Smuzhiyun 	.info_get		= nfp_devlink_info_get,
347*4882a593Smuzhiyun 	.flash_update		= nfp_devlink_flash_update,
348*4882a593Smuzhiyun };
349*4882a593Smuzhiyun 
nfp_devlink_port_register(struct nfp_app * app,struct nfp_port * port)350*4882a593Smuzhiyun int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun 	struct devlink_port_attrs attrs = {};
353*4882a593Smuzhiyun 	struct nfp_eth_table_port eth_port;
354*4882a593Smuzhiyun 	struct devlink *devlink;
355*4882a593Smuzhiyun 	const u8 *serial;
356*4882a593Smuzhiyun 	int serial_len;
357*4882a593Smuzhiyun 	int ret;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	rtnl_lock();
360*4882a593Smuzhiyun 	ret = nfp_devlink_fill_eth_port(port, &eth_port);
361*4882a593Smuzhiyun 	rtnl_unlock();
362*4882a593Smuzhiyun 	if (ret)
363*4882a593Smuzhiyun 		return ret;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	attrs.split = eth_port.is_split;
366*4882a593Smuzhiyun 	attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
367*4882a593Smuzhiyun 	attrs.lanes = eth_port.port_lanes;
368*4882a593Smuzhiyun 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
369*4882a593Smuzhiyun 	attrs.phys.port_number = eth_port.label_port;
370*4882a593Smuzhiyun 	attrs.phys.split_subport_number = eth_port.label_subport;
371*4882a593Smuzhiyun 	serial_len = nfp_cpp_serial(port->app->cpp, &serial);
372*4882a593Smuzhiyun 	memcpy(attrs.switch_id.id, serial, serial_len);
373*4882a593Smuzhiyun 	attrs.switch_id.id_len = serial_len;
374*4882a593Smuzhiyun 	devlink_port_attrs_set(&port->dl_port, &attrs);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	devlink = priv_to_devlink(app->pf);
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	return devlink_port_register(devlink, &port->dl_port, port->eth_id);
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun 
nfp_devlink_port_unregister(struct nfp_port * port)381*4882a593Smuzhiyun void nfp_devlink_port_unregister(struct nfp_port *port)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun 	devlink_port_unregister(&port->dl_port);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun 
nfp_devlink_port_type_eth_set(struct nfp_port * port)386*4882a593Smuzhiyun void nfp_devlink_port_type_eth_set(struct nfp_port *port)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun 	devlink_port_type_eth_set(&port->dl_port, port->netdev);
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
nfp_devlink_port_type_clear(struct nfp_port * port)391*4882a593Smuzhiyun void nfp_devlink_port_type_clear(struct nfp_port *port)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	devlink_port_type_clear(&port->dl_port);
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
nfp_devlink_get_devlink_port(struct net_device * netdev)396*4882a593Smuzhiyun struct devlink_port *nfp_devlink_get_devlink_port(struct net_device *netdev)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	struct nfp_port *port;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	port = nfp_port_from_netdev(netdev);
401*4882a593Smuzhiyun 	if (!port)
402*4882a593Smuzhiyun 		return NULL;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	return &port->dl_port;
405*4882a593Smuzhiyun }
406