1fa34a514SAlejandro Lucero // SPDX-License-Identifier: GPL-2.0-only
2fa34a514SAlejandro Lucero /****************************************************************************
3fa34a514SAlejandro Lucero * Driver for AMD network controllers and boards
4fa34a514SAlejandro Lucero * Copyright (C) 2023, Advanced Micro Devices, Inc.
5fa34a514SAlejandro Lucero *
6fa34a514SAlejandro Lucero * This program is free software; you can redistribute it and/or modify it
7fa34a514SAlejandro Lucero * under the terms of the GNU General Public License version 2 as published
8fa34a514SAlejandro Lucero * by the Free Software Foundation, incorporated herein by reference.
9fa34a514SAlejandro Lucero */
10fa34a514SAlejandro Lucero
11fa34a514SAlejandro Lucero #include "net_driver.h"
12fa78b017SAlejandro Lucero #include "ef100_nic.h"
13fa34a514SAlejandro Lucero #include "efx_devlink.h"
1414743dddSAlejandro Lucero #include <linux/rtc.h>
1514743dddSAlejandro Lucero #include "mcdi.h"
1614743dddSAlejandro Lucero #include "mcdi_functions.h"
1714743dddSAlejandro Lucero #include "mcdi_pcol.h"
1825414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
1925414b2aSAlejandro Lucero #include "mae.h"
2025414b2aSAlejandro Lucero #include "ef100_rep.h"
2125414b2aSAlejandro Lucero #endif
22fa34a514SAlejandro Lucero
23fa34a514SAlejandro Lucero struct efx_devlink {
24fa34a514SAlejandro Lucero struct efx_nic *efx;
25fa34a514SAlejandro Lucero };
26fa34a514SAlejandro Lucero
2725414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
2825414b2aSAlejandro Lucero
efx_devlink_port_addr_get(struct devlink_port * port,u8 * hw_addr,int * hw_addr_len,struct netlink_ext_ack * extack)2925414b2aSAlejandro Lucero static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr,
3025414b2aSAlejandro Lucero int *hw_addr_len,
3125414b2aSAlejandro Lucero struct netlink_ext_ack *extack)
3225414b2aSAlejandro Lucero {
3325414b2aSAlejandro Lucero struct efx_devlink *devlink = devlink_priv(port->devlink);
3425414b2aSAlejandro Lucero struct mae_mport_desc *mport_desc;
3525414b2aSAlejandro Lucero efx_qword_t pciefn;
3625414b2aSAlejandro Lucero u32 client_id;
3725414b2aSAlejandro Lucero int rc = 0;
3825414b2aSAlejandro Lucero
3925414b2aSAlejandro Lucero mport_desc = container_of(port, struct mae_mport_desc, dl_port);
4025414b2aSAlejandro Lucero
4125414b2aSAlejandro Lucero if (!ef100_mport_on_local_intf(devlink->efx, mport_desc)) {
4225414b2aSAlejandro Lucero rc = -EINVAL;
4325414b2aSAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
4425414b2aSAlejandro Lucero "Port not on local interface (mport: %u)",
4525414b2aSAlejandro Lucero mport_desc->mport_id);
4625414b2aSAlejandro Lucero goto out;
4725414b2aSAlejandro Lucero }
4825414b2aSAlejandro Lucero
4925414b2aSAlejandro Lucero if (ef100_mport_is_vf(mport_desc))
5025414b2aSAlejandro Lucero EFX_POPULATE_QWORD_3(pciefn,
5125414b2aSAlejandro Lucero PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
5225414b2aSAlejandro Lucero PCIE_FUNCTION_VF, mport_desc->vf_idx,
5325414b2aSAlejandro Lucero PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
5425414b2aSAlejandro Lucero else
5525414b2aSAlejandro Lucero EFX_POPULATE_QWORD_3(pciefn,
5625414b2aSAlejandro Lucero PCIE_FUNCTION_PF, mport_desc->pf_idx,
5725414b2aSAlejandro Lucero PCIE_FUNCTION_VF, PCIE_FUNCTION_VF_NULL,
5825414b2aSAlejandro Lucero PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
5925414b2aSAlejandro Lucero
6025414b2aSAlejandro Lucero rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
6125414b2aSAlejandro Lucero if (rc) {
62fa78b017SAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
63fa78b017SAlejandro Lucero "No internal client_ID for port (mport: %u)",
64fa78b017SAlejandro Lucero mport_desc->mport_id);
65fa78b017SAlejandro Lucero goto out;
66fa78b017SAlejandro Lucero }
67fa78b017SAlejandro Lucero
68fa78b017SAlejandro Lucero rc = ef100_get_mac_address(devlink->efx, hw_addr, client_id, true);
69fa78b017SAlejandro Lucero if (rc != 0)
70fa78b017SAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
71fa78b017SAlejandro Lucero "No available MAC for port (mport: %u)",
72fa78b017SAlejandro Lucero mport_desc->mport_id);
73fa78b017SAlejandro Lucero out:
74fa78b017SAlejandro Lucero *hw_addr_len = ETH_ALEN;
75fa78b017SAlejandro Lucero return rc;
76fa78b017SAlejandro Lucero }
77fa78b017SAlejandro Lucero
efx_devlink_port_addr_set(struct devlink_port * port,const u8 * hw_addr,int hw_addr_len,struct netlink_ext_ack * extack)78fa78b017SAlejandro Lucero static int efx_devlink_port_addr_set(struct devlink_port *port,
79fa78b017SAlejandro Lucero const u8 *hw_addr, int hw_addr_len,
80fa78b017SAlejandro Lucero struct netlink_ext_ack *extack)
81fa78b017SAlejandro Lucero {
82fa78b017SAlejandro Lucero MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_CLIENT_MAC_ADDRESSES_IN_LEN(1));
83fa78b017SAlejandro Lucero struct efx_devlink *devlink = devlink_priv(port->devlink);
84fa78b017SAlejandro Lucero struct mae_mport_desc *mport_desc;
85fa78b017SAlejandro Lucero efx_qword_t pciefn;
86fa78b017SAlejandro Lucero u32 client_id;
87fa78b017SAlejandro Lucero int rc;
88fa78b017SAlejandro Lucero
89fa78b017SAlejandro Lucero mport_desc = container_of(port, struct mae_mport_desc, dl_port);
90fa78b017SAlejandro Lucero
91fa78b017SAlejandro Lucero if (!ef100_mport_is_vf(mport_desc)) {
92fa78b017SAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
93fa78b017SAlejandro Lucero "port mac change not allowed (mport: %u)",
94fa78b017SAlejandro Lucero mport_desc->mport_id);
95fa78b017SAlejandro Lucero return -EPERM;
96fa78b017SAlejandro Lucero }
97fa78b017SAlejandro Lucero
98fa78b017SAlejandro Lucero EFX_POPULATE_QWORD_3(pciefn,
99fa78b017SAlejandro Lucero PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
100fa78b017SAlejandro Lucero PCIE_FUNCTION_VF, mport_desc->vf_idx,
101fa78b017SAlejandro Lucero PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
102fa78b017SAlejandro Lucero
103fa78b017SAlejandro Lucero rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
104fa78b017SAlejandro Lucero if (rc) {
105fa78b017SAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
106fa78b017SAlejandro Lucero "No internal client_ID for port (mport: %u)",
107fa78b017SAlejandro Lucero mport_desc->mport_id);
108fa78b017SAlejandro Lucero return rc;
109fa78b017SAlejandro Lucero }
110fa78b017SAlejandro Lucero
111fa78b017SAlejandro Lucero MCDI_SET_DWORD(inbuf, SET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
1123b6096c9SAlejandro Lucero client_id);
1133b6096c9SAlejandro Lucero
1143b6096c9SAlejandro Lucero ether_addr_copy(MCDI_PTR(inbuf, SET_CLIENT_MAC_ADDRESSES_IN_MAC_ADDRS),
1153b6096c9SAlejandro Lucero hw_addr);
1163b6096c9SAlejandro Lucero
1173b6096c9SAlejandro Lucero rc = efx_mcdi_rpc(devlink->efx, MC_CMD_SET_CLIENT_MAC_ADDRESSES, inbuf,
1183b6096c9SAlejandro Lucero sizeof(inbuf), NULL, 0, NULL);
1193b6096c9SAlejandro Lucero if (rc)
1203b6096c9SAlejandro Lucero NL_SET_ERR_MSG_FMT(extack,
1213b6096c9SAlejandro Lucero "sfc MC_CMD_SET_CLIENT_MAC_ADDRESSES mcdi error (mport: %u)",
1223b6096c9SAlejandro Lucero mport_desc->mport_id);
1233b6096c9SAlejandro Lucero
1243b6096c9SAlejandro Lucero return rc;
1253b6096c9SAlejandro Lucero }
1263b6096c9SAlejandro Lucero
1273b6096c9SAlejandro Lucero static const struct devlink_port_ops sfc_devlink_port_ops = {
1283b6096c9SAlejandro Lucero .port_fn_hw_addr_get = efx_devlink_port_addr_get,
1293b6096c9SAlejandro Lucero .port_fn_hw_addr_set = efx_devlink_port_addr_set,
1303b6096c9SAlejandro Lucero };
1313b6096c9SAlejandro Lucero
efx_devlink_del_port(struct devlink_port * dl_port)1323b6096c9SAlejandro Lucero static void efx_devlink_del_port(struct devlink_port *dl_port)
1333b6096c9SAlejandro Lucero {
1343b6096c9SAlejandro Lucero if (!dl_port)
1353b6096c9SAlejandro Lucero return;
1363b6096c9SAlejandro Lucero devl_port_unregister(dl_port);
1373b6096c9SAlejandro Lucero }
1383b6096c9SAlejandro Lucero
efx_devlink_add_port(struct efx_nic * efx,struct mae_mport_desc * mport)1393b6096c9SAlejandro Lucero static int efx_devlink_add_port(struct efx_nic *efx,
1403b6096c9SAlejandro Lucero struct mae_mport_desc *mport)
1413b6096c9SAlejandro Lucero {
1423b6096c9SAlejandro Lucero bool external = false;
1433b6096c9SAlejandro Lucero
1443b6096c9SAlejandro Lucero if (!ef100_mport_on_local_intf(efx, mport))
1453b6096c9SAlejandro Lucero external = true;
1463b6096c9SAlejandro Lucero
1473b6096c9SAlejandro Lucero switch (mport->mport_type) {
1483b6096c9SAlejandro Lucero case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
1493b6096c9SAlejandro Lucero if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
1503b6096c9SAlejandro Lucero devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
1513b6096c9SAlejandro Lucero mport->vf_idx,
1523b6096c9SAlejandro Lucero external);
1533b6096c9SAlejandro Lucero else
1543b6096c9SAlejandro Lucero devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
1553b6096c9SAlejandro Lucero external);
1563b6096c9SAlejandro Lucero break;
1573b6096c9SAlejandro Lucero default:
1583b6096c9SAlejandro Lucero /* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
1593b6096c9SAlejandro Lucero return 0;
1603b6096c9SAlejandro Lucero }
16125414b2aSAlejandro Lucero
16225414b2aSAlejandro Lucero mport->dl_port.index = mport->mport_id;
16314743dddSAlejandro Lucero
16414743dddSAlejandro Lucero return devl_port_register_with_ops(efx->devlink, &mport->dl_port,
16514743dddSAlejandro Lucero mport->mport_id,
16614743dddSAlejandro Lucero &sfc_devlink_port_ops);
16714743dddSAlejandro Lucero }
16814743dddSAlejandro Lucero
16914743dddSAlejandro Lucero #endif
17014743dddSAlejandro Lucero
efx_devlink_info_nvram_partition(struct efx_nic * efx,struct devlink_info_req * req,unsigned int partition_type,const char * version_name)17114743dddSAlejandro Lucero static int efx_devlink_info_nvram_partition(struct efx_nic *efx,
17214743dddSAlejandro Lucero struct devlink_info_req *req,
17314743dddSAlejandro Lucero unsigned int partition_type,
174*cfcb9428SAlejandro Lucero const char *version_name)
175*cfcb9428SAlejandro Lucero {
176*cfcb9428SAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
177*cfcb9428SAlejandro Lucero u16 version[4];
178*cfcb9428SAlejandro Lucero int rc;
17914743dddSAlejandro Lucero
180*cfcb9428SAlejandro Lucero rc = efx_mcdi_nvram_metadata(efx, partition_type, NULL, version, NULL,
181*cfcb9428SAlejandro Lucero 0);
18214743dddSAlejandro Lucero
18314743dddSAlejandro Lucero /* If the partition does not exist, that is not an error. */
18414743dddSAlejandro Lucero if (rc == -ENOENT)
18514743dddSAlejandro Lucero return 0;
18614743dddSAlejandro Lucero
18714743dddSAlejandro Lucero if (rc) {
18814743dddSAlejandro Lucero netif_err(efx, drv, efx->net_dev, "mcdi nvram %s: failed (rc=%d)\n",
18914743dddSAlejandro Lucero version_name, rc);
19014743dddSAlejandro Lucero return rc;
19114743dddSAlejandro Lucero }
19214743dddSAlejandro Lucero
19314743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u", version[0],
19414743dddSAlejandro Lucero version[1], version[2], version[3]);
195*cfcb9428SAlejandro Lucero devlink_info_version_stored_put(req, version_name, buf);
19614743dddSAlejandro Lucero
197*cfcb9428SAlejandro Lucero return 0;
198*cfcb9428SAlejandro Lucero }
199*cfcb9428SAlejandro Lucero
efx_devlink_info_stored_versions(struct efx_nic * efx,struct devlink_info_req * req)200*cfcb9428SAlejandro Lucero static int efx_devlink_info_stored_versions(struct efx_nic *efx,
201*cfcb9428SAlejandro Lucero struct devlink_info_req *req)
202*cfcb9428SAlejandro Lucero {
20314743dddSAlejandro Lucero int err;
20414743dddSAlejandro Lucero
20514743dddSAlejandro Lucero /* We do not care here about the specific error but just if an error
206*cfcb9428SAlejandro Lucero * happened. The specific error will be reported inside the call
20714743dddSAlejandro Lucero * through system messages, and if any error happened in any call
20814743dddSAlejandro Lucero * below, we report it through extack.
20914743dddSAlejandro Lucero */
210*cfcb9428SAlejandro Lucero err = efx_devlink_info_nvram_partition(efx, req,
21114743dddSAlejandro Lucero NVRAM_PARTITION_TYPE_BUNDLE,
21214743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID);
21314743dddSAlejandro Lucero
214*cfcb9428SAlejandro Lucero err |= efx_devlink_info_nvram_partition(efx, req,
21514743dddSAlejandro Lucero NVRAM_PARTITION_TYPE_MC_FIRMWARE,
21614743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_FW_MGMT);
21714743dddSAlejandro Lucero
218*cfcb9428SAlejandro Lucero err |= efx_devlink_info_nvram_partition(efx, req,
21914743dddSAlejandro Lucero NVRAM_PARTITION_TYPE_SUC_FIRMWARE,
22014743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC);
221*cfcb9428SAlejandro Lucero
22214743dddSAlejandro Lucero err |= efx_devlink_info_nvram_partition(efx, req,
22314743dddSAlejandro Lucero NVRAM_PARTITION_TYPE_EXPANSION_ROM,
22414743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_EXPROM);
22514743dddSAlejandro Lucero
22614743dddSAlejandro Lucero err |= efx_devlink_info_nvram_partition(efx, req,
22714743dddSAlejandro Lucero NVRAM_PARTITION_TYPE_EXPANSION_UEFI,
22814743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_UEFI);
22914743dddSAlejandro Lucero return err;
23014743dddSAlejandro Lucero }
23114743dddSAlejandro Lucero
23214743dddSAlejandro Lucero #define EFX_VER_FLAG(_f) \
23314743dddSAlejandro Lucero (MC_CMD_GET_VERSION_V5_OUT_ ## _f ## _PRESENT_LBN)
23414743dddSAlejandro Lucero
efx_devlink_info_running_v2(struct efx_nic * efx,struct devlink_info_req * req,unsigned int flags,efx_dword_t * outbuf)23514743dddSAlejandro Lucero static void efx_devlink_info_running_v2(struct efx_nic *efx,
23614743dddSAlejandro Lucero struct devlink_info_req *req,
23714743dddSAlejandro Lucero unsigned int flags, efx_dword_t *outbuf)
23814743dddSAlejandro Lucero {
23914743dddSAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
24014743dddSAlejandro Lucero union {
24114743dddSAlejandro Lucero const __le32 *dwords;
24214743dddSAlejandro Lucero const __le16 *words;
24314743dddSAlejandro Lucero const char *str;
24414743dddSAlejandro Lucero } ver;
24514743dddSAlejandro Lucero struct rtc_time build_date;
24614743dddSAlejandro Lucero unsigned int build_id;
24714743dddSAlejandro Lucero size_t offset;
24814743dddSAlejandro Lucero __maybe_unused u64 tstamp;
24914743dddSAlejandro Lucero
25014743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(BOARD_EXT_INFO))) {
25114743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%s",
25214743dddSAlejandro Lucero MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_NAME));
25314743dddSAlejandro Lucero devlink_info_version_fixed_put(req,
25414743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
25514743dddSAlejandro Lucero buf);
25614743dddSAlejandro Lucero
25714743dddSAlejandro Lucero /* Favour full board version if present (in V5 or later) */
25814743dddSAlejandro Lucero if (~flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
25914743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u",
26014743dddSAlejandro Lucero MCDI_DWORD(outbuf,
26114743dddSAlejandro Lucero GET_VERSION_V2_OUT_BOARD_REVISION));
26214743dddSAlejandro Lucero devlink_info_version_fixed_put(req,
26314743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
26414743dddSAlejandro Lucero buf);
26514743dddSAlejandro Lucero }
26614743dddSAlejandro Lucero
26714743dddSAlejandro Lucero ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_BOARD_SERIAL);
26814743dddSAlejandro Lucero if (ver.str[0])
26914743dddSAlejandro Lucero devlink_info_board_serial_number_put(req, ver.str);
27014743dddSAlejandro Lucero }
27114743dddSAlejandro Lucero
27214743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(FPGA_EXT_INFO))) {
27314743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
27414743dddSAlejandro Lucero GET_VERSION_V2_OUT_FPGA_VERSION);
27514743dddSAlejandro Lucero offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u_%c%u",
27614743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]),
27714743dddSAlejandro Lucero 'A' + le32_to_cpu(ver.dwords[1]),
27814743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]));
27914743dddSAlejandro Lucero
28014743dddSAlejandro Lucero ver.str = MCDI_PTR(outbuf, GET_VERSION_V2_OUT_FPGA_EXTRA);
28114743dddSAlejandro Lucero if (ver.str[0])
28214743dddSAlejandro Lucero snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
28314743dddSAlejandro Lucero " (%s)", ver.str);
28414743dddSAlejandro Lucero
28514743dddSAlejandro Lucero devlink_info_version_running_put(req,
28614743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FPGA_REV,
28714743dddSAlejandro Lucero buf);
28814743dddSAlejandro Lucero }
28914743dddSAlejandro Lucero
29014743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(CMC_EXT_INFO))) {
29114743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
29214743dddSAlejandro Lucero GET_VERSION_V2_OUT_CMCFW_VERSION);
29314743dddSAlejandro Lucero offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
29414743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]),
29514743dddSAlejandro Lucero le32_to_cpu(ver.dwords[1]),
29614743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
29714743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
29814743dddSAlejandro Lucero
29914743dddSAlejandro Lucero #ifdef CONFIG_RTC_LIB
30014743dddSAlejandro Lucero tstamp = MCDI_QWORD(outbuf,
30114743dddSAlejandro Lucero GET_VERSION_V2_OUT_CMCFW_BUILD_DATE);
30214743dddSAlejandro Lucero if (tstamp) {
30314743dddSAlejandro Lucero rtc_time64_to_tm(tstamp, &build_date);
30414743dddSAlejandro Lucero snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
30514743dddSAlejandro Lucero " (%ptRd)", &build_date);
30614743dddSAlejandro Lucero }
30714743dddSAlejandro Lucero #endif
30814743dddSAlejandro Lucero
30914743dddSAlejandro Lucero devlink_info_version_running_put(req,
31014743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_MGMT_CMC,
31114743dddSAlejandro Lucero buf);
31214743dddSAlejandro Lucero }
31314743dddSAlejandro Lucero
31414743dddSAlejandro Lucero ver.words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_V2_OUT_VERSION);
31514743dddSAlejandro Lucero offset = snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
31614743dddSAlejandro Lucero le16_to_cpu(ver.words[0]), le16_to_cpu(ver.words[1]),
31714743dddSAlejandro Lucero le16_to_cpu(ver.words[2]), le16_to_cpu(ver.words[3]));
31814743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(MCFW_EXT_INFO))) {
31914743dddSAlejandro Lucero build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_ID);
32014743dddSAlejandro Lucero snprintf(&buf[offset], EFX_MAX_VERSION_INFO_LEN - offset,
32114743dddSAlejandro Lucero " (%x) %s", build_id,
32214743dddSAlejandro Lucero MCDI_PTR(outbuf, GET_VERSION_V2_OUT_MCFW_BUILD_NAME));
32314743dddSAlejandro Lucero }
32414743dddSAlejandro Lucero devlink_info_version_running_put(req,
32514743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
32614743dddSAlejandro Lucero buf);
32714743dddSAlejandro Lucero
3285f22c3b6SAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
32914743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
33014743dddSAlejandro Lucero GET_VERSION_V2_OUT_SUCFW_VERSION);
33114743dddSAlejandro Lucero #ifdef CONFIG_RTC_LIB
33214743dddSAlejandro Lucero tstamp = MCDI_QWORD(outbuf,
33314743dddSAlejandro Lucero GET_VERSION_V2_OUT_SUCFW_BUILD_DATE);
33414743dddSAlejandro Lucero rtc_time64_to_tm(tstamp, &build_date);
33514743dddSAlejandro Lucero #else
33614743dddSAlejandro Lucero memset(&build_date, 0, sizeof(build_date));
33714743dddSAlejandro Lucero #endif
33814743dddSAlejandro Lucero build_id = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_SUCFW_CHIP_ID);
33914743dddSAlejandro Lucero
34014743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN,
34114743dddSAlejandro Lucero "%u.%u.%u.%u type %x (%ptRd)",
34214743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
34314743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]), le32_to_cpu(ver.dwords[3]),
34414743dddSAlejandro Lucero build_id, &build_date);
34514743dddSAlejandro Lucero
34614743dddSAlejandro Lucero devlink_info_version_running_put(req,
34714743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
34814743dddSAlejandro Lucero buf);
34914743dddSAlejandro Lucero }
35014743dddSAlejandro Lucero }
35114743dddSAlejandro Lucero
efx_devlink_info_running_v3(struct efx_nic * efx,struct devlink_info_req * req,unsigned int flags,efx_dword_t * outbuf)35214743dddSAlejandro Lucero static void efx_devlink_info_running_v3(struct efx_nic *efx,
35314743dddSAlejandro Lucero struct devlink_info_req *req,
35414743dddSAlejandro Lucero unsigned int flags, efx_dword_t *outbuf)
35514743dddSAlejandro Lucero {
35614743dddSAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
35714743dddSAlejandro Lucero union {
35814743dddSAlejandro Lucero const __le32 *dwords;
35914743dddSAlejandro Lucero const __le16 *words;
36014743dddSAlejandro Lucero const char *str;
36114743dddSAlejandro Lucero } ver;
36214743dddSAlejandro Lucero
36314743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(DATAPATH_HW_VERSION))) {
36414743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
36514743dddSAlejandro Lucero GET_VERSION_V3_OUT_DATAPATH_HW_VERSION);
36614743dddSAlejandro Lucero
36714743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
36814743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
36914743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]));
37014743dddSAlejandro Lucero
37114743dddSAlejandro Lucero devlink_info_version_running_put(req,
37214743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_DATAPATH_HW,
37314743dddSAlejandro Lucero buf);
37414743dddSAlejandro Lucero }
37514743dddSAlejandro Lucero
37614743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(DATAPATH_FW_VERSION))) {
37714743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
37814743dddSAlejandro Lucero GET_VERSION_V3_OUT_DATAPATH_FW_VERSION);
37914743dddSAlejandro Lucero
38014743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u",
38114743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
38214743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]));
38314743dddSAlejandro Lucero
38414743dddSAlejandro Lucero devlink_info_version_running_put(req,
38514743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_DATAPATH_FW,
38614743dddSAlejandro Lucero buf);
38714743dddSAlejandro Lucero }
38814743dddSAlejandro Lucero }
38914743dddSAlejandro Lucero
efx_devlink_info_running_v4(struct efx_nic * efx,struct devlink_info_req * req,unsigned int flags,efx_dword_t * outbuf)39014743dddSAlejandro Lucero static void efx_devlink_info_running_v4(struct efx_nic *efx,
39114743dddSAlejandro Lucero struct devlink_info_req *req,
39214743dddSAlejandro Lucero unsigned int flags, efx_dword_t *outbuf)
39314743dddSAlejandro Lucero {
39414743dddSAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
39514743dddSAlejandro Lucero union {
39614743dddSAlejandro Lucero const __le32 *dwords;
39714743dddSAlejandro Lucero const __le16 *words;
39814743dddSAlejandro Lucero const char *str;
39914743dddSAlejandro Lucero } ver;
40014743dddSAlejandro Lucero
40114743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SOC_BOOT_VERSION))) {
40214743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
40314743dddSAlejandro Lucero GET_VERSION_V4_OUT_SOC_BOOT_VERSION);
40414743dddSAlejandro Lucero
40514743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
40614743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
40714743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
40814743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
40914743dddSAlejandro Lucero
41014743dddSAlejandro Lucero devlink_info_version_running_put(req,
41114743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_SOC_BOOT,
41214743dddSAlejandro Lucero buf);
41314743dddSAlejandro Lucero }
41414743dddSAlejandro Lucero
41514743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SOC_UBOOT_VERSION))) {
41614743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
41714743dddSAlejandro Lucero GET_VERSION_V4_OUT_SOC_UBOOT_VERSION);
41814743dddSAlejandro Lucero
41914743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
42014743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
42114743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
42214743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
42314743dddSAlejandro Lucero
42414743dddSAlejandro Lucero devlink_info_version_running_put(req,
42514743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_SOC_UBOOT,
42614743dddSAlejandro Lucero buf);
42714743dddSAlejandro Lucero }
42814743dddSAlejandro Lucero
42914743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SOC_MAIN_ROOTFS_VERSION))) {
43014743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
43114743dddSAlejandro Lucero GET_VERSION_V4_OUT_SOC_MAIN_ROOTFS_VERSION);
43214743dddSAlejandro Lucero
43314743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
43414743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
43514743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
43614743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
43714743dddSAlejandro Lucero
43814743dddSAlejandro Lucero devlink_info_version_running_put(req,
43914743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_SOC_MAIN,
44014743dddSAlejandro Lucero buf);
44114743dddSAlejandro Lucero }
44214743dddSAlejandro Lucero
44314743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SOC_RECOVERY_BUILDROOT_VERSION))) {
44414743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
44514743dddSAlejandro Lucero GET_VERSION_V4_OUT_SOC_RECOVERY_BUILDROOT_VERSION);
44614743dddSAlejandro Lucero
44714743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
44814743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
44914743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
45014743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
45114743dddSAlejandro Lucero
45214743dddSAlejandro Lucero devlink_info_version_running_put(req,
45314743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_SOC_RECOVERY,
45414743dddSAlejandro Lucero buf);
45514743dddSAlejandro Lucero }
45614743dddSAlejandro Lucero
45714743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(SUCFW_VERSION)) &&
45814743dddSAlejandro Lucero ~flags & BIT(EFX_VER_FLAG(SUCFW_EXT_INFO))) {
45914743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
46014743dddSAlejandro Lucero GET_VERSION_V4_OUT_SUCFW_VERSION);
46114743dddSAlejandro Lucero
46214743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
46314743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
46414743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
46514743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
46614743dddSAlejandro Lucero
46714743dddSAlejandro Lucero devlink_info_version_running_put(req,
46814743dddSAlejandro Lucero EFX_DEVLINK_INFO_VERSION_FW_MGMT_SUC,
46914743dddSAlejandro Lucero buf);
47014743dddSAlejandro Lucero }
47114743dddSAlejandro Lucero }
47214743dddSAlejandro Lucero
efx_devlink_info_running_v5(struct efx_nic * efx,struct devlink_info_req * req,unsigned int flags,efx_dword_t * outbuf)47314743dddSAlejandro Lucero static void efx_devlink_info_running_v5(struct efx_nic *efx,
47414743dddSAlejandro Lucero struct devlink_info_req *req,
47514743dddSAlejandro Lucero unsigned int flags, efx_dword_t *outbuf)
47614743dddSAlejandro Lucero {
47714743dddSAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
47814743dddSAlejandro Lucero union {
47914743dddSAlejandro Lucero const __le32 *dwords;
48014743dddSAlejandro Lucero const __le16 *words;
48114743dddSAlejandro Lucero const char *str;
48214743dddSAlejandro Lucero } ver;
48314743dddSAlejandro Lucero
48414743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(BOARD_VERSION))) {
48514743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
48614743dddSAlejandro Lucero GET_VERSION_V5_OUT_BOARD_VERSION);
48714743dddSAlejandro Lucero
48814743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
48914743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
49014743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
49114743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
49214743dddSAlejandro Lucero
49314743dddSAlejandro Lucero devlink_info_version_running_put(req,
49414743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
49514743dddSAlejandro Lucero buf);
49614743dddSAlejandro Lucero }
49714743dddSAlejandro Lucero
49814743dddSAlejandro Lucero if (flags & BIT(EFX_VER_FLAG(BUNDLE_VERSION))) {
49914743dddSAlejandro Lucero ver.dwords = (__le32 *)MCDI_PTR(outbuf,
50014743dddSAlejandro Lucero GET_VERSION_V5_OUT_BUNDLE_VERSION);
50114743dddSAlejandro Lucero
50214743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
50314743dddSAlejandro Lucero le32_to_cpu(ver.dwords[0]), le32_to_cpu(ver.dwords[1]),
50414743dddSAlejandro Lucero le32_to_cpu(ver.dwords[2]),
50514743dddSAlejandro Lucero le32_to_cpu(ver.dwords[3]));
50614743dddSAlejandro Lucero
50714743dddSAlejandro Lucero devlink_info_version_running_put(req,
50814743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
50914743dddSAlejandro Lucero buf);
51014743dddSAlejandro Lucero }
51114743dddSAlejandro Lucero }
51214743dddSAlejandro Lucero
efx_devlink_info_running_versions(struct efx_nic * efx,struct devlink_info_req * req)51314743dddSAlejandro Lucero static int efx_devlink_info_running_versions(struct efx_nic *efx,
51414743dddSAlejandro Lucero struct devlink_info_req *req)
51514743dddSAlejandro Lucero {
51614743dddSAlejandro Lucero MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_VERSION_V5_OUT_LEN);
51714743dddSAlejandro Lucero MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_VERSION_EXT_IN_LEN);
51814743dddSAlejandro Lucero char buf[EFX_MAX_VERSION_INFO_LEN];
51914743dddSAlejandro Lucero union {
52014743dddSAlejandro Lucero const __le32 *dwords;
52114743dddSAlejandro Lucero const __le16 *words;
52214743dddSAlejandro Lucero const char *str;
52314743dddSAlejandro Lucero } ver;
52414743dddSAlejandro Lucero size_t outlength;
52514743dddSAlejandro Lucero unsigned int flags;
52614743dddSAlejandro Lucero int rc;
52714743dddSAlejandro Lucero
52814743dddSAlejandro Lucero rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, inbuf, sizeof(inbuf),
52914743dddSAlejandro Lucero outbuf, sizeof(outbuf), &outlength);
53014743dddSAlejandro Lucero if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) {
53114743dddSAlejandro Lucero netif_err(efx, drv, efx->net_dev,
53214743dddSAlejandro Lucero "mcdi MC_CMD_GET_VERSION failed\n");
53314743dddSAlejandro Lucero return rc;
53414743dddSAlejandro Lucero }
53514743dddSAlejandro Lucero
53614743dddSAlejandro Lucero /* Handle previous output */
53714743dddSAlejandro Lucero if (outlength < MC_CMD_GET_VERSION_V2_OUT_LEN) {
53814743dddSAlejandro Lucero ver.words = (__le16 *)MCDI_PTR(outbuf,
53914743dddSAlejandro Lucero GET_VERSION_EXT_OUT_VERSION);
54014743dddSAlejandro Lucero snprintf(buf, EFX_MAX_VERSION_INFO_LEN, "%u.%u.%u.%u",
54114743dddSAlejandro Lucero le16_to_cpu(ver.words[0]),
54214743dddSAlejandro Lucero le16_to_cpu(ver.words[1]),
54314743dddSAlejandro Lucero le16_to_cpu(ver.words[2]),
54414743dddSAlejandro Lucero le16_to_cpu(ver.words[3]));
54514743dddSAlejandro Lucero
54614743dddSAlejandro Lucero devlink_info_version_running_put(req,
54714743dddSAlejandro Lucero DEVLINK_INFO_VERSION_GENERIC_FW_MGMT,
54814743dddSAlejandro Lucero buf);
54914743dddSAlejandro Lucero return 0;
55014743dddSAlejandro Lucero }
55114743dddSAlejandro Lucero
55214743dddSAlejandro Lucero /* Handle V2 additions */
55314743dddSAlejandro Lucero flags = MCDI_DWORD(outbuf, GET_VERSION_V2_OUT_FLAGS);
55414743dddSAlejandro Lucero efx_devlink_info_running_v2(efx, req, flags, outbuf);
55514743dddSAlejandro Lucero
55614743dddSAlejandro Lucero if (outlength < MC_CMD_GET_VERSION_V3_OUT_LEN)
55714743dddSAlejandro Lucero return 0;
55814743dddSAlejandro Lucero
55914743dddSAlejandro Lucero /* Handle V3 additions */
56014743dddSAlejandro Lucero efx_devlink_info_running_v3(efx, req, flags, outbuf);
56114743dddSAlejandro Lucero
56214743dddSAlejandro Lucero if (outlength < MC_CMD_GET_VERSION_V4_OUT_LEN)
56314743dddSAlejandro Lucero return 0;
56414743dddSAlejandro Lucero
56514743dddSAlejandro Lucero /* Handle V4 additions */
56614743dddSAlejandro Lucero efx_devlink_info_running_v4(efx, req, flags, outbuf);
56714743dddSAlejandro Lucero
56814743dddSAlejandro Lucero if (outlength < MC_CMD_GET_VERSION_V5_OUT_LEN)
56914743dddSAlejandro Lucero return 0;
57014743dddSAlejandro Lucero
57114743dddSAlejandro Lucero /* Handle V5 additions */
57214743dddSAlejandro Lucero efx_devlink_info_running_v5(efx, req, flags, outbuf);
57314743dddSAlejandro Lucero
57414743dddSAlejandro Lucero return 0;
57514743dddSAlejandro Lucero }
57614743dddSAlejandro Lucero
57714743dddSAlejandro Lucero #define EFX_MAX_SERIALNUM_LEN (ETH_ALEN * 2 + 1)
57814743dddSAlejandro Lucero
efx_devlink_info_board_cfg(struct efx_nic * efx,struct devlink_info_req * req)57914743dddSAlejandro Lucero static int efx_devlink_info_board_cfg(struct efx_nic *efx,
58014743dddSAlejandro Lucero struct devlink_info_req *req)
58114743dddSAlejandro Lucero {
58214743dddSAlejandro Lucero char sn[EFX_MAX_SERIALNUM_LEN];
58314743dddSAlejandro Lucero u8 mac_address[ETH_ALEN];
58414743dddSAlejandro Lucero int rc;
58514743dddSAlejandro Lucero
58614743dddSAlejandro Lucero rc = efx_mcdi_get_board_cfg(efx, (u8 *)mac_address, NULL, NULL);
58714743dddSAlejandro Lucero if (!rc) {
58814743dddSAlejandro Lucero snprintf(sn, EFX_MAX_SERIALNUM_LEN, "%pm", mac_address);
58914743dddSAlejandro Lucero devlink_info_serial_number_put(req, sn);
59014743dddSAlejandro Lucero }
59114743dddSAlejandro Lucero return rc;
592*cfcb9428SAlejandro Lucero }
59314743dddSAlejandro Lucero
efx_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)594*cfcb9428SAlejandro Lucero static int efx_devlink_info_get(struct devlink *devlink,
595*cfcb9428SAlejandro Lucero struct devlink_info_req *req,
596*cfcb9428SAlejandro Lucero struct netlink_ext_ack *extack)
59714743dddSAlejandro Lucero {
598*cfcb9428SAlejandro Lucero struct efx_devlink *devlink_private = devlink_priv(devlink);
599*cfcb9428SAlejandro Lucero struct efx_nic *efx = devlink_private->efx;
600*cfcb9428SAlejandro Lucero int err;
601*cfcb9428SAlejandro Lucero
602*cfcb9428SAlejandro Lucero /* Several different MCDI commands are used. We report if errors
603*cfcb9428SAlejandro Lucero * happened through extack. Specific error information via system
604*cfcb9428SAlejandro Lucero * messages inside the calls.
605*cfcb9428SAlejandro Lucero */
60614743dddSAlejandro Lucero err = efx_devlink_info_board_cfg(efx, req);
60714743dddSAlejandro Lucero
60814743dddSAlejandro Lucero err |= efx_devlink_info_stored_versions(efx, req);
60914743dddSAlejandro Lucero
610fa34a514SAlejandro Lucero err |= efx_devlink_info_running_versions(efx, req);
61114743dddSAlejandro Lucero
612fa78b017SAlejandro Lucero if (err)
613fa78b017SAlejandro Lucero NL_SET_ERR_MSG_MOD(extack, "Errors when getting device info. Check system messages");
6143b6096c9SAlejandro Lucero
615fa78b017SAlejandro Lucero return 0;
616fa34a514SAlejandro Lucero }
617fa34a514SAlejandro Lucero
61825414b2aSAlejandro Lucero static const struct devlink_ops sfc_devlink_ops = {
61925414b2aSAlejandro Lucero .info_get = efx_devlink_info_get,
62025414b2aSAlejandro Lucero };
62125414b2aSAlejandro Lucero
62225414b2aSAlejandro Lucero #ifdef CONFIG_SFC_SRIOV
ef100_set_devlink_port(struct efx_nic * efx,u32 idx)62325414b2aSAlejandro Lucero static struct devlink_port *ef100_set_devlink_port(struct efx_nic *efx, u32 idx)
62425414b2aSAlejandro Lucero {
62525414b2aSAlejandro Lucero struct mae_mport_desc *mport;
62625414b2aSAlejandro Lucero u32 id;
62725414b2aSAlejandro Lucero int rc;
62825414b2aSAlejandro Lucero
62925414b2aSAlejandro Lucero if (!efx->mae)
63025414b2aSAlejandro Lucero return NULL;
63125414b2aSAlejandro Lucero
63225414b2aSAlejandro Lucero if (efx_mae_lookup_mport(efx, idx, &id)) {
63325414b2aSAlejandro Lucero /* This should not happen. */
63425414b2aSAlejandro Lucero if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
63525414b2aSAlejandro Lucero pci_warn_once(efx->pci_dev, "No mport ID found for PF.\n");
63625414b2aSAlejandro Lucero else
63725414b2aSAlejandro Lucero pci_warn_once(efx->pci_dev, "No mport ID found for VF %u.\n",
63825414b2aSAlejandro Lucero idx);
63925414b2aSAlejandro Lucero return NULL;
64025414b2aSAlejandro Lucero }
64125414b2aSAlejandro Lucero
64225414b2aSAlejandro Lucero mport = efx_mae_get_mport(efx, id);
64325414b2aSAlejandro Lucero if (!mport) {
64425414b2aSAlejandro Lucero /* This should not happen. */
64525414b2aSAlejandro Lucero if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
64625414b2aSAlejandro Lucero pci_warn_once(efx->pci_dev, "No mport found for PF.\n");
64725414b2aSAlejandro Lucero else
64825414b2aSAlejandro Lucero pci_warn_once(efx->pci_dev, "No mport found for VF %u.\n",
64925414b2aSAlejandro Lucero idx);
65025414b2aSAlejandro Lucero return NULL;
65125414b2aSAlejandro Lucero }
65225414b2aSAlejandro Lucero
6530d39ad3eSColin Ian King rc = efx_devlink_add_port(efx, mport);
65425414b2aSAlejandro Lucero if (rc) {
65525414b2aSAlejandro Lucero if (idx == MAE_MPORT_DESC_VF_IDX_NULL)
65625414b2aSAlejandro Lucero pci_warn(efx->pci_dev,
65725414b2aSAlejandro Lucero "devlink port creation for PF failed.\n");
65825414b2aSAlejandro Lucero else
65925414b2aSAlejandro Lucero pci_warn(efx->pci_dev,
66025414b2aSAlejandro Lucero "devlink_port creation for VF %u failed.\n",
66125414b2aSAlejandro Lucero idx);
66225414b2aSAlejandro Lucero return NULL;
66325414b2aSAlejandro Lucero }
66425414b2aSAlejandro Lucero
66525414b2aSAlejandro Lucero return &mport->dl_port;
66625414b2aSAlejandro Lucero }
66725414b2aSAlejandro Lucero
ef100_rep_set_devlink_port(struct efx_rep * efv)66825414b2aSAlejandro Lucero void ef100_rep_set_devlink_port(struct efx_rep *efv)
66925414b2aSAlejandro Lucero {
67025414b2aSAlejandro Lucero efv->dl_port = ef100_set_devlink_port(efv->parent, efv->idx);
67125414b2aSAlejandro Lucero }
67225414b2aSAlejandro Lucero
ef100_pf_set_devlink_port(struct efx_nic * efx)67325414b2aSAlejandro Lucero void ef100_pf_set_devlink_port(struct efx_nic *efx)
67425414b2aSAlejandro Lucero {
67525414b2aSAlejandro Lucero efx->dl_port = ef100_set_devlink_port(efx, MAE_MPORT_DESC_VF_IDX_NULL);
67625414b2aSAlejandro Lucero }
67725414b2aSAlejandro Lucero
ef100_rep_unset_devlink_port(struct efx_rep * efv)67825414b2aSAlejandro Lucero void ef100_rep_unset_devlink_port(struct efx_rep *efv)
67925414b2aSAlejandro Lucero {
68025414b2aSAlejandro Lucero efx_devlink_del_port(efv->dl_port);
68125414b2aSAlejandro Lucero }
682fa34a514SAlejandro Lucero
ef100_pf_unset_devlink_port(struct efx_nic * efx)683fa34a514SAlejandro Lucero void ef100_pf_unset_devlink_port(struct efx_nic *efx)
684fa34a514SAlejandro Lucero {
685fa34a514SAlejandro Lucero efx_devlink_del_port(efx->dl_port);
686fa34a514SAlejandro Lucero }
687fa34a514SAlejandro Lucero #endif
688fa34a514SAlejandro Lucero
efx_fini_devlink_lock(struct efx_nic * efx)689fa34a514SAlejandro Lucero void efx_fini_devlink_lock(struct efx_nic *efx)
690fa34a514SAlejandro Lucero {
691fa34a514SAlejandro Lucero if (efx->devlink)
692fa34a514SAlejandro Lucero devl_lock(efx->devlink);
693fa34a514SAlejandro Lucero }
694fa34a514SAlejandro Lucero
efx_fini_devlink_and_unlock(struct efx_nic * efx)695fa34a514SAlejandro Lucero void efx_fini_devlink_and_unlock(struct efx_nic *efx)
696fa34a514SAlejandro Lucero {
697fa34a514SAlejandro Lucero if (efx->devlink) {
698fa34a514SAlejandro Lucero devl_unregister(efx->devlink);
699fa34a514SAlejandro Lucero devl_unlock(efx->devlink);
700fa34a514SAlejandro Lucero devlink_free(efx->devlink);
701fa34a514SAlejandro Lucero efx->devlink = NULL;
702fa34a514SAlejandro Lucero }
703fa34a514SAlejandro Lucero }
704fa34a514SAlejandro Lucero
efx_probe_devlink_and_lock(struct efx_nic * efx)705fa34a514SAlejandro Lucero int efx_probe_devlink_and_lock(struct efx_nic *efx)
706fa34a514SAlejandro Lucero {
707fa34a514SAlejandro Lucero struct efx_devlink *devlink_private;
708fa34a514SAlejandro Lucero
709fa34a514SAlejandro Lucero if (efx->type->is_vf)
710fa34a514SAlejandro Lucero return 0;
711fa34a514SAlejandro Lucero
712fa34a514SAlejandro Lucero efx->devlink = devlink_alloc(&sfc_devlink_ops,
713fa34a514SAlejandro Lucero sizeof(struct efx_devlink),
714fa34a514SAlejandro Lucero &efx->pci_dev->dev);
715fa34a514SAlejandro Lucero if (!efx->devlink)
716fa34a514SAlejandro Lucero return -ENOMEM;
717fa34a514SAlejandro Lucero
718fa34a514SAlejandro Lucero devl_lock(efx->devlink);
719fa34a514SAlejandro Lucero devlink_private = devlink_priv(efx->devlink);
720fa34a514SAlejandro Lucero devlink_private->efx = efx;
721fa34a514SAlejandro Lucero
722fa34a514SAlejandro Lucero devl_register(efx->devlink);
723fa34a514SAlejandro Lucero
724fa34a514SAlejandro Lucero return 0;
725fa34a514SAlejandro Lucero }
726fa34a514SAlejandro Lucero
efx_probe_devlink_unlock(struct efx_nic * efx)727 void efx_probe_devlink_unlock(struct efx_nic *efx)
728 {
729 if (!efx->devlink)
730 return;
731
732 devl_unlock(efx->devlink);
733 }
734