1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2024 Marvell. 3 */ 4 5 #include <cnxk_eswitch.h> 6 7 #define PF_SHIFT 10 8 static inline int 9 get_hw_func(uint16_t pf, uint16_t vf) 10 { 11 return (pf << PF_SHIFT) | vf; 12 } 13 14 static int 15 populate_repr_hw_info(struct cnxk_eswitch_dev *eswitch_dev, struct rte_eth_devargs *eth_da, 16 uint16_t idx) 17 { 18 struct cnxk_eswitch_devargs *esw_da = &eswitch_dev->esw_da[idx]; 19 uint16_t nb_repr_ports, hw_func; 20 int rc, i, j; 21 22 if (eth_da->type == RTE_ETH_REPRESENTOR_NONE) { 23 plt_err("No representor type found"); 24 return -EINVAL; 25 } 26 27 if (eth_da->type != RTE_ETH_REPRESENTOR_VF && eth_da->type != RTE_ETH_REPRESENTOR_PF && 28 eth_da->type != RTE_ETH_REPRESENTOR_SF) { 29 plt_err("unsupported representor type %d", eth_da->type); 30 return -ENOTSUP; 31 } 32 33 nb_repr_ports = (eth_da->type == RTE_ETH_REPRESENTOR_PF) ? eth_da->nb_ports : 34 eth_da->nb_representor_ports; 35 esw_da->nb_repr_ports = nb_repr_ports; 36 /* If plain list is provided as representor pattern */ 37 if (eth_da->nb_ports == 0) 38 return 0; 39 40 esw_da->repr_hw_info = plt_zmalloc(nb_repr_ports * sizeof(struct cnxk_esw_repr_hw_info), 0); 41 if (!esw_da->repr_hw_info) { 42 plt_err("Failed to allocate memory"); 43 rc = -ENOMEM; 44 goto fail; 45 } 46 47 plt_esw_dbg("Representor param %d has %d pfvf", idx, nb_repr_ports); 48 /* Check if representor can be created for PFVF and populating HW func list */ 49 for (i = 0; i < nb_repr_ports; i++) { 50 if (eth_da->type == RTE_ETH_REPRESENTOR_PF) 51 hw_func = get_hw_func(eth_da->ports[i], 0); 52 else 53 hw_func = get_hw_func(eth_da->ports[0], eth_da->representor_ports[i] + 1); 54 55 for (j = 0; j < eswitch_dev->repr_cnt.max_repr; j++) { 56 if (eswitch_dev->nix.rep_pfvf_map[j] == hw_func) 57 break; 58 } 59 60 /* HW func which doesn not match the map table received from AF, no 61 * representor port is assigned. 62 */ 63 if (j == eswitch_dev->repr_cnt.max_repr) { 64 plt_err("Representor port can't be created for PF%dVF%d", eth_da->ports[0], 65 eth_da->representor_ports[i]); 66 rc = -EINVAL; 67 goto fail; 68 } 69 70 esw_da->repr_hw_info[i].hw_func = hw_func; 71 esw_da->repr_hw_info[i].rep_id = j; 72 esw_da->repr_hw_info[i].pfvf = (eth_da->type == RTE_ETH_REPRESENTOR_PF) ? 73 eth_da->ports[0] : 74 eth_da->representor_ports[i]; 75 TAILQ_INIT(&esw_da->repr_hw_info[i].repr_flow_list); 76 plt_esw_dbg(" HW func %x index %d type %d", hw_func, j, eth_da->type); 77 } 78 79 esw_da->type = CNXK_ESW_DA_TYPE_PFVF; 80 81 return 0; 82 fail: 83 return rc; 84 } 85 86 int 87 cnxk_eswitch_repr_devargs(struct rte_pci_device *pci_dev, struct cnxk_eswitch_dev *eswitch_dev) 88 { 89 struct rte_devargs *devargs = pci_dev->device.devargs; 90 struct rte_eth_devargs eth_da[RTE_MAX_ETHPORTS]; 91 int rc, i, j, count; 92 93 if (devargs == NULL) { 94 plt_err("No devargs passed"); 95 rc = -EINVAL; 96 goto fail; 97 } 98 99 /* Parse devargs passed to ESW device */ 100 rc = rte_eth_devargs_parse(devargs->args, eth_da, RTE_MAX_ETHPORTS); 101 if (rc < 0) { 102 plt_err("Failed to parse devargs, err %d", rc); 103 goto fail; 104 } 105 106 count = rc; 107 j = eswitch_dev->nb_esw_da; 108 for (i = 0; i < count; i++) { 109 rc = populate_repr_hw_info(eswitch_dev, ð_da[i], j); 110 if (rc) { 111 plt_err("Failed to populate representer hw funcs, err %d", rc); 112 goto fail; 113 } 114 115 rte_memcpy(&eswitch_dev->esw_da[j].da, ð_da[i], sizeof(struct rte_eth_devargs)); 116 /* No of representor ports to be created */ 117 eswitch_dev->repr_cnt.nb_repr_created += eswitch_dev->esw_da[j].nb_repr_ports; 118 j++; 119 } 120 eswitch_dev->nb_esw_da += count; 121 122 return 0; 123 fail: 124 return rc; 125 } 126