Skip to content

Commit fa15072

Browse files
author
Paolo Abeni
committed
Merge branch 'sfc-devlink-support-for-ef100'
Alejandro Lucero says: ==================== sfc: devlink support for ef100 This patchset adds devlink port support for ef100 allowing setting VFs mac addresses through the VF representor devlink ports. Basic devlink infrastructure is first introduced, then support for info command. Next changes for enumerating MAE ports which will be used for devlink port creation when netdevs are registered. Adding support for devlink port_function_hw_addr_get requires changes in the ef100 driver for getting the mac address based on a client handle. This allows to obtain VFs mac addresses during netdev initialization as well what is included in patch 6. Such client handle is used in patches 7 and 8 for getting and setting devlink port addresses. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents e9ab255 + 3b6096c commit fa15072

File tree

17 files changed

+1359
-25
lines changed

17 files changed

+1359
-25
lines changed

Documentation/networking/devlink/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ parameters, info versions, and other features it supports.
6666
prestera
6767
iosm
6868
octeontx2
69+
sfc
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
===================
4+
sfc devlink support
5+
===================
6+
7+
This document describes the devlink features implemented by the ``sfc``
8+
device driver for the ef100 device.
9+
10+
Info versions
11+
=============
12+
13+
The ``sfc`` driver reports the following versions
14+
15+
.. list-table:: devlink info versions implemented
16+
:widths: 5 5 90
17+
18+
* - Name
19+
- Type
20+
- Description
21+
* - ``fw.mgmt.suc``
22+
- running
23+
- For boards where the management function is split between multiple
24+
control units, this is the SUC control unit's firmware version.
25+
* - ``fw.mgmt.cmc``
26+
- running
27+
- For boards where the management function is split between multiple
28+
control units, this is the CMC control unit's firmware version.
29+
* - ``fpga.rev``
30+
- running
31+
- FPGA design revision.
32+
* - ``fpga.app``
33+
- running
34+
- Datapath programmable logic version.
35+
* - ``fw.app``
36+
- running
37+
- Datapath software/microcode/firmware version.
38+
* - ``coproc.boot``
39+
- running
40+
- SmartNIC application co-processor (APU) first stage boot loader version.
41+
* - ``coproc.uboot``
42+
- running
43+
- SmartNIC application co-processor (APU) co-operating system loader version.
44+
* - ``coproc.main``
45+
- running
46+
- SmartNIC application co-processor (APU) main operating system version.
47+
* - ``coproc.recovery``
48+
- running
49+
- SmartNIC application co-processor (APU) recovery operating system version.
50+
* - ``fw.exprom``
51+
- running
52+
- Expansion ROM version. For boards where the expansion ROM is split between
53+
multiple images (e.g. PXE and UEFI), this is the specifically the PXE boot
54+
ROM version.
55+
* - ``fw.uefi``
56+
- running
57+
- UEFI driver version (No UNDI support).

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18937,6 +18937,7 @@ M: Edward Cree <[email protected]>
1893718937
M: Martin Habets <[email protected]>
1893818938
1893918939
S: Supported
18940+
F: Documentation/networking/devlink/sfc.rst
1894018941
F: drivers/net/ethernet/sfc/
1894118942

1894218943
SFF/SFP/SFP+ MODULE SUPPORT

drivers/net/ethernet/sfc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ config SFC
2222
depends on PTP_1588_CLOCK_OPTIONAL
2323
select MDIO
2424
select CRC32
25+
select NET_DEVLINK
2526
help
2627
This driver supports 10/40-gigabit Ethernet cards based on
2728
the Solarflare SFC9100-family controllers.

drivers/net/ethernet/sfc/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
66
mcdi.o mcdi_port.o mcdi_port_common.o \
77
mcdi_functions.o mcdi_filters.o mcdi_mon.o \
88
ef100.o ef100_nic.o ef100_netdev.o \
9-
ef100_ethtool.o ef100_rx.o ef100_tx.o
9+
ef100_ethtool.o ef100_rx.o ef100_tx.o \
10+
efx_devlink.o
1011
sfc-$(CONFIG_SFC_MTD) += mtd.o
1112
sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
1213
mae.o tc.o tc_bindings.o tc_counters.o

drivers/net/ethernet/sfc/ef100_netdev.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "rx_common.h"
2525
#include "ef100_sriov.h"
2626
#include "tc_bindings.h"
27+
#include "efx_devlink.h"
2728

2829
static void ef100_update_name(struct efx_nic *efx)
2930
{
@@ -332,9 +333,11 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)
332333
efx_ef100_pci_sriov_disable(efx, true);
333334
#endif
334335

336+
efx_fini_devlink_lock(efx);
335337
ef100_unregister_netdev(efx);
336338

337339
#ifdef CONFIG_SFC_SRIOV
340+
ef100_pf_unset_devlink_port(efx);
338341
efx_fini_tc(efx);
339342
#endif
340343

@@ -345,6 +348,8 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)
345348
kfree(efx->phy_data);
346349
efx->phy_data = NULL;
347350

