* Spawn an Ethernet device from Verbs information. * * @param dpdk_dev * Backing DPDK device. * @param spawn * Verbs device parameters (name, port, switch_info) to spawn. * @param eth_da * Device arguments. * @param mkvlist * Pointer to mlx5 kvargs control, can be NULL if there is no devargs. * * @return * A valid Ethernet device object on success, NULL otherwise and rte_errn
| 1098 | * EEXIST: device is already spawned |
| 1099 | */ |
| 1100 | static struct rte_eth_dev * |
| 1101 | mlx5_dev_spawn(struct rte_device *dpdk_dev, |
| 1102 | struct mlx5_dev_spawn_data *spawn, |
| 1103 | struct rte_eth_devargs *eth_da, |
| 1104 | struct mlx5_kvargs_ctrl *mkvlist) |
| 1105 | { |
| 1106 | const struct mlx5_switch_info *switch_info = &spawn->info; |
| 1107 | struct mlx5_dev_ctx_shared *sh = NULL; |
| 1108 | struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP }; |
| 1109 | struct rte_eth_dev *eth_dev = NULL; |
| 1110 | struct mlx5_priv *priv = NULL; |
| 1111 | int err = 0; |
| 1112 | struct rte_ether_addr mac; |
| 1113 | char name[RTE_ETH_NAME_MAX_LEN]; |
| 1114 | int own_domain_id = 0; |
| 1115 | uint16_t port_id; |
| 1116 | struct mlx5_port_info vport_info = { .query_flags = 0 }; |
| 1117 | int nl_rdma; |
| 1118 | int i; |
| 1119 | |
| 1120 | /* Determine if this port representor is supposed to be spawned. */ |
| 1121 | if (switch_info->representor && dpdk_dev->devargs && |
| 1122 | !mlx5_representor_match(spawn, eth_da)) |
| 1123 | return NULL; |
| 1124 | /* Build device name. */ |
| 1125 | if (spawn->pf_bond >= 0) { |
| 1126 | /* Bonding device. */ |
| 1127 | if (!switch_info->representor) { |
| 1128 | err = snprintf(name, sizeof(name), "%s_%s", |
| 1129 | dpdk_dev->name, spawn->phys_dev_name); |
| 1130 | } else { |
| 1131 | err = snprintf(name, sizeof(name), "%s_%s_representor_c%dpf%d%s%u", |
| 1132 | dpdk_dev->name, spawn->phys_dev_name, |
| 1133 | switch_info->ctrl_num, |
| 1134 | switch_info->pf_num, |
| 1135 | switch_info->name_type == |
| 1136 | MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", |
| 1137 | switch_info->port_name); |
| 1138 | } |
| 1139 | } else if (mlx5_is_probed_port_on_mpesw_device(spawn)) { |
| 1140 | /* MPESW device. */ |
| 1141 | if (switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) { |
| 1142 | err = snprintf(name, sizeof(name), "%s_p%d", |
| 1143 | dpdk_dev->name, spawn->mpesw_port); |
| 1144 | } else { |
| 1145 | err = snprintf(name, sizeof(name), "%s_representor_c%dpf%d%s%u", |
| 1146 | dpdk_dev->name, |
| 1147 | switch_info->ctrl_num, |
| 1148 | switch_info->pf_num, |
| 1149 | switch_info->name_type == |
| 1150 | MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", |
| 1151 | switch_info->port_name); |
| 1152 | } |
| 1153 | } else { |
| 1154 | /* Single device. */ |
| 1155 | if (!switch_info->representor) |
| 1156 | strlcpy(name, dpdk_dev->name, sizeof(name)); |
| 1157 | else |
no test coverage detected