11def64c2SNipun Gupta /* SPDX-License-Identifier: BSD-3-Clause 200e928e9SSachin Saxena * Copyright 2018-2021,2023 NXP 31def64c2SNipun Gupta */ 41def64c2SNipun Gupta 51def64c2SNipun Gupta #include <sys/queue.h> 61def64c2SNipun Gupta #include <stdio.h> 71def64c2SNipun Gupta #include <errno.h> 81def64c2SNipun Gupta #include <stdint.h> 91def64c2SNipun Gupta #include <string.h> 101def64c2SNipun Gupta #include <unistd.h> 111def64c2SNipun Gupta #include <stdarg.h> 121def64c2SNipun Gupta 131def64c2SNipun Gupta #include <rte_ethdev.h> 141def64c2SNipun Gupta #include <rte_log.h> 151def64c2SNipun Gupta #include <rte_malloc.h> 161def64c2SNipun Gupta #include <rte_flow_driver.h> 171def64c2SNipun Gupta #include <rte_tailq.h> 181def64c2SNipun Gupta 19b4f22ca5SDavid Marchand #include <bus_fslmc_driver.h> 201def64c2SNipun Gupta #include <fsl_dpdmux.h> 211def64c2SNipun Gupta #include <fsl_dpkg.h> 221def64c2SNipun Gupta 231def64c2SNipun Gupta #include <dpaa2_ethdev.h> 241def64c2SNipun Gupta #include <dpaa2_pmd_logs.h> 251def64c2SNipun Gupta 261def64c2SNipun Gupta struct dpaa2_dpdmux_dev { 271def64c2SNipun Gupta TAILQ_ENTRY(dpaa2_dpdmux_dev) next; 281def64c2SNipun Gupta /**< Pointer to Next device instance */ 291def64c2SNipun Gupta struct fsl_mc_io dpdmux; /** handle to DPDMUX portal object */ 301def64c2SNipun Gupta uint16_t token; 311def64c2SNipun Gupta uint32_t dpdmux_id; /*HW ID for DPDMUX object */ 321def64c2SNipun Gupta uint8_t num_ifs; /* Number of interfaces in DPDMUX */ 331def64c2SNipun Gupta }; 341def64c2SNipun Gupta 35*25e5845bSJun Yang #define DPAA2_MUX_FLOW_MAX_RULE_NUM 8 36*25e5845bSJun Yang struct dpaa2_mux_flow { 37*25e5845bSJun Yang struct dpdmux_rule_cfg rule[DPAA2_MUX_FLOW_MAX_RULE_NUM]; 381def64c2SNipun Gupta }; 391def64c2SNipun Gupta 401def64c2SNipun Gupta TAILQ_HEAD(dpdmux_dev_list, dpaa2_dpdmux_dev); 411def64c2SNipun Gupta static struct dpdmux_dev_list dpdmux_dev_list = 421def64c2SNipun Gupta TAILQ_HEAD_INITIALIZER(dpdmux_dev_list); /*!< DPDMUX device list */ 431def64c2SNipun Gupta 441def64c2SNipun Gupta static struct dpaa2_dpdmux_dev *get_dpdmux_from_id(uint32_t dpdmux_id) 451def64c2SNipun Gupta { 461def64c2SNipun Gupta struct dpaa2_dpdmux_dev *dpdmux_dev = NULL; 471def64c2SNipun Gupta 48274fd921SRohit Raj /* Get DPDMUX dev handle from list using index */ 491def64c2SNipun Gupta TAILQ_FOREACH(dpdmux_dev, &dpdmux_dev_list, next) { 501def64c2SNipun Gupta if (dpdmux_dev->dpdmux_id == dpdmux_id) 511def64c2SNipun Gupta break; 521def64c2SNipun Gupta } 531def64c2SNipun Gupta 541def64c2SNipun Gupta return dpdmux_dev; 551def64c2SNipun Gupta } 561def64c2SNipun Gupta 57*25e5845bSJun Yang int 581def64c2SNipun Gupta rte_pmd_dpaa2_mux_flow_create(uint32_t dpdmux_id, 59*25e5845bSJun Yang struct rte_flow_item pattern[], 60*25e5845bSJun Yang struct rte_flow_action actions[]) 611def64c2SNipun Gupta { 621def64c2SNipun Gupta struct dpaa2_dpdmux_dev *dpdmux_dev; 63*25e5845bSJun Yang static struct dpkg_profile_cfg s_kg_cfg; 641def64c2SNipun Gupta struct dpkg_profile_cfg kg_cfg; 651def64c2SNipun Gupta const struct rte_flow_action_vf *vf_conf; 661def64c2SNipun Gupta struct dpdmux_cls_action dpdmux_action; 67*25e5845bSJun Yang uint8_t *key_va = NULL, *mask_va = NULL; 68*25e5845bSJun Yang void *key_cfg_va = NULL; 69*25e5845bSJun Yang uint64_t key_iova, mask_iova, key_cfg_iova; 7016035e4eSHemant Agrawal uint8_t key_size = 0; 71*25e5845bSJun Yang int ret = 0, loop = 0; 72*25e5845bSJun Yang static int s_i; 73*25e5845bSJun Yang struct dpkg_extract *extract; 74*25e5845bSJun Yang struct dpdmux_rule_cfg rule; 751def64c2SNipun Gupta 76*25e5845bSJun Yang memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg)); 774ed8a733SVanshika Shukla 781def64c2SNipun Gupta /* Find the DPDMUX from dpdmux_id in our list */ 791def64c2SNipun Gupta dpdmux_dev = get_dpdmux_from_id(dpdmux_id); 801def64c2SNipun Gupta if (!dpdmux_dev) { 811def64c2SNipun Gupta DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id); 82*25e5845bSJun Yang ret = -ENODEV; 8316035e4eSHemant Agrawal goto creation_error; 8416035e4eSHemant Agrawal } 85*25e5845bSJun Yang 86*25e5845bSJun Yang key_cfg_va = rte_zmalloc(NULL, DIST_PARAM_IOVA_SIZE, 87*25e5845bSJun Yang RTE_CACHE_LINE_SIZE); 88*25e5845bSJun Yang if (!key_cfg_va) { 89*25e5845bSJun Yang DPAA2_PMD_ERR("Unable to allocate key configure buffer"); 90*25e5845bSJun Yang ret = -ENOMEM; 91*25e5845bSJun Yang goto creation_error; 92*25e5845bSJun Yang } 93*25e5845bSJun Yang 94*25e5845bSJun Yang key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_va, 95*25e5845bSJun Yang DIST_PARAM_IOVA_SIZE); 96*25e5845bSJun Yang if (key_cfg_iova == RTE_BAD_IOVA) { 97*25e5845bSJun Yang DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)", 98*25e5845bSJun Yang __func__, key_cfg_va); 99*25e5845bSJun Yang ret = -ENOBUFS; 100*25e5845bSJun Yang goto creation_error; 101*25e5845bSJun Yang } 102*25e5845bSJun Yang 103*25e5845bSJun Yang key_va = rte_zmalloc(NULL, (2 * DIST_PARAM_IOVA_SIZE), 104*25e5845bSJun Yang RTE_CACHE_LINE_SIZE); 105*25e5845bSJun Yang if (!key_va) { 106*25e5845bSJun Yang DPAA2_PMD_ERR("Unable to allocate flow dist parameter"); 107*25e5845bSJun Yang ret = -ENOMEM; 108*25e5845bSJun Yang goto creation_error; 109*25e5845bSJun Yang } 110*25e5845bSJun Yang 111*25e5845bSJun Yang key_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_va, 112*25e5845bSJun Yang (2 * DIST_PARAM_IOVA_SIZE)); 113*25e5845bSJun Yang if (key_iova == RTE_BAD_IOVA) { 114*25e5845bSJun Yang DPAA2_PMD_ERR("%s: No IOMMU mapping for address(%p)", 115*25e5845bSJun Yang __func__, key_va); 116*25e5845bSJun Yang ret = -ENOBUFS; 117*25e5845bSJun Yang goto creation_error; 118*25e5845bSJun Yang } 119*25e5845bSJun Yang 120*25e5845bSJun Yang mask_va = key_va + DIST_PARAM_IOVA_SIZE; 121*25e5845bSJun Yang mask_iova = key_iova + DIST_PARAM_IOVA_SIZE; 1221def64c2SNipun Gupta 1231def64c2SNipun Gupta /* Currently taking only IP protocol as an extract type. 1247be78d02SJosh Soref * This can be extended to other fields using pattern->type. 1251def64c2SNipun Gupta */ 1261def64c2SNipun Gupta memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg)); 12716035e4eSHemant Agrawal 128*25e5845bSJun Yang while (pattern[loop].type != RTE_FLOW_ITEM_TYPE_END) { 129*25e5845bSJun Yang if (kg_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) { 130*25e5845bSJun Yang DPAA2_PMD_ERR("Too many extracts(%d)", 131*25e5845bSJun Yang kg_cfg.num_extracts); 132*25e5845bSJun Yang ret = -ENOTSUP; 133*25e5845bSJun Yang goto creation_error; 134*25e5845bSJun Yang } 135*25e5845bSJun Yang switch (pattern[loop].type) { 13616035e4eSHemant Agrawal case RTE_FLOW_ITEM_TYPE_IPV4: 13716035e4eSHemant Agrawal { 13816035e4eSHemant Agrawal const struct rte_flow_item_ipv4 *spec; 139*25e5845bSJun Yang const struct rte_flow_item_ipv4 *mask; 1407a582318SNipun Gupta 141*25e5845bSJun Yang extract = &kg_cfg.extracts[kg_cfg.num_extracts]; 142*25e5845bSJun Yang extract->type = DPKG_EXTRACT_FROM_HDR; 143*25e5845bSJun Yang extract->extract.from_hdr.prot = NET_PROT_IP; 144*25e5845bSJun Yang extract->extract.from_hdr.field = NH_FLD_IP_PROTO; 145*25e5845bSJun Yang extract->extract.from_hdr.type = DPKG_FULL_FIELD; 1461def64c2SNipun Gupta 147*25e5845bSJun Yang kg_cfg.num_extracts++; 148*25e5845bSJun Yang 149*25e5845bSJun Yang spec = pattern[loop].spec; 150*25e5845bSJun Yang mask = pattern[loop].mask; 151*25e5845bSJun Yang rte_memcpy(&key_va[key_size], 152*25e5845bSJun Yang &spec->hdr.next_proto_id, sizeof(uint8_t)); 153*25e5845bSJun Yang if (mask) { 154*25e5845bSJun Yang rte_memcpy(&mask_va[key_size], 155*25e5845bSJun Yang &mask->hdr.next_proto_id, 15616035e4eSHemant Agrawal sizeof(uint8_t)); 157*25e5845bSJun Yang } else { 158*25e5845bSJun Yang mask_va[key_size] = 0xff; 159*25e5845bSJun Yang } 160*25e5845bSJun Yang key_size += sizeof(uint8_t); 16116035e4eSHemant Agrawal } 16216035e4eSHemant Agrawal break; 16316035e4eSHemant Agrawal 16441603590SVanshika Shukla case RTE_FLOW_ITEM_TYPE_VLAN: 16541603590SVanshika Shukla { 16641603590SVanshika Shukla const struct rte_flow_item_vlan *spec; 167*25e5845bSJun Yang const struct rte_flow_item_vlan *mask; 16841603590SVanshika Shukla 169*25e5845bSJun Yang extract = &kg_cfg.extracts[kg_cfg.num_extracts]; 170*25e5845bSJun Yang extract->type = DPKG_EXTRACT_FROM_HDR; 171*25e5845bSJun Yang extract->extract.from_hdr.prot = NET_PROT_VLAN; 172*25e5845bSJun Yang extract->extract.from_hdr.field = NH_FLD_VLAN_TCI; 173*25e5845bSJun Yang extract->extract.from_hdr.type = DPKG_FULL_FIELD; 17441603590SVanshika Shukla 175*25e5845bSJun Yang kg_cfg.num_extracts++; 176*25e5845bSJun Yang 177*25e5845bSJun Yang spec = pattern[loop].spec; 178*25e5845bSJun Yang mask = pattern[loop].mask; 179*25e5845bSJun Yang rte_memcpy(&key_va[key_size], 180*25e5845bSJun Yang &spec->tci, sizeof(uint16_t)); 181*25e5845bSJun Yang if (mask) { 182*25e5845bSJun Yang rte_memcpy(&mask_va[key_size], 183*25e5845bSJun Yang &mask->tci, sizeof(uint16_t)); 184*25e5845bSJun Yang } else { 185*25e5845bSJun Yang memset(&mask_va[key_size], 0xff, 186*25e5845bSJun Yang sizeof(rte_be16_t)); 187*25e5845bSJun Yang } 188*25e5845bSJun Yang key_size += sizeof(uint16_t); 18941603590SVanshika Shukla } 19041603590SVanshika Shukla break; 19141603590SVanshika Shukla 1927a582318SNipun Gupta case RTE_FLOW_ITEM_TYPE_UDP: 1937a582318SNipun Gupta { 1947a582318SNipun Gupta const struct rte_flow_item_udp *spec; 195*25e5845bSJun Yang const struct rte_flow_item_udp *mask; 1967a582318SNipun Gupta 197*25e5845bSJun Yang extract = &kg_cfg.extracts[kg_cfg.num_extracts]; 198*25e5845bSJun Yang extract->type = DPKG_EXTRACT_FROM_HDR; 199*25e5845bSJun Yang extract->extract.from_hdr.prot = NET_PROT_UDP; 200*25e5845bSJun Yang extract->extract.from_hdr.type = DPKG_FULL_FIELD; 201*25e5845bSJun Yang extract->extract.from_hdr.field = NH_FLD_UDP_PORT_DST; 202*25e5845bSJun Yang kg_cfg.num_extracts++; 2037a582318SNipun Gupta 204*25e5845bSJun Yang spec = pattern[loop].spec; 205*25e5845bSJun Yang mask = pattern[loop].mask; 206*25e5845bSJun Yang rte_memcpy(&key_va[key_size], 207*25e5845bSJun Yang &spec->hdr.dst_port, sizeof(rte_be16_t)); 208*25e5845bSJun Yang if (mask) { 209*25e5845bSJun Yang rte_memcpy(&mask_va[key_size], 210*25e5845bSJun Yang &mask->hdr.dst_port, 2117a582318SNipun Gupta sizeof(rte_be16_t)); 212*25e5845bSJun Yang } else { 213*25e5845bSJun Yang memset(&mask_va[key_size], 0xff, 214*25e5845bSJun Yang sizeof(rte_be16_t)); 215*25e5845bSJun Yang } 216*25e5845bSJun Yang key_size += sizeof(rte_be16_t); 2177a582318SNipun Gupta } 2187a582318SNipun Gupta break; 2197a582318SNipun Gupta 22016035e4eSHemant Agrawal case RTE_FLOW_ITEM_TYPE_ETH: 22116035e4eSHemant Agrawal { 22216035e4eSHemant Agrawal const struct rte_flow_item_eth *spec; 223*25e5845bSJun Yang const struct rte_flow_item_eth *mask; 2247a582318SNipun Gupta 225*25e5845bSJun Yang extract = &kg_cfg.extracts[kg_cfg.num_extracts]; 226*25e5845bSJun Yang extract->type = DPKG_EXTRACT_FROM_HDR; 227*25e5845bSJun Yang extract->extract.from_hdr.prot = NET_PROT_ETH; 228*25e5845bSJun Yang extract->extract.from_hdr.type = DPKG_FULL_FIELD; 229*25e5845bSJun Yang extract->extract.from_hdr.field = NH_FLD_ETH_TYPE; 230*25e5845bSJun Yang kg_cfg.num_extracts++; 23116035e4eSHemant Agrawal 232*25e5845bSJun Yang spec = pattern[loop].spec; 233*25e5845bSJun Yang mask = pattern[loop].mask; 234*25e5845bSJun Yang rte_memcpy(&key_va[key_size], 235*25e5845bSJun Yang &spec->type, sizeof(rte_be16_t)); 236*25e5845bSJun Yang if (mask) { 237*25e5845bSJun Yang rte_memcpy(&mask_va[key_size], 238*25e5845bSJun Yang &mask->type, sizeof(rte_be16_t)); 239*25e5845bSJun Yang } else { 240*25e5845bSJun Yang memset(&mask_va[key_size], 0xff, 24116035e4eSHemant Agrawal sizeof(rte_be16_t)); 242*25e5845bSJun Yang } 243*25e5845bSJun Yang key_size += sizeof(rte_be16_t); 24416035e4eSHemant Agrawal } 24516035e4eSHemant Agrawal break; 24616035e4eSHemant Agrawal 247e5e9ef72SAkhil Goyal case RTE_FLOW_ITEM_TYPE_RAW: 248e5e9ef72SAkhil Goyal { 249e5e9ef72SAkhil Goyal const struct rte_flow_item_raw *spec; 250*25e5845bSJun Yang const struct rte_flow_item_raw *mask; 251e5e9ef72SAkhil Goyal 252*25e5845bSJun Yang spec = pattern[loop].spec; 253*25e5845bSJun Yang mask = pattern[loop].mask; 254*25e5845bSJun Yang extract = &kg_cfg.extracts[kg_cfg.num_extracts]; 255*25e5845bSJun Yang extract->type = DPKG_EXTRACT_FROM_DATA; 256*25e5845bSJun Yang extract->extract.from_data.offset = spec->offset; 257*25e5845bSJun Yang extract->extract.from_data.size = spec->length; 258*25e5845bSJun Yang kg_cfg.num_extracts++; 259e5e9ef72SAkhil Goyal 260*25e5845bSJun Yang rte_memcpy(&key_va[key_size], 261*25e5845bSJun Yang spec->pattern, spec->length); 262*25e5845bSJun Yang if (mask && mask->pattern) { 263*25e5845bSJun Yang rte_memcpy(&mask_va[key_size], 264*25e5845bSJun Yang mask->pattern, spec->length); 265*25e5845bSJun Yang } else { 266*25e5845bSJun Yang memset(&mask_va[key_size], 0xff, spec->length); 267*25e5845bSJun Yang } 268*25e5845bSJun Yang 269*25e5845bSJun Yang key_size += spec->length; 270e5e9ef72SAkhil Goyal } 271e5e9ef72SAkhil Goyal break; 272e5e9ef72SAkhil Goyal 27316035e4eSHemant Agrawal default: 274*25e5845bSJun Yang DPAA2_PMD_ERR("Not supported pattern[%d] type: %d", 275*25e5845bSJun Yang loop, pattern[loop].type); 276*25e5845bSJun Yang ret = -ENOTSUP; 27716035e4eSHemant Agrawal goto creation_error; 27816035e4eSHemant Agrawal } 279*25e5845bSJun Yang loop++; 280*25e5845bSJun Yang } 28116035e4eSHemant Agrawal 282*25e5845bSJun Yang ret = dpkg_prepare_key_cfg(&kg_cfg, key_cfg_va); 2831def64c2SNipun Gupta if (ret) { 2841def64c2SNipun Gupta DPAA2_PMD_ERR("dpkg_prepare_key_cfg failed: err(%d)", ret); 2851def64c2SNipun Gupta goto creation_error; 2861def64c2SNipun Gupta } 2871def64c2SNipun Gupta 288*25e5845bSJun Yang if (!s_i) { 289*25e5845bSJun Yang ret = dpdmux_set_custom_key(&dpdmux_dev->dpdmux, 290*25e5845bSJun Yang CMD_PRI_LOW, dpdmux_dev->token, key_cfg_iova); 2911def64c2SNipun Gupta if (ret) { 292e5e9ef72SAkhil Goyal DPAA2_PMD_ERR("dpdmux_set_custom_key failed: err(%d)", 293e5e9ef72SAkhil Goyal ret); 2941def64c2SNipun Gupta goto creation_error; 2951def64c2SNipun Gupta } 296*25e5845bSJun Yang rte_memcpy(&s_kg_cfg, &kg_cfg, sizeof(struct dpkg_profile_cfg)); 297*25e5845bSJun Yang } else { 298*25e5845bSJun Yang if (memcmp(&s_kg_cfg, &kg_cfg, 299*25e5845bSJun Yang sizeof(struct dpkg_profile_cfg))) { 300*25e5845bSJun Yang DPAA2_PMD_ERR("%s: Single flow support only.", 301*25e5845bSJun Yang __func__); 302*25e5845bSJun Yang ret = -ENOTSUP; 303*25e5845bSJun Yang goto creation_error; 304e5e9ef72SAkhil Goyal } 305*25e5845bSJun Yang } 3061def64c2SNipun Gupta 307*25e5845bSJun Yang vf_conf = actions[0].conf; 3081def64c2SNipun Gupta if (vf_conf->id == 0 || vf_conf->id > dpdmux_dev->num_ifs) { 309*25e5845bSJun Yang DPAA2_PMD_ERR("Invalid destination id(%d)", vf_conf->id); 3101def64c2SNipun Gupta goto creation_error; 3111def64c2SNipun Gupta } 3121def64c2SNipun Gupta dpdmux_action.dest_if = vf_conf->id; 3131def64c2SNipun Gupta 314*25e5845bSJun Yang rule.key_iova = key_iova; 315*25e5845bSJun Yang rule.mask_iova = mask_iova; 316*25e5845bSJun Yang rule.key_size = key_size; 317*25e5845bSJun Yang rule.entry_index = s_i; 318*25e5845bSJun Yang s_i++; 319*25e5845bSJun Yang 320*25e5845bSJun Yang /* As now our key extract parameters are set, let us configure 321*25e5845bSJun Yang * the rule. 322*25e5845bSJun Yang */ 323*25e5845bSJun Yang ret = dpdmux_add_custom_cls_entry(&dpdmux_dev->dpdmux, 324*25e5845bSJun Yang CMD_PRI_LOW, dpdmux_dev->token, 325*25e5845bSJun Yang &rule, &dpdmux_action); 3261def64c2SNipun Gupta if (ret) { 327*25e5845bSJun Yang DPAA2_PMD_ERR("Add classification entry failed:err(%d)", ret); 3281def64c2SNipun Gupta goto creation_error; 3291def64c2SNipun Gupta } 3301def64c2SNipun Gupta 3311def64c2SNipun Gupta creation_error: 332*25e5845bSJun Yang rte_free(key_cfg_va); 333*25e5845bSJun Yang rte_free(key_va); 334*25e5845bSJun Yang 335*25e5845bSJun Yang return ret; 3361def64c2SNipun Gupta } 3371def64c2SNipun Gupta 33866c64eb2SHemant Agrawal int 339cfe96771SVanshika Shukla rte_pmd_dpaa2_mux_flow_l2(uint32_t dpdmux_id, 340cfe96771SVanshika Shukla uint8_t mac_addr[6], uint16_t vlan_id, int dest_if) 341cfe96771SVanshika Shukla { 342cfe96771SVanshika Shukla struct dpaa2_dpdmux_dev *dpdmux_dev; 343cfe96771SVanshika Shukla struct dpdmux_l2_rule rule; 344cfe96771SVanshika Shukla int ret, i; 345cfe96771SVanshika Shukla 346cfe96771SVanshika Shukla /* Find the DPDMUX from dpdmux_id in our list */ 347cfe96771SVanshika Shukla dpdmux_dev = get_dpdmux_from_id(dpdmux_id); 348cfe96771SVanshika Shukla if (!dpdmux_dev) { 349cfe96771SVanshika Shukla DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id); 350cfe96771SVanshika Shukla return -ENODEV; 351cfe96771SVanshika Shukla } 352cfe96771SVanshika Shukla 353cfe96771SVanshika Shukla for (i = 0; i < 6; i++) 354cfe96771SVanshika Shukla rule.mac_addr[i] = mac_addr[i]; 355cfe96771SVanshika Shukla rule.vlan_id = vlan_id; 356cfe96771SVanshika Shukla 357cfe96771SVanshika Shukla ret = dpdmux_if_add_l2_rule(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 358cfe96771SVanshika Shukla dpdmux_dev->token, dest_if, &rule); 359cfe96771SVanshika Shukla if (ret) { 360cfe96771SVanshika Shukla DPAA2_PMD_ERR("dpdmux_if_add_l2_rule failed:err(%d)", ret); 361cfe96771SVanshika Shukla return ret; 362cfe96771SVanshika Shukla } 363cfe96771SVanshika Shukla 364cfe96771SVanshika Shukla return 0; 365cfe96771SVanshika Shukla } 366cfe96771SVanshika Shukla 367cfe96771SVanshika Shukla int 36866c64eb2SHemant Agrawal rte_pmd_dpaa2_mux_rx_frame_len(uint32_t dpdmux_id, uint16_t max_rx_frame_len) 36966c64eb2SHemant Agrawal { 37066c64eb2SHemant Agrawal struct dpaa2_dpdmux_dev *dpdmux_dev; 37166c64eb2SHemant Agrawal int ret; 37266c64eb2SHemant Agrawal 37366c64eb2SHemant Agrawal /* Find the DPDMUX from dpdmux_id in our list */ 37466c64eb2SHemant Agrawal dpdmux_dev = get_dpdmux_from_id(dpdmux_id); 37566c64eb2SHemant Agrawal if (!dpdmux_dev) { 37666c64eb2SHemant Agrawal DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id); 37766c64eb2SHemant Agrawal return -1; 37866c64eb2SHemant Agrawal } 37966c64eb2SHemant Agrawal 38066c64eb2SHemant Agrawal ret = dpdmux_set_max_frame_length(&dpdmux_dev->dpdmux, 38166c64eb2SHemant Agrawal CMD_PRI_LOW, dpdmux_dev->token, max_rx_frame_len); 38266c64eb2SHemant Agrawal if (ret) { 38366c64eb2SHemant Agrawal DPAA2_PMD_ERR("DPDMUX:Unable to set mtu. check config %d", ret); 38466c64eb2SHemant Agrawal return ret; 38566c64eb2SHemant Agrawal } 38666c64eb2SHemant Agrawal 38766c64eb2SHemant Agrawal DPAA2_PMD_INFO("dpdmux mtu set as %u", 38866c64eb2SHemant Agrawal DPAA2_MAX_RX_PKT_LEN - RTE_ETHER_CRC_LEN); 38966c64eb2SHemant Agrawal 39066c64eb2SHemant Agrawal return ret; 39166c64eb2SHemant Agrawal } 39266c64eb2SHemant Agrawal 39317eda10dSHemant Agrawal /* dump the status of the dpaa2_mux counters on the console */ 39417eda10dSHemant Agrawal void 39517eda10dSHemant Agrawal rte_pmd_dpaa2_mux_dump_counter(FILE *f, uint32_t dpdmux_id, int num_if) 39617eda10dSHemant Agrawal { 39717eda10dSHemant Agrawal struct dpaa2_dpdmux_dev *dpdmux; 39817eda10dSHemant Agrawal uint64_t counter; 39917eda10dSHemant Agrawal int ret; 40017eda10dSHemant Agrawal int if_id; 40117eda10dSHemant Agrawal 40217eda10dSHemant Agrawal /* Find the DPDMUX from dpdmux_id in our list */ 40317eda10dSHemant Agrawal dpdmux = get_dpdmux_from_id(dpdmux_id); 40417eda10dSHemant Agrawal if (!dpdmux) { 40517eda10dSHemant Agrawal DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id); 40617eda10dSHemant Agrawal return; 40717eda10dSHemant Agrawal } 40817eda10dSHemant Agrawal 40917eda10dSHemant Agrawal for (if_id = 0; if_id < num_if; if_id++) { 41017eda10dSHemant Agrawal fprintf(f, "dpdmux.%d\n", if_id); 41117eda10dSHemant Agrawal 41217eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 41317eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME, &counter); 41417eda10dSHemant Agrawal if (!ret) 41517eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_FRAME %" PRIu64 "\n", 41617eda10dSHemant Agrawal counter); 41717eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 41817eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_BYTE, &counter); 41917eda10dSHemant Agrawal if (!ret) 42017eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_BYTE %" PRIu64 "\n", 42117eda10dSHemant Agrawal counter); 42217eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 42317eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_FLTR_FRAME, 42417eda10dSHemant Agrawal &counter); 42517eda10dSHemant Agrawal if (!ret) 42617eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_FLTR_FRAME %" PRIu64 "\n", 42717eda10dSHemant Agrawal counter); 42817eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 42917eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME_DISCARD, 43017eda10dSHemant Agrawal &counter); 43117eda10dSHemant Agrawal if (!ret) 43217eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_FRAME_DISCARD %" PRIu64 "\n", 43317eda10dSHemant Agrawal counter); 43417eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 43517eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_FRAME, 43617eda10dSHemant Agrawal &counter); 43717eda10dSHemant Agrawal if (!ret) 43817eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_MCAST_FRAME %" PRIu64 "\n", 43917eda10dSHemant Agrawal counter); 44017eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 44117eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_BYTE, 44217eda10dSHemant Agrawal &counter); 44317eda10dSHemant Agrawal if (!ret) 44417eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_MCAST_BYTE %" PRIu64 "\n", 44517eda10dSHemant Agrawal counter); 44617eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 44717eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_FRAME, 44817eda10dSHemant Agrawal &counter); 44917eda10dSHemant Agrawal if (!ret) 45017eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_BCAST_FRAME %" PRIu64 "\n", 45117eda10dSHemant Agrawal counter); 45217eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 45317eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_BYTES, 45417eda10dSHemant Agrawal &counter); 45517eda10dSHemant Agrawal if (!ret) 45617eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_ING_BCAST_BYTES %" PRIu64 "\n", 45717eda10dSHemant Agrawal counter); 45817eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 45917eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME, &counter); 46017eda10dSHemant Agrawal if (!ret) 46117eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_EGR_FRAME %" PRIu64 "\n", 46217eda10dSHemant Agrawal counter); 46317eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 46417eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_EGR_BYTE, &counter); 46517eda10dSHemant Agrawal if (!ret) 46617eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_EGR_BYTE %" PRIu64 "\n", 46717eda10dSHemant Agrawal counter); 46817eda10dSHemant Agrawal ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW, 46917eda10dSHemant Agrawal dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME_DISCARD, 47017eda10dSHemant Agrawal &counter); 47117eda10dSHemant Agrawal if (!ret) 47217eda10dSHemant Agrawal fprintf(f, "DPDMUX_CNT_EGR_FRAME_DISCARD %" PRIu64 "\n", 47317eda10dSHemant Agrawal counter); 47417eda10dSHemant Agrawal } 47517eda10dSHemant Agrawal } 47617eda10dSHemant Agrawal 4771def64c2SNipun Gupta static int 4781def64c2SNipun Gupta dpaa2_create_dpdmux_device(int vdev_fd __rte_unused, 4791def64c2SNipun Gupta struct vfio_device_info *obj_info __rte_unused, 4804d4399aeSJun Yang struct rte_dpaa2_device *obj) 4811def64c2SNipun Gupta { 4821def64c2SNipun Gupta struct dpaa2_dpdmux_dev *dpdmux_dev; 4831def64c2SNipun Gupta struct dpdmux_attr attr; 4844d4399aeSJun Yang int ret, dpdmux_id = obj->object_id; 485914450baSApeksha Gupta uint16_t maj_ver; 486914450baSApeksha Gupta uint16_t min_ver; 487cfe96771SVanshika Shukla uint8_t skip_reset_flags; 4881def64c2SNipun Gupta 4891def64c2SNipun Gupta PMD_INIT_FUNC_TRACE(); 4901def64c2SNipun Gupta 4911def64c2SNipun Gupta /* Allocate DPAA2 dpdmux handle */ 492*25e5845bSJun Yang dpdmux_dev = rte_zmalloc(NULL, 493*25e5845bSJun Yang sizeof(struct dpaa2_dpdmux_dev), RTE_CACHE_LINE_SIZE); 4941def64c2SNipun Gupta if (!dpdmux_dev) { 4951def64c2SNipun Gupta DPAA2_PMD_ERR("Memory allocation failed for DPDMUX Device"); 496*25e5845bSJun Yang return -ENOMEM; 4971def64c2SNipun Gupta } 4981def64c2SNipun Gupta 4991def64c2SNipun Gupta /* Open the dpdmux object */ 500a6a5f4b4SHemant Agrawal dpdmux_dev->dpdmux.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX); 5011def64c2SNipun Gupta ret = dpdmux_open(&dpdmux_dev->dpdmux, CMD_PRI_LOW, dpdmux_id, 5021def64c2SNipun Gupta &dpdmux_dev->token); 5031def64c2SNipun Gupta if (ret) { 5041def64c2SNipun Gupta DPAA2_PMD_ERR("Unable to open dpdmux object: err(%d)", ret); 5051def64c2SNipun Gupta goto init_err; 5061def64c2SNipun Gupta } 5071def64c2SNipun Gupta 5081def64c2SNipun Gupta ret = dpdmux_get_attributes(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 5091def64c2SNipun Gupta dpdmux_dev->token, &attr); 5101def64c2SNipun Gupta if (ret) { 5111def64c2SNipun Gupta DPAA2_PMD_ERR("Unable to get dpdmux attr: err(%d)", ret); 5121def64c2SNipun Gupta goto init_err; 5131def64c2SNipun Gupta } 5141def64c2SNipun Gupta 515cfe96771SVanshika Shukla if (attr.method != DPDMUX_METHOD_C_VLAN_MAC) { 5161def64c2SNipun Gupta ret = dpdmux_if_set_default(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 5170b5da8ccSTianli Lai dpdmux_dev->token, attr.default_if); 5181def64c2SNipun Gupta if (ret) { 5191def64c2SNipun Gupta DPAA2_PMD_ERR("setting default interface failed in %s", 5201def64c2SNipun Gupta __func__); 5211def64c2SNipun Gupta goto init_err; 5221def64c2SNipun Gupta } 523cfe96771SVanshika Shukla skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE 524cfe96771SVanshika Shukla | DPDMUX_SKIP_UNICAST_RULES | DPDMUX_SKIP_MULTICAST_RULES; 525cfe96771SVanshika Shukla } else { 526cfe96771SVanshika Shukla skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE; 527cfe96771SVanshika Shukla } 5281def64c2SNipun Gupta 529914450baSApeksha Gupta ret = dpdmux_get_api_version(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 530914450baSApeksha Gupta &maj_ver, &min_ver); 531914450baSApeksha Gupta if (ret) { 532914450baSApeksha Gupta DPAA2_PMD_ERR("setting version failed in %s", 533914450baSApeksha Gupta __func__); 534914450baSApeksha Gupta goto init_err; 535914450baSApeksha Gupta } 536914450baSApeksha Gupta 537914450baSApeksha Gupta /* The new dpdmux_set/get_resetable() API are available starting with 538914450baSApeksha Gupta * DPDMUX_VER_MAJOR==6 and DPDMUX_VER_MINOR==6 539914450baSApeksha Gupta */ 540914450baSApeksha Gupta if (maj_ver >= 6 && min_ver >= 6) { 541914450baSApeksha Gupta ret = dpdmux_set_resetable(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 542cfe96771SVanshika Shukla dpdmux_dev->token, skip_reset_flags); 543914450baSApeksha Gupta if (ret) { 544914450baSApeksha Gupta DPAA2_PMD_ERR("setting default interface failed in %s", 545914450baSApeksha Gupta __func__); 546914450baSApeksha Gupta goto init_err; 547914450baSApeksha Gupta } 548914450baSApeksha Gupta } 549914450baSApeksha Gupta 5503d43972bSHemant Agrawal if (maj_ver >= 6 && min_ver >= 9) { 5513d43972bSHemant Agrawal struct dpdmux_error_cfg mux_err_cfg; 5523d43972bSHemant Agrawal 5533d43972bSHemant Agrawal memset(&mux_err_cfg, 0, sizeof(mux_err_cfg)); 55400e928e9SSachin Saxena /* Note: Discarded flag(DPDMUX_ERROR_DISC) has effect only when 55500e928e9SSachin Saxena * ERROR_ACTION is set to DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE. 55600e928e9SSachin Saxena */ 557cfe96771SVanshika Shukla mux_err_cfg.errors = DPDMUX_ALL_ERRORS; 55800e928e9SSachin Saxena mux_err_cfg.error_action = DPDMUX_ERROR_ACTION_CONTINUE; 5593d43972bSHemant Agrawal 5603d43972bSHemant Agrawal ret = dpdmux_if_set_errors_behavior(&dpdmux_dev->dpdmux, 5613d43972bSHemant Agrawal CMD_PRI_LOW, 562e45956ceSVanshika Shukla dpdmux_dev->token, DPAA2_DPDMUX_DPMAC_IDX, 5633d43972bSHemant Agrawal &mux_err_cfg); 5643d43972bSHemant Agrawal if (ret) { 5653d43972bSHemant Agrawal DPAA2_PMD_ERR("dpdmux_if_set_errors_behavior %s err %d", 5663d43972bSHemant Agrawal __func__, ret); 5673d43972bSHemant Agrawal goto init_err; 5683d43972bSHemant Agrawal } 5693d43972bSHemant Agrawal } 5703d43972bSHemant Agrawal 5711def64c2SNipun Gupta dpdmux_dev->dpdmux_id = dpdmux_id; 5721def64c2SNipun Gupta dpdmux_dev->num_ifs = attr.num_ifs; 5731def64c2SNipun Gupta 5741def64c2SNipun Gupta TAILQ_INSERT_TAIL(&dpdmux_dev_list, dpdmux_dev, next); 5751def64c2SNipun Gupta 5761def64c2SNipun Gupta return 0; 5771def64c2SNipun Gupta 5781def64c2SNipun Gupta init_err: 5791def64c2SNipun Gupta rte_free(dpdmux_dev); 5801def64c2SNipun Gupta 5811def64c2SNipun Gupta return -1; 5821def64c2SNipun Gupta } 5831def64c2SNipun Gupta 584274fd921SRohit Raj static void 585274fd921SRohit Raj dpaa2_close_dpdmux_device(int object_id) 586274fd921SRohit Raj { 587274fd921SRohit Raj struct dpaa2_dpdmux_dev *dpdmux_dev; 588274fd921SRohit Raj 589274fd921SRohit Raj dpdmux_dev = get_dpdmux_from_id((uint32_t)object_id); 590274fd921SRohit Raj 591274fd921SRohit Raj if (dpdmux_dev) { 592274fd921SRohit Raj dpdmux_close(&dpdmux_dev->dpdmux, CMD_PRI_LOW, 593274fd921SRohit Raj dpdmux_dev->token); 594274fd921SRohit Raj TAILQ_REMOVE(&dpdmux_dev_list, dpdmux_dev, next); 595274fd921SRohit Raj rte_free(dpdmux_dev); 596274fd921SRohit Raj } 597274fd921SRohit Raj } 598274fd921SRohit Raj 5991def64c2SNipun Gupta static struct rte_dpaa2_object rte_dpaa2_dpdmux_obj = { 6001def64c2SNipun Gupta .dev_type = DPAA2_MUX, 6011def64c2SNipun Gupta .create = dpaa2_create_dpdmux_device, 602274fd921SRohit Raj .close = dpaa2_close_dpdmux_device, 6031def64c2SNipun Gupta }; 6041def64c2SNipun Gupta 6051def64c2SNipun Gupta RTE_PMD_REGISTER_DPAA2_OBJECT(dpdmux, rte_dpaa2_dpdmux_obj); 606