351+
efx_fini_devlink_and_unlock(efx);
352+
348353
free_netdev(efx->net_dev);
349354
efx->net_dev = NULL;
350355
efx->state = STATE_PROBED;
@@ -354,6 +359,7 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
354359
{
355360
struct efx_nic *efx = &probe_data->efx;
356361
struct efx_probe_data **probe_ptr;
362+
struct ef100_nic_data *nic_data;
357363
struct net_device *net_dev;
358364
int rc;
359365

@@ -405,6 +411,20 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
405411
/* Don't fail init if RSS setup doesn't work. */
406412
efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels);
407413

414+
nic_data = efx->nic_data;
415+
rc = ef100_get_mac_address(efx, net_dev->perm_addr, CLIENT_HANDLE_SELF,
416+
efx->type->is_vf);
417+
if (rc)
418+
return rc;
419+
/* Assign MAC address */
420+
eth_hw_addr_set(net_dev, net_dev->perm_addr);
421+
ether_addr_copy(nic_data->port_id, net_dev->perm_addr);
422+
423+
/* devlink creation, registration and lock */
424+
rc = efx_probe_devlink_and_lock(efx);
425+
if (rc)
426+
pci_info(efx->pci_dev, "devlink registration failed");
427+
408428
rc = ef100_register_netdev(efx);
409429
if (rc)
410430
goto fail;
@@ -413,6 +433,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
413433
rc = ef100_probe_netdev_pf(efx);
414434
if (rc)
415435
goto fail;
436+
#ifdef CONFIG_SFC_SRIOV
437+
ef100_pf_set_devlink_port(efx);
438+
#endif
416439
}
417440

418441
efx->netdev_notifier.notifier_call = ef100_netdev_event;
@@ -423,6 +446,13 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
423446
goto fail;
424447
}
425448

449+
efx_probe_devlink_unlock(efx);
450+
return rc;
426451
fail:
452+
#ifdef CONFIG_SFC_SRIOV
453+
/* remove devlink port if does exist */
454+
ef100_pf_unset_devlink_port(efx);
455+
#endif
456+
efx_probe_devlink_unlock(efx);
427457
return rc;
428458
}

drivers/net/ethernet/sfc/ef100_nic.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,23 +130,34 @@ static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
130130

131131
/* MCDI calls
132132
*/
133-
static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address)
133+
int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address,
134+
int client_handle, bool empty_ok)
134135
{
135-
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
136+
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CLIENT_MAC_ADDRESSES_OUT_LEN(1));
137+
MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_CLIENT_MAC_ADDRESSES_IN_LEN);
136138
size_t outlen;
137139
int rc;
138140

139141
BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0);
142+
MCDI_SET_DWORD(inbuf, GET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
143+
client_handle);
140144

141-
rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0,
142-
outbuf, sizeof(outbuf), &outlen);
145+
rc = efx_mcdi_rpc(efx, MC_CMD_GET_CLIENT_MAC_ADDRESSES, inbuf,
146+
sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
143147
if (rc)
144148
return rc;
145-
if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
146-
return -EIO;
147149

148-
ether_addr_copy(mac_address,
149-
MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE));
150+
if (outlen >= MC_CMD_GET_CLIENT_MAC_ADDRESSES_OUT_LEN(1)) {
151+
ether_addr_copy(mac_address,
152+
MCDI_PTR(outbuf, GET_CLIENT_MAC_ADDRESSES_OUT_MAC_ADDRS));
153+
} else if (empty_ok) {
154+
pci_warn(efx->pci_dev,
155+
"No MAC address provisioned for client ID %#x.\n",
156+
client_handle);
157+
eth_zero_addr(mac_address);
158+
} else {
159+
return -ENOENT;
160+
}
150161
return 0;
151162
}
152163

@@ -736,7 +747,7 @@ static int efx_ef100_get_base_mport(struct efx_nic *efx)
736747
/* Construct mport selector for "physical network port" */
737748
efx_mae_mport_wire(efx, &selector);
738749
/* Look up actual mport ID */
739-
rc = efx_mae_lookup_mport(efx, selector, &id);
750+
rc = efx_mae_fw_lookup_mport(efx, selector, &id);
740751
if (rc)
741752
return rc;
742753
/* The ID should always fit in 16 bits, because that's how wide the
@@ -747,6 +758,19 @@ static int efx_ef100_get_base_mport(struct efx_nic *efx)
747758
id);
748759
nic_data->base_mport = id;
749760
nic_data->have_mport = true;
761+
762+
/* Construct mport selector for "calling PF" */
763+
efx_mae_mport_uplink(efx, &selector);
764+
/* Look up actual mport ID */
765+
rc = efx_mae_fw_lookup_mport(efx, selector, &id);
766+
if (rc)
767+
return rc;
768+
if (id >> 16)
769+
netif_warn(efx, probe, efx->net_dev, "Bad own m-port id %#x\n",
770+
id);
771+
nic_data->own_mport = id;
772+
nic_data->have_own_mport = true;
773+
750774
return 0;
751775
}
752776
#endif
@@ -1098,19 +1122,39 @@ static int ef100_probe_main(struct efx_nic *efx)
10981122
return rc;
10991123
}
11001124

