+ char name[RTE_ETH_NAME_MAX_LEN];
+ struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
+ struct rte_eth_dev *backing_eth_dev, *vf_rep_eth_dev;
+ uint16_t num_rep;
+ int i, ret = 0;
+ struct bnxt *backing_bp;
+
+ if (pci_dev->device.devargs) {
+ ret = rte_eth_devargs_parse(pci_dev->device.devargs->args,
+ ð_da);
+ if (ret)
+ return ret;
+ }
+
+ num_rep = eth_da.nb_representor_ports;
+ PMD_DRV_LOG(DEBUG, "nb_representor_ports = %d\n",
+ num_rep);
+
+ /* We could come here after first level of probe is already invoked
+ * as part of an application bringup(OVS-DPDK vswitchd), so first check
+ * for already allocated eth_dev for the backing device (PF/Trusted VF)
+ */
+ backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
+ if (backing_eth_dev == NULL) {
+ ret = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
+ sizeof(struct bnxt),
+ eth_dev_pci_specific_init, pci_dev,
+ bnxt_dev_init, NULL);
+
+ if (ret || !num_rep)
+ return ret;
+ }
+
+ if (num_rep > BNXT_MAX_VF_REPS) {
+ PMD_DRV_LOG(ERR, "nb_representor_ports = %d > %d MAX VF REPS\n",
+ eth_da.nb_representor_ports, BNXT_MAX_VF_REPS);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ /* probe representor ports now */
+ if (!backing_eth_dev)
+ backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
+ if (backing_eth_dev == NULL) {
+ ret = -ENODEV;
+ return ret;
+ }
+ backing_bp = backing_eth_dev->data->dev_private;
+
+ if (!(BNXT_PF(backing_bp) || BNXT_VF_IS_TRUSTED(backing_bp))) {
+ PMD_DRV_LOG(ERR,
+ "Not a PF or trusted VF. No Representor support\n");
+ /* Returning an error is not an option.
+ * Applications are not handling this correctly
+ */
+ return ret;
+ }
+
+ for (i = 0; i < eth_da.nb_representor_ports; i++) {
+ struct bnxt_vf_representor representor = {
+ .vf_id = eth_da.representor_ports[i],
+ .switch_domain_id = backing_bp->switch_domain_id,
+ .parent_priv = backing_bp
+ };
+
+ if (representor.vf_id >= BNXT_MAX_VF_REPS) {
+ PMD_DRV_LOG(ERR, "VF-Rep id %d >= %d MAX VF ID\n",
+ representor.vf_id, BNXT_MAX_VF_REPS);
+ continue;
+ }
+
+ /* representor port net_bdf_port */
+ snprintf(name, sizeof(name), "net_%s_representor_%d",
+ pci_dev->device.name, eth_da.representor_ports[i]);
+
+ ret = rte_eth_dev_create(&pci_dev->device, name,
+ sizeof(struct bnxt_vf_representor),
+ NULL, NULL,
+ bnxt_vf_representor_init,
+ &representor);
+
+ if (!ret) {
+ vf_rep_eth_dev = rte_eth_dev_allocated(name);
+ if (!vf_rep_eth_dev) {
+ PMD_DRV_LOG(ERR, "Failed to find the eth_dev"
+ " for VF-Rep: %s.", name);
+ bnxt_pci_remove_dev_with_reps(backing_eth_dev);
+ ret = -ENODEV;
+ return ret;
+ }
+ backing_bp->rep_info[representor.vf_id].vfr_eth_dev =
+ vf_rep_eth_dev;
+ backing_bp->num_reps++;
+ } else {
+ PMD_DRV_LOG(ERR, "failed to create bnxt vf "
+ "representor %s.", name);
+ bnxt_pci_remove_dev_with_reps(backing_eth_dev);
+ }
+ }
+
+ return ret;