Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright 2015 6WIND S.A. 3 : : * Copyright 2015 Mellanox Technologies, Ltd 4 : : */ 5 : : 6 : : #include <stddef.h> 7 : : #include <errno.h> 8 : : #include <stdint.h> 9 : : #include <unistd.h> 10 : : 11 : : /* 12 : : * Not needed by this file; included to work around the lack of off_t 13 : : * definition for mlx5dv.h with unpatched rdma-core versions. 14 : : */ 15 : : #include <sys/types.h> 16 : : 17 : : #include <ethdev_driver.h> 18 : : #include <rte_common.h> 19 : : #include <rte_malloc.h> 20 : : #include <rte_hypervisor.h> 21 : : 22 : : #include <mlx5.h> 23 : : #include <mlx5_nl.h> 24 : : #include <mlx5_malloc.h> 25 : : 26 : : /* 27 : : * Release VLAN network device, created for VM workaround. 28 : : * 29 : : * @param[in] dev 30 : : * Ethernet device object, Netlink context provider. 31 : : * @param[in] vlan 32 : : * Object representing the network device to release. 33 : : */ 34 : : void 35 : 0 : mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, 36 : : struct mlx5_vf_vlan *vlan) 37 : : { 38 : 0 : struct mlx5_priv *priv = dev->data->dev_private; 39 : 0 : struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context; 40 : 0 : struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; 41 : : 42 : : MLX5_ASSERT(vlan->created); 43 : : MLX5_ASSERT(priv->vmwa_context); 44 [ # # # # ]: 0 : if (!vlan->created || !vmwa) 45 : : return; 46 : 0 : vlan->created = 0; 47 : 0 : rte_spinlock_lock(&vmwa->sl); 48 : : MLX5_ASSERT(vlan_dev[vlan->tag].refcnt); 49 [ # # ]: 0 : if (--vlan_dev[vlan->tag].refcnt == 0 && 50 [ # # ]: 0 : vlan_dev[vlan->tag].ifindex) { 51 : 0 : mlx5_nl_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex); 52 : 0 : vlan_dev[vlan->tag].ifindex = 0; 53 : : } 54 : : rte_spinlock_unlock(&vmwa->sl); 55 : : } 56 : : 57 : : /** 58 : : * Acquire VLAN interface with specified tag for VM workaround. 59 : : * 60 : : * @param[in] dev 61 : : * Ethernet device object, Netlink context provider. 62 : : * @param[in] vlan 63 : : * Object representing the network device to acquire. 64 : : */ 65 : : void 66 : 0 : mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, 67 : : struct mlx5_vf_vlan *vlan) 68 : : { 69 : 0 : struct mlx5_priv *priv = dev->data->dev_private; 70 : 0 : struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context; 71 : 0 : struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; 72 : : 73 : : MLX5_ASSERT(!vlan->created); 74 : : MLX5_ASSERT(priv->vmwa_context); 75 [ # # # # ]: 0 : if (vlan->created || !vmwa) 76 : : return; 77 : 0 : rte_spinlock_lock(&vmwa->sl); 78 [ # # ]: 0 : if (vlan_dev[vlan->tag].refcnt == 0) { 79 : : MLX5_ASSERT(!vlan_dev[vlan->tag].ifindex); 80 : 0 : vlan_dev[vlan->tag].ifindex = 81 : 0 : mlx5_nl_vlan_vmwa_create(vmwa, vmwa->vf_ifindex, 82 : : vlan->tag); 83 : : } 84 [ # # ]: 0 : if (vlan_dev[vlan->tag].ifindex) { 85 : 0 : vlan_dev[vlan->tag].refcnt++; 86 : 0 : vlan->created = 1; 87 : : } 88 : : rte_spinlock_unlock(&vmwa->sl); 89 : : } 90 : : 91 : : /* 92 : : * Create per ethernet device VLAN VM workaround context 93 : : * 94 : : * @param dev 95 : : * Pointer to Ethernet device structure. 96 : : * @param ifindex 97 : : * Interface index. 98 : : * 99 : : * @Return 100 : : * Pointer to mlx5_nl_vlan_vmwa_context 101 : : */ 102 : : void * 103 : 0 : mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex) 104 : : { 105 : 0 : struct mlx5_priv *priv = dev->data->dev_private; 106 : : struct mlx5_nl_vlan_vmwa_context *vmwa; 107 : : enum rte_hypervisor hv_type; 108 : : 109 : : /* Do not engage workaround over PF. */ 110 [ # # ]: 0 : if (!priv->sh->dev_cap.vf) 111 : : return NULL; 112 : : /* Check whether there is desired virtual environment */ 113 : 0 : hv_type = rte_hypervisor_get(); 114 [ # # ]: 0 : switch (hv_type) { 115 : : case RTE_HYPERVISOR_UNKNOWN: 116 : : case RTE_HYPERVISOR_VMWARE: 117 : : /* 118 : : * The "white list" of configurations 119 : : * to engage the workaround. 120 : : */ 121 : : break; 122 : : default: 123 : : /* 124 : : * The configuration is not found in the "white list". 125 : : * We should not engage the VLAN workaround. 126 : : */ 127 : : return NULL; 128 : : } 129 : 0 : vmwa = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*vmwa), sizeof(uint32_t), 130 : : SOCKET_ID_ANY); 131 [ # # ]: 0 : if (!vmwa) { 132 : 0 : DRV_LOG(WARNING, 133 : : "Can not allocate memory" 134 : : " for VLAN workaround context"); 135 : 0 : return NULL; 136 : : } 137 : : rte_spinlock_init(&vmwa->sl); 138 : 0 : vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE, 0); 139 [ # # ]: 0 : if (vmwa->nl_socket < 0) { 140 : 0 : DRV_LOG(WARNING, 141 : : "Can not create Netlink socket" 142 : : " for VLAN workaround context"); 143 : 0 : mlx5_free(vmwa); 144 : 0 : return NULL; 145 : : } 146 : 0 : vmwa->vf_ifindex = ifindex; 147 : : /* Cleanup for existing VLAN devices. */ 148 : 0 : return vmwa; 149 : : } 150 : : 151 : : /* 152 : : * Destroy per ethernet device VLAN VM workaround context 153 : : * 154 : : * @param dev 155 : : * Pointer to VM context 156 : : */ 157 : : void 158 : 0 : mlx5_vlan_vmwa_exit(void *vmctx) 159 : : { 160 : : unsigned int i; 161 : : 162 : : struct mlx5_nl_vlan_vmwa_context *vmwa = vmctx; 163 : : /* Delete all remaining VLAN devices. */ 164 [ # # ]: 0 : for (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) { 165 [ # # ]: 0 : if (vmwa->vlan_dev[i].ifindex) 166 : 0 : mlx5_nl_vlan_vmwa_delete(vmwa, 167 : : vmwa->vlan_dev[i].ifindex); 168 : : } 169 [ # # ]: 0 : if (vmwa->nl_socket >= 0) 170 : 0 : close(vmwa->nl_socket); 171 : 0 : mlx5_free(vmwa); 172 : 0 : }