1125+
/* MCDI commands are related to the same device issuing them. This function
1126+
* allows to do an MCDI command on behalf of another device, mainly PFs setting
1127+
* things for VFs.
1128+
*/
1129+
int efx_ef100_lookup_client_id(struct efx_nic *efx, efx_qword_t pciefn, u32 *id)
1130+
{
1131+
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CLIENT_HANDLE_OUT_LEN);
1132+
MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_CLIENT_HANDLE_IN_LEN);
1133+
u64 pciefn_flat = le64_to_cpu(pciefn.u64[0]);
1134+
size_t outlen;
1135+
int rc;
1136+
1137+
MCDI_SET_DWORD(inbuf, GET_CLIENT_HANDLE_IN_TYPE,
1138+
MC_CMD_GET_CLIENT_HANDLE_IN_TYPE_FUNC);
1139+
MCDI_SET_QWORD(inbuf, GET_CLIENT_HANDLE_IN_FUNC,
1140+
pciefn_flat);
1141+
1142+
rc = efx_mcdi_rpc(efx, MC_CMD_GET_CLIENT_HANDLE, inbuf, sizeof(inbuf),
1143+
outbuf, sizeof(outbuf), &outlen);
1144+
if (rc)
1145+
return rc;
1146+
if (outlen < sizeof(outbuf))
1147+
return -EIO;
1148+
*id = MCDI_DWORD(outbuf, GET_CLIENT_HANDLE_OUT_HANDLE);
1149+
return 0;
1150+
}
1151+
11011152
int ef100_probe_netdev_pf(struct efx_nic *efx)
11021153
{
11031154
struct ef100_nic_data *nic_data = efx->nic_data;
11041155
struct net_device *net_dev = efx->net_dev;
11051156
int rc;
11061157

1107-
rc = ef100_get_mac_address(efx, net_dev->perm_addr);
1108-
if (rc)
1109-
goto fail;
1110-
/* Assign MAC address */
1111-
eth_hw_addr_set(net_dev, net_dev->perm_addr);
1112-
memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN);
1113-
11141158
if (!nic_data->grp_mae)
11151159
return 0;
11161160

@@ -1126,6 +1170,14 @@ int ef100_probe_netdev_pf(struct efx_nic *efx)
11261170
rc);
11271171
}
11281172

1173+
rc = efx_init_mae(efx);
1174+
if (rc)
1175+
netif_warn(efx, probe, net_dev,
1176+
"Failed to init MAE rc %d; representors will not function\n",
1177+
rc);
1178+
else
1179+
efx_ef100_init_reps(efx);
1180+
11291181
rc = efx_init_tc(efx);
11301182
if (rc) {
11311183
/* Either we don't have an MAE at all (i.e. legacy v-switching),
@@ -1142,9 +1194,6 @@ int ef100_probe_netdev_pf(struct efx_nic *efx)
11421194
efx->fixed_features |= NETIF_F_HW_TC;
11431195
}
11441196
#endif
1145-
return 0;
1146-
1147-
fail:
11481197
return rc;
11491198
}
11501199

@@ -1157,6 +1206,12 @@ void ef100_remove(struct efx_nic *efx)
11571206
{
11581207
struct ef100_nic_data *nic_data = efx->nic_data;
11591208

1209+
#ifdef CONFIG_SFC_SRIOV
1210+
if (efx->mae) {
1211+
efx_ef100_fini_reps(efx);
1212+
efx_fini_mae(efx);
1213+
}
1214+
#endif
11601215
efx_mcdi_detach(efx);
11611216
efx_mcdi_fini(efx);
11621217
if (nic_data)

drivers/net/ethernet/sfc/ef100_nic.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ struct ef100_nic_data {
7474
u64 stats[EF100_STAT_COUNT];
7575
u32 base_mport;
7676
bool have_mport; /* base_mport was populated successfully */
77+
u32 own_mport;
78+
u32 local_mae_intf; /* interface_idx that corresponds to us, in mport enumerate */
79+
bool have_own_mport; /* own_mport was populated successfully */
80+
bool have_local_intf; /* local_mae_intf was populated successfully */
7781
bool grp_mae; /* MAE Privilege */
7882
u16 tso_max_hdr_len;
7983
u16 tso_max_payload_num_segs;
@@ -88,4 +92,7 @@ int efx_ef100_init_datapath_caps(struct efx_nic *efx);
8892
int ef100_phy_probe(struct efx_nic *efx);
8993
int ef100_filter_table_probe(struct efx_nic *efx);
9094

95+
int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address,
96+
int client_handle, bool empty_ok);
97+
int efx_ef100_lookup_client_id(struct efx_nic *efx, efx_qword_t pciefn, u32 *id);
9198
#endif /* EFX_EF100_NIC_H */

0 commit comments

Comments
 (0)