196de2506SJakub Kicinski // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
296de2506SJakub Kicinski /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
31851f93fSSimon Horman
453e7a08fSJakub Kicinski #include <linux/rtnetlink.h>
51851f93fSSimon Horman #include <net/devlink.h>
61851f93fSSimon Horman
74adba008SJakub Kicinski #include "nfpcore/nfp.h"
853e7a08fSJakub Kicinski #include "nfpcore/nfp_nsp.h"
953e7a08fSJakub Kicinski #include "nfp_app.h"
101851f93fSSimon Horman #include "nfp_main.h"
1153e7a08fSJakub Kicinski #include "nfp_port.h"
1253e7a08fSJakub Kicinski
1353e7a08fSJakub Kicinski static int
nfp_devlink_fill_eth_port(struct nfp_port * port,struct nfp_eth_table_port * copy)1453e7a08fSJakub Kicinski nfp_devlink_fill_eth_port(struct nfp_port *port,
1553e7a08fSJakub Kicinski struct nfp_eth_table_port *copy)
1653e7a08fSJakub Kicinski {
1753e7a08fSJakub Kicinski struct nfp_eth_table_port *eth_port;
1853e7a08fSJakub Kicinski
1953e7a08fSJakub Kicinski eth_port = __nfp_port_get_eth_port(port);
2053e7a08fSJakub Kicinski if (!eth_port)
2153e7a08fSJakub Kicinski return -EINVAL;
2253e7a08fSJakub Kicinski
2353e7a08fSJakub Kicinski memcpy(copy, eth_port, sizeof(*eth_port));
2453e7a08fSJakub Kicinski
2553e7a08fSJakub Kicinski return 0;
2653e7a08fSJakub Kicinski }
271851f93fSSimon Horman
28ec8b1fbeSJakub Kicinski static int
nfp_devlink_fill_eth_port_from_id(struct nfp_pf * pf,struct devlink_port * dl_port,struct nfp_eth_table_port * copy)29706217c1SJakub Kicinski nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf,
30706217c1SJakub Kicinski struct devlink_port *dl_port,
31ec8b1fbeSJakub Kicinski struct nfp_eth_table_port *copy)
32ec8b1fbeSJakub Kicinski {
33706217c1SJakub Kicinski struct nfp_port *port = container_of(dl_port, struct nfp_port, dl_port);
34ec8b1fbeSJakub Kicinski
35ec8b1fbeSJakub Kicinski return nfp_devlink_fill_eth_port(port, copy);
36ec8b1fbeSJakub Kicinski }
37ec8b1fbeSJakub Kicinski
38ec8b1fbeSJakub Kicinski static int
nfp_devlink_set_lanes(struct nfp_pf * pf,unsigned int idx,unsigned int lanes)39ec8b1fbeSJakub Kicinski nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes)
40ec8b1fbeSJakub Kicinski {
41ec8b1fbeSJakub Kicinski struct nfp_nsp *nsp;
42ec8b1fbeSJakub Kicinski int ret;
43ec8b1fbeSJakub Kicinski
44ec8b1fbeSJakub Kicinski nsp = nfp_eth_config_start(pf->cpp, idx);
45ec8b1fbeSJakub Kicinski if (IS_ERR(nsp))
46ec8b1fbeSJakub Kicinski return PTR_ERR(nsp);
47ec8b1fbeSJakub Kicinski
48ec8b1fbeSJakub Kicinski ret = __nfp_eth_set_split(nsp, lanes);
49ec8b1fbeSJakub Kicinski if (ret) {
50ec8b1fbeSJakub Kicinski nfp_eth_config_cleanup_end(nsp);
51ec8b1fbeSJakub Kicinski return ret;
52ec8b1fbeSJakub Kicinski }
53ec8b1fbeSJakub Kicinski
54ec8b1fbeSJakub Kicinski ret = nfp_eth_config_commit_end(nsp);
55ec8b1fbeSJakub Kicinski if (ret < 0)
56ec8b1fbeSJakub Kicinski return ret;
57ec8b1fbeSJakub Kicinski if (ret) /* no change */
58ec8b1fbeSJakub Kicinski return 0;
59ec8b1fbeSJakub Kicinski
60ec8b1fbeSJakub Kicinski return nfp_net_refresh_port_table_sync(pf);
61ec8b1fbeSJakub Kicinski }
62ec8b1fbeSJakub Kicinski
63ec8b1fbeSJakub Kicinski static int
nfp_devlink_port_split(struct devlink * devlink,struct devlink_port * port,unsigned int count,struct netlink_ext_ack * extack)64706217c1SJakub Kicinski nfp_devlink_port_split(struct devlink *devlink, struct devlink_port *port,
65ac0fc8a1SDavid Ahern unsigned int count, struct netlink_ext_ack *extack)
66ec8b1fbeSJakub Kicinski {
67ec8b1fbeSJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
68ec8b1fbeSJakub Kicinski struct nfp_eth_table_port eth_port;
695948185bSRyan C Goodfellow unsigned int lanes;
70ec8b1fbeSJakub Kicinski int ret;
71ec8b1fbeSJakub Kicinski
72ec8b1fbeSJakub Kicinski rtnl_lock();
73706217c1SJakub Kicinski ret = nfp_devlink_fill_eth_port_from_id(pf, port, ð_port);
74ec8b1fbeSJakub Kicinski rtnl_unlock();
75ec8b1fbeSJakub Kicinski if (ret)
7649e83bbeSJakub Kicinski return ret;
77ec8b1fbeSJakub Kicinski
7849e83bbeSJakub Kicinski if (eth_port.port_lanes % count)
7949e83bbeSJakub Kicinski return -EINVAL;
80ec8b1fbeSJakub Kicinski
815948185bSRyan C Goodfellow /* Special case the 100G CXP -> 2x40G split */
825948185bSRyan C Goodfellow lanes = eth_port.port_lanes / count;
835948185bSRyan C Goodfellow if (eth_port.lanes == 10 && count == 2)
845948185bSRyan C Goodfellow lanes = 8 / count;
855948185bSRyan C Goodfellow
8649e83bbeSJakub Kicinski return nfp_devlink_set_lanes(pf, eth_port.index, lanes);
87ec8b1fbeSJakub Kicinski }
88ec8b1fbeSJakub Kicinski
89ec8b1fbeSJakub Kicinski static int
nfp_devlink_port_unsplit(struct devlink * devlink,struct devlink_port * port,struct netlink_ext_ack * extack)90706217c1SJakub Kicinski nfp_devlink_port_unsplit(struct devlink *devlink, struct devlink_port *port,
91ac0fc8a1SDavid Ahern struct netlink_ext_ack *extack)
92ec8b1fbeSJakub Kicinski {
93ec8b1fbeSJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
94ec8b1fbeSJakub Kicinski struct nfp_eth_table_port eth_port;
955948185bSRyan C Goodfellow unsigned int lanes;
96ec8b1fbeSJakub Kicinski int ret;
97ec8b1fbeSJakub Kicinski
98ec8b1fbeSJakub Kicinski rtnl_lock();
99706217c1SJakub Kicinski ret = nfp_devlink_fill_eth_port_from_id(pf, port, ð_port);
100ec8b1fbeSJakub Kicinski rtnl_unlock();
101ec8b1fbeSJakub Kicinski if (ret)
10249e83bbeSJakub Kicinski return ret;
103ec8b1fbeSJakub Kicinski
10449e83bbeSJakub Kicinski if (!eth_port.is_split)
10549e83bbeSJakub Kicinski return -EINVAL;
106ec8b1fbeSJakub Kicinski
1075948185bSRyan C Goodfellow /* Special case the 100G CXP -> 2x40G unsplit */
1085948185bSRyan C Goodfellow lanes = eth_port.port_lanes;
1095948185bSRyan C Goodfellow if (eth_port.port_lanes == 8)
1105948185bSRyan C Goodfellow lanes = 10;
1115948185bSRyan C Goodfellow
11249e83bbeSJakub Kicinski return nfp_devlink_set_lanes(pf, eth_port.index, lanes);
113ec8b1fbeSJakub Kicinski }
114ec8b1fbeSJakub Kicinski
115a0d163f4SJakub Kicinski static int
nfp_devlink_sb_pool_get(struct devlink * devlink,unsigned int sb_index,u16 pool_index,struct devlink_sb_pool_info * pool_info)116a0d163f4SJakub Kicinski nfp_devlink_sb_pool_get(struct devlink *devlink, unsigned int sb_index,
117a0d163f4SJakub Kicinski u16 pool_index, struct devlink_sb_pool_info *pool_info)
118a0d163f4SJakub Kicinski {
119a0d163f4SJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
120a0d163f4SJakub Kicinski
121a0d163f4SJakub Kicinski return nfp_shared_buf_pool_get(pf, sb_index, pool_index, pool_info);
122a0d163f4SJakub Kicinski }
123a0d163f4SJakub Kicinski
124a0d163f4SJakub Kicinski 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)125a0d163f4SJakub Kicinski nfp_devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
126a0d163f4SJakub Kicinski u16 pool_index,
127f2ad1a52SIdo Schimmel u32 size, enum devlink_sb_threshold_type threshold_type,
128f2ad1a52SIdo Schimmel struct netlink_ext_ack *extack)
129a0d163f4SJakub Kicinski {
130a0d163f4SJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
131a0d163f4SJakub Kicinski
132a0d163f4SJakub Kicinski return nfp_shared_buf_pool_set(pf, sb_index, pool_index,
133a0d163f4SJakub Kicinski size, threshold_type);
134a0d163f4SJakub Kicinski }
135a0d163f4SJakub Kicinski
nfp_devlink_eswitch_mode_get(struct devlink * devlink,u16 * mode)1369daee04aSJakub Kicinski static int nfp_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
1379daee04aSJakub Kicinski {
1389daee04aSJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
1399daee04aSJakub Kicinski
140bcc93a23SJakub Kicinski return nfp_app_eswitch_mode_get(pf->app, mode);
1419daee04aSJakub Kicinski }
1429daee04aSJakub Kicinski
nfp_devlink_eswitch_mode_set(struct devlink * devlink,u16 mode,struct netlink_ext_ack * extack)143db7ff19eSEli Britstein static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
144db7ff19eSEli Britstein struct netlink_ext_ack *extack)
1454afa3af4SJakub Kicinski {
1464afa3af4SJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
1474afa3af4SJakub Kicinski
14814e426bfSJakub Kicinski return nfp_app_eswitch_mode_set(pf->app, mode);
1494afa3af4SJakub Kicinski }
1504afa3af4SJakub Kicinski
151937a3e26SJakub Kicinski static const struct nfp_devlink_versions_simple {
152937a3e26SJakub Kicinski const char *key;
153937a3e26SJakub Kicinski const char *hwinfo;
154937a3e26SJakub Kicinski } nfp_devlink_versions_hwinfo[] = {
155937a3e26SJakub Kicinski { DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, "assembly.partno", },
156937a3e26SJakub Kicinski { DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, "assembly.revision", },
15705fe4ab7SJakub Kicinski { DEVLINK_INFO_VERSION_GENERIC_BOARD_MANUFACTURE, "assembly.vendor", },
158937a3e26SJakub Kicinski { "board.model", /* code name */ "assembly.model", },
159937a3e26SJakub Kicinski };
160937a3e26SJakub Kicinski
161937a3e26SJakub Kicinski static int
nfp_devlink_versions_get_hwinfo(struct nfp_pf * pf,struct devlink_info_req * req)162937a3e26SJakub Kicinski nfp_devlink_versions_get_hwinfo(struct nfp_pf *pf, struct devlink_info_req *req)
163937a3e26SJakub Kicinski {
164937a3e26SJakub Kicinski unsigned int i;
165937a3e26SJakub Kicinski int err;
166937a3e26SJakub Kicinski
167937a3e26SJakub Kicinski for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_hwinfo); i++) {
168937a3e26SJakub Kicinski const struct nfp_devlink_versions_simple *info;
169937a3e26SJakub Kicinski const char *val;
170937a3e26SJakub Kicinski
171937a3e26SJakub Kicinski info = &nfp_devlink_versions_hwinfo[i];
172937a3e26SJakub Kicinski
173937a3e26SJakub Kicinski val = nfp_hwinfo_lookup(pf->hwinfo, info->hwinfo);
174937a3e26SJakub Kicinski if (!val)
175937a3e26SJakub Kicinski continue;
176937a3e26SJakub Kicinski
177937a3e26SJakub Kicinski err = devlink_info_version_fixed_put(req, info->key, val);
178937a3e26SJakub Kicinski if (err)
179937a3e26SJakub Kicinski return err;
180937a3e26SJakub Kicinski }
181937a3e26SJakub Kicinski
182937a3e26SJakub Kicinski return 0;
183937a3e26SJakub Kicinski }
184937a3e26SJakub Kicinski
1857c908f46SJakub Kicinski static const struct nfp_devlink_versions {
1867c908f46SJakub Kicinski enum nfp_nsp_versions id;
1877c908f46SJakub Kicinski const char *key;
1887c908f46SJakub Kicinski } nfp_devlink_versions_nsp[] = {
189c90977a3SJacob Keller { NFP_VERSIONS_BUNDLE, DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, },
1907c908f46SJakub Kicinski { NFP_VERSIONS_BSP, DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, },
1917c908f46SJakub Kicinski { NFP_VERSIONS_CPLD, "fw.cpld", },
1927c908f46SJakub Kicinski { NFP_VERSIONS_APP, DEVLINK_INFO_VERSION_GENERIC_FW_APP, },
1937c908f46SJakub Kicinski { NFP_VERSIONS_UNDI, DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, },
1947c908f46SJakub Kicinski { NFP_VERSIONS_NCSI, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, },
1957c908f46SJakub Kicinski { NFP_VERSIONS_CFGR, "chip.init", },
1967c908f46SJakub Kicinski };
1977c908f46SJakub Kicinski
1987c908f46SJakub Kicinski static int
nfp_devlink_versions_get_nsp(struct devlink_info_req * req,bool flash,const u8 * buf,unsigned int size)1997c908f46SJakub Kicinski nfp_devlink_versions_get_nsp(struct devlink_info_req *req, bool flash,
2007c908f46SJakub Kicinski const u8 *buf, unsigned int size)
2017c908f46SJakub Kicinski {
2027c908f46SJakub Kicinski unsigned int i;
2037c908f46SJakub Kicinski int err;
2047c908f46SJakub Kicinski
2057c908f46SJakub Kicinski for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_nsp); i++) {
2067c908f46SJakub Kicinski const struct nfp_devlink_versions *info;
2077c908f46SJakub Kicinski const char *version;
2087c908f46SJakub Kicinski
2097c908f46SJakub Kicinski info = &nfp_devlink_versions_nsp[i];
2107c908f46SJakub Kicinski
2117c908f46SJakub Kicinski version = nfp_nsp_versions_get(info->id, flash, buf, size);
2127c908f46SJakub Kicinski if (IS_ERR(version)) {
2137c908f46SJakub Kicinski if (PTR_ERR(version) == -ENOENT)
2147c908f46SJakub Kicinski continue;
2157c908f46SJakub Kicinski else
2167c908f46SJakub Kicinski return PTR_ERR(version);
2177c908f46SJakub Kicinski }
2187c908f46SJakub Kicinski
2197c908f46SJakub Kicinski if (flash)
2207c908f46SJakub Kicinski err = devlink_info_version_stored_put(req, info->key,
2217c908f46SJakub Kicinski version);
2227c908f46SJakub Kicinski else
2237c908f46SJakub Kicinski err = devlink_info_version_running_put(req, info->key,
2247c908f46SJakub Kicinski version);
2257c908f46SJakub Kicinski if (err)
2267c908f46SJakub Kicinski return err;
2277c908f46SJakub Kicinski }
2287c908f46SJakub Kicinski
2297c908f46SJakub Kicinski return 0;
2307c908f46SJakub Kicinski }
2317c908f46SJakub Kicinski
2324adba008SJakub Kicinski static int
nfp_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)2334adba008SJakub Kicinski nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
2344adba008SJakub Kicinski struct netlink_ext_ack *extack)
2354adba008SJakub Kicinski {
2364adba008SJakub Kicinski struct nfp_pf *pf = devlink_priv(devlink);
2371f5cf103SJakub Kicinski const char *sn, *vendor, *part;
2387c908f46SJakub Kicinski struct nfp_nsp *nsp;
2397c908f46SJakub Kicinski char *buf = NULL;
2404adba008SJakub Kicinski int err;
2414adba008SJakub Kicinski
2421f5cf103SJakub Kicinski vendor = nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor");
2431f5cf103SJakub Kicinski part = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno");
2444adba008SJakub Kicinski sn = nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial");
2451f5cf103SJakub Kicinski if (vendor && part && sn) {
2461f5cf103SJakub Kicinski char *buf;
2471f5cf103SJakub Kicinski
2481f5cf103SJakub Kicinski buf = kmalloc(strlen(vendor) + strlen(part) + strlen(sn) + 1,
2491f5cf103SJakub Kicinski GFP_KERNEL);
2501f5cf103SJakub Kicinski if (!buf)
2511f5cf103SJakub Kicinski return -ENOMEM;
2521f5cf103SJakub Kicinski
2531f5cf103SJakub Kicinski buf[0] = '\0';
2541f5cf103SJakub Kicinski strcat(buf, vendor);
2551f5cf103SJakub Kicinski strcat(buf, part);
2561f5cf103SJakub Kicinski strcat(buf, sn);
2571f5cf103SJakub Kicinski
2581f5cf103SJakub Kicinski err = devlink_info_serial_number_put(req, buf);
2591f5cf103SJakub Kicinski kfree(buf);
2604adba008SJakub Kicinski if (err)
2614adba008SJakub Kicinski return err;
2624adba008SJakub Kicinski }
2634adba008SJakub Kicinski
2647c908f46SJakub Kicinski nsp = nfp_nsp_open(pf->cpp);
2657c908f46SJakub Kicinski if (IS_ERR(nsp)) {
2667c908f46SJakub Kicinski NL_SET_ERR_MSG_MOD(extack, "can't access NSP");
2677c908f46SJakub Kicinski return PTR_ERR(nsp);
2687c908f46SJakub Kicinski }
2697c908f46SJakub Kicinski
2707c908f46SJakub Kicinski if (nfp_nsp_has_versions(nsp)) {
2717c908f46SJakub Kicinski buf = kzalloc(NFP_NSP_VERSION_BUFSZ, GFP_KERNEL);
2727c908f46SJakub Kicinski if (!buf) {
2737c908f46SJakub Kicinski err = -ENOMEM;
2747c908f46SJakub Kicinski goto err_close_nsp;
2757c908f46SJakub Kicinski }
2767c908f46SJakub Kicinski
2777c908f46SJakub Kicinski err = nfp_nsp_versions(nsp, buf, NFP_NSP_VERSION_BUFSZ);
2787c908f46SJakub Kicinski if (err)
2797c908f46SJakub Kicinski goto err_free_buf;
2807c908f46SJakub Kicinski
2817c908f46SJakub Kicinski err = nfp_devlink_versions_get_nsp(req, false,
2827c908f46SJakub Kicinski buf, NFP_NSP_VERSION_BUFSZ);
2837c908f46SJakub Kicinski if (err)
2847c908f46SJakub Kicinski goto err_free_buf;
2857c908f46SJakub Kicinski
2867c908f46SJakub Kicinski err = nfp_devlink_versions_get_nsp(req, true,
2877c908f46SJakub Kicinski buf, NFP_NSP_VERSION_BUFSZ);
2887c908f46SJakub Kicinski if (err)
2897c908f46SJakub Kicinski goto err_free_buf;
2907c908f46SJakub Kicinski
2917c908f46SJakub Kicinski kfree(buf);
2927c908f46SJakub Kicinski }
2937c908f46SJakub Kicinski
2947c908f46SJakub Kicinski nfp_nsp_close(nsp);
2957c908f46SJakub Kicinski
296937a3e26SJakub Kicinski return nfp_devlink_versions_get_hwinfo(pf, req);
2977c908f46SJakub Kicinski
2987c908f46SJakub Kicinski err_free_buf:
2997c908f46SJakub Kicinski kfree(buf);
3007c908f46SJakub Kicinski err_close_nsp:
3017c908f46SJakub Kicinski nfp_nsp_close(nsp);
3027c908f46SJakub Kicinski return err;
3034adba008SJakub Kicinski }
3044adba008SJakub Kicinski
3055c5696f3SJakub Kicinski static int
nfp_devlink_flash_update(struct devlink * devlink,struct devlink_flash_update_params * params,struct netlink_ext_ack * extack)306bc75c054SJacob Keller nfp_devlink_flash_update(struct devlink *devlink,
307bc75c054SJacob Keller struct devlink_flash_update_params *params,
308bc75c054SJacob Keller struct netlink_ext_ack *extack)
3095c5696f3SJakub Kicinski {
310b44cfd4fSJacob Keller return nfp_flash_update_common(devlink_priv(devlink), params->fw, extack);
3115c5696f3SJakub Kicinski }
3125c5696f3SJakub Kicinski
3131851f93fSSimon Horman const struct devlink_ops nfp_devlink_ops = {
314a0d163f4SJakub Kicinski .sb_pool_get = nfp_devlink_sb_pool_get,
315a0d163f4SJakub Kicinski .sb_pool_set = nfp_devlink_sb_pool_set,
3169daee04aSJakub Kicinski .eswitch_mode_get = nfp_devlink_eswitch_mode_get,
3174afa3af4SJakub Kicinski .eswitch_mode_set = nfp_devlink_eswitch_mode_set,
3184adba008SJakub Kicinski .info_get = nfp_devlink_info_get,
3195c5696f3SJakub Kicinski .flash_update = nfp_devlink_flash_update,
3201851f93fSSimon Horman };
32153e7a08fSJakub Kicinski
322ab8ccc6cSJiri Pirko static const struct devlink_port_ops nfp_devlink_port_ops = {
323*f58a3e4dSJiri Pirko .port_split = nfp_devlink_port_split,
324*f58a3e4dSJiri Pirko .port_unsplit = nfp_devlink_port_unsplit,
325ab8ccc6cSJiri Pirko };
326ab8ccc6cSJiri Pirko
nfp_devlink_port_register(struct nfp_app * app,struct nfp_port * port)32753e7a08fSJakub Kicinski int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
32853e7a08fSJakub Kicinski {
32971ad8d55SDanielle Ratson struct devlink_port_attrs attrs = {};
33053e7a08fSJakub Kicinski struct nfp_eth_table_port eth_port;
33153e7a08fSJakub Kicinski struct devlink *devlink;
3321b15c902SJiri Pirko const u8 *serial;
3331b15c902SJiri Pirko int serial_len;
33453e7a08fSJakub Kicinski int ret;
33553e7a08fSJakub Kicinski
336ac73d4bfSJiri Pirko SET_NETDEV_DEVLINK_PORT(port->netdev, &port->dl_port);
337ac73d4bfSJiri Pirko
33853e7a08fSJakub Kicinski rtnl_lock();
33953e7a08fSJakub Kicinski ret = nfp_devlink_fill_eth_port(port, ð_port);
34053e7a08fSJakub Kicinski rtnl_unlock();
34153e7a08fSJakub Kicinski if (ret)
34253e7a08fSJakub Kicinski return ret;
34353e7a08fSJakub Kicinski
34471ad8d55SDanielle Ratson attrs.split = eth_port.is_split;
3454abd9600SDiana Wang attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
34690b669d6SYinjun Zhang attrs.lanes = eth_port.port_lanes;
34771ad8d55SDanielle Ratson attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
34871ad8d55SDanielle Ratson attrs.phys.port_number = eth_port.label_port;
34971ad8d55SDanielle Ratson attrs.phys.split_subport_number = eth_port.label_subport;
3501b15c902SJiri Pirko serial_len = nfp_cpp_serial(port->app->cpp, &serial);
35171ad8d55SDanielle Ratson memcpy(attrs.switch_id.id, serial, serial_len);
35271ad8d55SDanielle Ratson attrs.switch_id.id_len = serial_len;
35371ad8d55SDanielle Ratson devlink_port_attrs_set(&port->dl_port, &attrs);
35453e7a08fSJakub Kicinski
35553e7a08fSJakub Kicinski devlink = priv_to_devlink(app->pf);
35653e7a08fSJakub Kicinski
357ab8ccc6cSJiri Pirko return devl_port_register_with_ops(devlink, &port->dl_port,
358ab8ccc6cSJiri Pirko port->eth_id, &nfp_devlink_port_ops);
35953e7a08fSJakub Kicinski }
36053e7a08fSJakub Kicinski
nfp_devlink_port_unregister(struct nfp_port * port)36153e7a08fSJakub Kicinski void nfp_devlink_port_unregister(struct nfp_port *port)
36253e7a08fSJakub Kicinski {
363162cca42SJakub Kicinski devl_port_unregister(&port->dl_port);
36453e7a08fSJakub Kicinski }
365