1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2019 Solarflare Communications Inc.
6 * This software was jointly developed between OKTET Labs (under contract
7 * for Solarflare) and Solarflare Communications, Inc.
10 #include <rte_common.h>
11 #include <rte_bus_pci.h>
20 * Check if a MAC address is already assigned to one of previously
21 * configured vPorts (either PF itself or one of already configured VFs).
23 * Typically the first vPort which corresponds to PF has globally
24 * administered unicast address, but it still could be locally
25 * administered if user assigned it or in the case of unconfigured NIC.
26 * So, it is safer to include it as well in uniqueness check.
29 sriov_mac_addr_assigned(const efx_vport_config_t *vport_config,
30 unsigned int num, const uint8_t *mac_addr)
34 /* Check PF's MAC address as well as explained above */
35 for (i = 0; i < num; ++i) {
36 if (memcmp(mac_addr, vport_config[i].evc_mac_addr,
37 sizeof(vport_config[i].evc_mac_addr)) == 0)
45 sfc_sriov_attach(struct sfc_adapter *sa)
47 const struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
48 struct sfc_sriov *sriov = &sa->sriov;
49 efx_vport_config_t *vport_config;
53 sfc_log_init(sa, "entry");
55 sriov->num_vfs = pci_dev->max_vfs;
56 if (sa->switchdev || sriov->num_vfs == 0)
59 vport_config = calloc(sriov->num_vfs + 1, sizeof(*vport_config));
60 if (vport_config == NULL) {
62 goto fail_alloc_vport_config;
65 vport_config[0].evc_function = 0xffff;
66 vport_config[0].evc_vid = EFX_VF_VID_DEFAULT;
67 vport_config[0].evc_vlan_restrict = B_FALSE;
69 for (i = 1; i <= sriov->num_vfs; ++i) {
70 vport_config[i].evc_function = i - 1;
71 vport_config[i].evc_vid = EFX_VF_VID_DEFAULT;
72 vport_config[i].evc_vlan_restrict = B_FALSE;
74 rte_eth_random_addr(vport_config[i].evc_mac_addr);
75 } while (sriov_mac_addr_assigned(vport_config, i,
76 vport_config[i].evc_mac_addr));
79 sriov->vport_config = vport_config;
82 sfc_log_init(sa, "done");
85 fail_alloc_vport_config:
91 sfc_sriov_detach(struct sfc_adapter *sa)
93 struct sfc_sriov *sriov = &sa->sriov;
95 sfc_log_init(sa, "entry");
97 free(sriov->vport_config);
98 sriov->vport_config = NULL;
101 sfc_log_init(sa, "done");
105 sfc_sriov_vswitch_create(struct sfc_adapter *sa)
107 struct sfc_sriov *sriov = &sa->sriov;
108 efx_vport_config_t *vport_config = sriov->vport_config;
111 sfc_log_init(sa, "entry");
114 sfc_log_init(sa, "don't create vswitch in switchdev mode");
118 if (sriov->num_vfs == 0) {
119 sfc_log_init(sa, "no VFs enabled");
123 rc = efx_evb_init(sa->nic);
125 sfc_err(sa, "EVB init failed %d", rc);
129 RTE_BUILD_BUG_ON(sizeof(sa->port.default_mac_addr) !=
130 sizeof(vport_config[0].evc_mac_addr));
131 rte_ether_addr_copy(&sa->port.default_mac_addr,
132 (struct rte_ether_addr *)vport_config[0].evc_mac_addr);
134 rc = efx_evb_vswitch_create(sa->nic, sriov->num_vfs + 1,
135 vport_config, &sriov->vswitch);
137 sfc_err(sa, "EVB vSwitch create failed %d", rc);
138 goto fail_evb_vswitch_create;
142 sfc_log_init(sa, "done");
145 fail_evb_vswitch_create:
146 efx_evb_fini(sa->nic);
153 sfc_sriov_vswitch_destroy(struct sfc_adapter *sa)
155 struct sfc_sriov *sriov = &sa->sriov;
158 sfc_log_init(sa, "entry");
160 if (sa->switchdev || sriov->num_vfs == 0)
163 rc = efx_evb_vswitch_destroy(sa->nic, sriov->vswitch);
165 sfc_err(sa, "efx_evb_vswitch_destroy() failed %d", rc);
167 sriov->vswitch = NULL;
169 efx_evb_fini(sa->nic);
172 sfc_log_init(sa, "done");