1a07f7cedSKiran Kumar K /* SPDX-License-Identifier: BSD-3-Clause 2a07f7cedSKiran Kumar K * Copyright(C) 2021 Marvell. 3a07f7cedSKiran Kumar K */ 4a07f7cedSKiran Kumar K 5a07f7cedSKiran Kumar K #include "roc_api.h" 6a07f7cedSKiran Kumar K #include "roc_priv.h" 7a07f7cedSKiran Kumar K 8a07f7cedSKiran Kumar K int 98a44b2a5SHanumanth Pothula roc_npc_mark_actions_get(struct roc_npc *roc_npc) 108a44b2a5SHanumanth Pothula { 118a44b2a5SHanumanth Pothula struct npc *npc = roc_npc_to_npc_priv(roc_npc); 128a44b2a5SHanumanth Pothula 138a44b2a5SHanumanth Pothula return npc->mark_actions; 148a44b2a5SHanumanth Pothula } 158a44b2a5SHanumanth Pothula 168a44b2a5SHanumanth Pothula int 178a44b2a5SHanumanth Pothula roc_npc_mark_actions_sub_return(struct roc_npc *roc_npc, uint32_t count) 188a44b2a5SHanumanth Pothula { 198a44b2a5SHanumanth Pothula struct npc *npc = roc_npc_to_npc_priv(roc_npc); 208a44b2a5SHanumanth Pothula 218a44b2a5SHanumanth Pothula npc->mark_actions -= count; 228a44b2a5SHanumanth Pothula return npc->mark_actions; 238a44b2a5SHanumanth Pothula } 248a44b2a5SHanumanth Pothula 258a44b2a5SHanumanth Pothula int 2619f3cc23SSatheesh Paul roc_npc_vtag_actions_get(struct roc_npc *roc_npc) 2719f3cc23SSatheesh Paul { 2819f3cc23SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 2919f3cc23SSatheesh Paul 308ca851cdSSatheesh Paul return npc->vtag_strip_actions; 3119f3cc23SSatheesh Paul } 3219f3cc23SSatheesh Paul 3319f3cc23SSatheesh Paul int 3419f3cc23SSatheesh Paul roc_npc_vtag_actions_sub_return(struct roc_npc *roc_npc, uint32_t count) 3519f3cc23SSatheesh Paul { 3619f3cc23SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 3719f3cc23SSatheesh Paul 388ca851cdSSatheesh Paul npc->vtag_strip_actions -= count; 398ca851cdSSatheesh Paul return npc->vtag_strip_actions; 4019f3cc23SSatheesh Paul } 4119f3cc23SSatheesh Paul 4219f3cc23SSatheesh Paul int 43a07f7cedSKiran Kumar K roc_npc_mcam_free_counter(struct roc_npc *roc_npc, uint16_t ctr_id) 44a07f7cedSKiran Kumar K { 45a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 46a07f7cedSKiran Kumar K 47df5cf15fSKiran Kumar K return npc_mcam_free_counter(npc->mbox, ctr_id); 48df5cf15fSKiran Kumar K } 49df5cf15fSKiran Kumar K 50df5cf15fSKiran Kumar K int 51df5cf15fSKiran Kumar K roc_npc_inl_mcam_read_counter(uint32_t ctr_id, uint64_t *count) 52df5cf15fSKiran Kumar K { 53df5cf15fSKiran Kumar K struct nix_inl_dev *inl_dev = NULL; 54df5cf15fSKiran Kumar K struct idev_cfg *idev; 55df5cf15fSKiran Kumar K 56df5cf15fSKiran Kumar K idev = idev_get_cfg(); 57df5cf15fSKiran Kumar K if (idev) 58df5cf15fSKiran Kumar K inl_dev = idev->nix_inl_dev; 59df5cf15fSKiran Kumar K if (!inl_dev) 60df5cf15fSKiran Kumar K return 0; 61df5cf15fSKiran Kumar K return npc_mcam_read_counter(inl_dev->dev.mbox, ctr_id, count); 62df5cf15fSKiran Kumar K } 63df5cf15fSKiran Kumar K 64df5cf15fSKiran Kumar K int 65df5cf15fSKiran Kumar K roc_npc_inl_mcam_clear_counter(uint32_t ctr_id) 66df5cf15fSKiran Kumar K { 67df5cf15fSKiran Kumar K struct nix_inl_dev *inl_dev = NULL; 68df5cf15fSKiran Kumar K struct idev_cfg *idev; 69df5cf15fSKiran Kumar K 70df5cf15fSKiran Kumar K idev = idev_get_cfg(); 71df5cf15fSKiran Kumar K if (idev) 72df5cf15fSKiran Kumar K inl_dev = idev->nix_inl_dev; 73df5cf15fSKiran Kumar K if (!inl_dev) 74df5cf15fSKiran Kumar K return 0; 75df5cf15fSKiran Kumar K 76df5cf15fSKiran Kumar K return npc_mcam_clear_counter(inl_dev->dev.mbox, ctr_id); 77a07f7cedSKiran Kumar K } 78a07f7cedSKiran Kumar K 79a07f7cedSKiran Kumar K int 80df29c91cSHarman Kalra roc_npc_mcam_alloc_counter(struct roc_npc *roc_npc, uint16_t *ctr_id) 81df29c91cSHarman Kalra { 82df29c91cSHarman Kalra struct npc *npc = roc_npc_to_npc_priv(roc_npc); 83df29c91cSHarman Kalra 84df29c91cSHarman Kalra return npc_mcam_alloc_counter(npc->mbox, ctr_id); 85df29c91cSHarman Kalra } 86df29c91cSHarman Kalra 87df29c91cSHarman Kalra int 88df29c91cSHarman Kalra roc_npc_get_free_mcam_entry(struct roc_npc *roc_npc, struct roc_npc_flow *flow) 89df29c91cSHarman Kalra { 90df29c91cSHarman Kalra struct npc *npc = roc_npc_to_npc_priv(roc_npc); 91df29c91cSHarman Kalra 92df29c91cSHarman Kalra return npc_get_free_mcam_entry(npc->mbox, flow, npc); 93df29c91cSHarman Kalra } 94df29c91cSHarman Kalra 95df29c91cSHarman Kalra int 96df29c91cSHarman Kalra roc_npc_mcam_read_counter(struct roc_npc *roc_npc, uint32_t ctr_id, uint64_t *count) 97a07f7cedSKiran Kumar K { 98a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 99a07f7cedSKiran Kumar K 100df5cf15fSKiran Kumar K return npc_mcam_read_counter(npc->mbox, ctr_id, count); 101a07f7cedSKiran Kumar K } 102a07f7cedSKiran Kumar K 103a07f7cedSKiran Kumar K int 104a07f7cedSKiran Kumar K roc_npc_mcam_clear_counter(struct roc_npc *roc_npc, uint32_t ctr_id) 105a07f7cedSKiran Kumar K { 106a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 107a07f7cedSKiran Kumar K 108df5cf15fSKiran Kumar K return npc_mcam_clear_counter(npc->mbox, ctr_id); 109a07f7cedSKiran Kumar K } 110a07f7cedSKiran Kumar K 111a07f7cedSKiran Kumar K int 112a07f7cedSKiran Kumar K roc_npc_mcam_free_entry(struct roc_npc *roc_npc, uint32_t entry) 113a07f7cedSKiran Kumar K { 114a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 115a07f7cedSKiran Kumar K 116df5cf15fSKiran Kumar K return npc_mcam_free_entry(npc->mbox, entry); 117a07f7cedSKiran Kumar K } 118a07f7cedSKiran Kumar K 119a07f7cedSKiran Kumar K int 12022d9d348SSatheesh Paul roc_npc_mcam_free(struct roc_npc *roc_npc, struct roc_npc_flow *mcam) 12122d9d348SSatheesh Paul { 12222d9d348SSatheesh Paul int rc = 0; 12322d9d348SSatheesh Paul 12422d9d348SSatheesh Paul if (mcam->use_ctr) { 12522d9d348SSatheesh Paul rc = roc_npc_mcam_clear_counter(roc_npc, mcam->ctr_id); 12622d9d348SSatheesh Paul if (rc) 12722d9d348SSatheesh Paul return rc; 12822d9d348SSatheesh Paul 12922d9d348SSatheesh Paul rc = roc_npc_mcam_free_counter(roc_npc, mcam->ctr_id); 13022d9d348SSatheesh Paul if (rc) 13122d9d348SSatheesh Paul return rc; 13222d9d348SSatheesh Paul } 13322d9d348SSatheesh Paul 13422d9d348SSatheesh Paul return roc_npc_mcam_free_entry(roc_npc, mcam->mcam_id); 13522d9d348SSatheesh Paul } 13622d9d348SSatheesh Paul 13722d9d348SSatheesh Paul int 13822d9d348SSatheesh Paul roc_npc_mcam_init(struct roc_npc *roc_npc, struct roc_npc_flow *flow, 13922d9d348SSatheesh Paul int mcam_id) 14022d9d348SSatheesh Paul { 14122d9d348SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 14222d9d348SSatheesh Paul int rc; 14322d9d348SSatheesh Paul 14422d9d348SSatheesh Paul rc = npc_mcam_init(npc, flow, mcam_id); 14522d9d348SSatheesh Paul if (rc != 0) { 14622d9d348SSatheesh Paul plt_err("npc: mcam initialisation write failed"); 14722d9d348SSatheesh Paul return rc; 14822d9d348SSatheesh Paul } 14922d9d348SSatheesh Paul return 0; 15022d9d348SSatheesh Paul } 15122d9d348SSatheesh Paul 15222d9d348SSatheesh Paul int 15322d9d348SSatheesh Paul roc_npc_mcam_move(struct roc_npc *roc_npc, uint16_t old_ent, uint16_t new_ent) 15422d9d348SSatheesh Paul { 15522d9d348SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 15622d9d348SSatheesh Paul struct mbox *mbox = npc->mbox; 15722d9d348SSatheesh Paul int rc; 15822d9d348SSatheesh Paul 15922d9d348SSatheesh Paul rc = npc_mcam_move(mbox, old_ent, new_ent); 16022d9d348SSatheesh Paul if (rc) 16122d9d348SSatheesh Paul return rc; 16222d9d348SSatheesh Paul 16322d9d348SSatheesh Paul return 0; 16422d9d348SSatheesh Paul } 16522d9d348SSatheesh Paul 16622d9d348SSatheesh Paul int 167a07f7cedSKiran Kumar K roc_npc_mcam_free_all_resources(struct roc_npc *roc_npc) 168a07f7cedSKiran Kumar K { 169a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 170a07f7cedSKiran Kumar K 171a07f7cedSKiran Kumar K return npc_flow_free_all_resources(npc); 172a07f7cedSKiran Kumar K } 173a07f7cedSKiran Kumar K 174a07f7cedSKiran Kumar K int 175df29c91cSHarman Kalra roc_npc_mcam_alloc_entries(struct roc_npc *roc_npc, int ref_entry, int *alloc_entry, int req_count, 176df29c91cSHarman Kalra int priority, int *resp_count, bool is_conti) 177a07f7cedSKiran Kumar K { 178a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 179a07f7cedSKiran Kumar K 180df5cf15fSKiran Kumar K return npc_mcam_alloc_entries(npc->mbox, ref_entry, alloc_entry, req_count, priority, 181df29c91cSHarman Kalra resp_count, is_conti); 182a07f7cedSKiran Kumar K } 183a07f7cedSKiran Kumar K 184a07f7cedSKiran Kumar K int 185fbc0fa74SKiran Kumar K roc_npc_mcam_enable_all_entries(struct roc_npc *roc_npc, bool enable) 186fbc0fa74SKiran Kumar K { 187fbc0fa74SKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 188fbc0fa74SKiran Kumar K 189fbc0fa74SKiran Kumar K return npc_flow_enable_all_entries(npc, enable); 190fbc0fa74SKiran Kumar K } 191fbc0fa74SKiran Kumar K 192fbc0fa74SKiran Kumar K int 193a07f7cedSKiran Kumar K roc_npc_mcam_alloc_entry(struct roc_npc *roc_npc, struct roc_npc_flow *mcam, 194a07f7cedSKiran Kumar K struct roc_npc_flow *ref_mcam, int prio, 195a07f7cedSKiran Kumar K int *resp_count) 196a07f7cedSKiran Kumar K { 197a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 198a07f7cedSKiran Kumar K 199a07f7cedSKiran Kumar K return npc_mcam_alloc_entry(npc, mcam, ref_mcam, prio, resp_count); 200a07f7cedSKiran Kumar K } 201a07f7cedSKiran Kumar K 202a07f7cedSKiran Kumar K int 203a07f7cedSKiran Kumar K roc_npc_mcam_ena_dis_entry(struct roc_npc *roc_npc, struct roc_npc_flow *mcam, 204a07f7cedSKiran Kumar K bool enable) 205a07f7cedSKiran Kumar K { 206a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 207a07f7cedSKiran Kumar K 208a07f7cedSKiran Kumar K return npc_mcam_ena_dis_entry(npc, mcam, enable); 209a07f7cedSKiran Kumar K } 210a07f7cedSKiran Kumar K 211a07f7cedSKiran Kumar K int 212a07f7cedSKiran Kumar K roc_npc_mcam_write_entry(struct roc_npc *roc_npc, struct roc_npc_flow *mcam) 213a07f7cedSKiran Kumar K { 214a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 215a07f7cedSKiran Kumar K 216df5cf15fSKiran Kumar K return npc_mcam_write_entry(npc->mbox, mcam); 217a07f7cedSKiran Kumar K } 218a07f7cedSKiran Kumar K 219a07f7cedSKiran Kumar K int 220a07f7cedSKiran Kumar K roc_npc_get_low_priority_mcam(struct roc_npc *roc_npc) 221a07f7cedSKiran Kumar K { 222a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 223a07f7cedSKiran Kumar K 224a07f7cedSKiran Kumar K if (roc_model_is_cn10k()) 225a07f7cedSKiran Kumar K return (npc->mcam_entries - NPC_MCAME_RESVD_10XX - 1); 2268b9f07b8SHarman Kalra else if (roc_model_is_cn98xx()) 2278b9f07b8SHarman Kalra return (npc->mcam_entries - NPC_MCAME_RESVD_98XX - 1); 228a07f7cedSKiran Kumar K else 229a07f7cedSKiran Kumar K return (npc->mcam_entries - NPC_MCAME_RESVD_9XXX - 1); 230a07f7cedSKiran Kumar K } 231a07f7cedSKiran Kumar K 232a07f7cedSKiran Kumar K static int 233a07f7cedSKiran Kumar K npc_mcam_tot_entries(void) 234a07f7cedSKiran Kumar K { 235a07f7cedSKiran Kumar K /* FIXME: change to reading in AF from NPC_AF_CONST1/2 236a07f7cedSKiran Kumar K * MCAM_BANK_DEPTH(_EXT) * MCAM_BANKS 237a07f7cedSKiran Kumar K */ 23819f3cc23SSatheesh Paul if (roc_model_is_cn10k() || roc_model_is_cn98xx()) 239a07f7cedSKiran Kumar K return 16 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 4096 */ 240a07f7cedSKiran Kumar K else 241a07f7cedSKiran Kumar K return 4 * 1024; /* MCAM_BANKS = 4, BANK_DEPTH_EXT = 1024 */ 242a07f7cedSKiran Kumar K } 243a07f7cedSKiran Kumar K 244a07f7cedSKiran Kumar K const char * 245a07f7cedSKiran Kumar K roc_npc_profile_name_get(struct roc_npc *roc_npc) 246a07f7cedSKiran Kumar K { 247a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 248a07f7cedSKiran Kumar K 249a07f7cedSKiran Kumar K return (char *)npc->profile_name; 250a07f7cedSKiran Kumar K } 251a07f7cedSKiran Kumar K 252a07f7cedSKiran Kumar K int 2533c3accd0SSatheesh Paul roc_npc_kex_capa_get(struct roc_nix *roc_nix, uint64_t *kex_capability) 2543c3accd0SSatheesh Paul { 2553c3accd0SSatheesh Paul struct nix *nix = roc_nix_to_nix_priv(roc_nix); 2563c3accd0SSatheesh Paul struct npc npc; 2573c3accd0SSatheesh Paul int rc = 0; 2583c3accd0SSatheesh Paul 2593c3accd0SSatheesh Paul memset(&npc, 0, sizeof(npc)); 2603c3accd0SSatheesh Paul 2613c3accd0SSatheesh Paul npc.mbox = (&nix->dev)->mbox; 2623c3accd0SSatheesh Paul 2633c3accd0SSatheesh Paul rc = npc_mcam_fetch_kex_cfg(&npc); 2643c3accd0SSatheesh Paul if (rc) 2653c3accd0SSatheesh Paul return rc; 2663c3accd0SSatheesh Paul 2673c3accd0SSatheesh Paul rc = npc_mcam_fetch_hw_cap(&npc, &npc.hash_extract_cap); 2683c3accd0SSatheesh Paul if (rc) 2693c3accd0SSatheesh Paul return rc; 2703c3accd0SSatheesh Paul 2713c3accd0SSatheesh Paul *kex_capability = npc_get_kex_capability(&npc); 2723c3accd0SSatheesh Paul 2733c3accd0SSatheesh Paul return 0; 2743c3accd0SSatheesh Paul } 2753c3accd0SSatheesh Paul 2763c3accd0SSatheesh Paul int 277a07f7cedSKiran Kumar K roc_npc_init(struct roc_npc *roc_npc) 278a07f7cedSKiran Kumar K { 279a07f7cedSKiran Kumar K uint8_t *mem = NULL, *nix_mem = NULL, *npc_mem = NULL; 280a07f7cedSKiran Kumar K struct nix *nix = roc_nix_to_nix_priv(roc_npc->roc_nix); 281a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 282a07f7cedSKiran Kumar K uint32_t bmap_sz; 283a07f7cedSKiran Kumar K int rc = 0, idx; 284a07f7cedSKiran Kumar K size_t sz; 285a07f7cedSKiran Kumar K 286a07f7cedSKiran Kumar K PLT_STATIC_ASSERT(sizeof(struct npc) <= ROC_NPC_MEM_SZ); 287a07f7cedSKiran Kumar K 288a07f7cedSKiran Kumar K memset(npc, 0, sizeof(*npc)); 289a07f7cedSKiran Kumar K npc->mbox = (&nix->dev)->mbox; 290a07f7cedSKiran Kumar K roc_npc->channel = nix->rx_chan_base; 291a07f7cedSKiran Kumar K roc_npc->pf_func = (&nix->dev)->pf_func; 292a07f7cedSKiran Kumar K npc->channel = roc_npc->channel; 293a07f7cedSKiran Kumar K npc->pf_func = roc_npc->pf_func; 294a07f7cedSKiran Kumar K npc->flow_max_priority = roc_npc->flow_max_priority; 295a07f7cedSKiran Kumar K npc->switch_header_type = roc_npc->switch_header_type; 296a07f7cedSKiran Kumar K npc->flow_prealloc_size = roc_npc->flow_prealloc_size; 297a07f7cedSKiran Kumar K 298a07f7cedSKiran Kumar K if (npc->mbox == NULL) 299a07f7cedSKiran Kumar K return NPC_ERR_PARAM; 300a07f7cedSKiran Kumar K 301a07f7cedSKiran Kumar K rc = npc_mcam_fetch_kex_cfg(npc); 302a07f7cedSKiran Kumar K if (rc) 303a07f7cedSKiran Kumar K goto done; 304a07f7cedSKiran Kumar K 305e3315630SSatheesh Paul rc = npc_mcam_fetch_hw_cap(npc, &npc->hash_extract_cap); 306e3315630SSatheesh Paul if (rc) 307e3315630SSatheesh Paul goto done; 308e3315630SSatheesh Paul 309a07f7cedSKiran Kumar K roc_npc->kex_capability = npc_get_kex_capability(npc); 310a07f7cedSKiran Kumar K roc_npc->rx_parse_nibble = npc->keyx_supp_nmask[NPC_MCAM_RX]; 311a07f7cedSKiran Kumar K 312a07f7cedSKiran Kumar K npc->mcam_entries = npc_mcam_tot_entries() >> npc->keyw[NPC_MCAM_RX]; 313a9064972SNithin Dabilpuram nix->exact_match_ena = npc->exact_match_ena; 314a07f7cedSKiran Kumar K 315a07f7cedSKiran Kumar K /* Free, free_rev, live and live_rev entries */ 316a07f7cedSKiran Kumar K bmap_sz = plt_bitmap_get_memory_footprint(npc->mcam_entries); 317a07f7cedSKiran Kumar K mem = plt_zmalloc(4 * bmap_sz * npc->flow_max_priority, 0); 318a07f7cedSKiran Kumar K if (mem == NULL) { 319a07f7cedSKiran Kumar K plt_err("Bmap alloc failed"); 320a07f7cedSKiran Kumar K rc = NPC_ERR_NO_MEM; 321a07f7cedSKiran Kumar K return rc; 322a07f7cedSKiran Kumar K } 323a07f7cedSKiran Kumar K 324a07f7cedSKiran Kumar K sz = npc->flow_max_priority * sizeof(struct npc_flow_list); 325a07f7cedSKiran Kumar K npc->flow_list = plt_zmalloc(sz, 0); 326a07f7cedSKiran Kumar K if (npc->flow_list == NULL) { 327a07f7cedSKiran Kumar K plt_err("flow_list alloc failed"); 328a07f7cedSKiran Kumar K rc = NPC_ERR_NO_MEM; 329a07f7cedSKiran Kumar K goto done; 330a07f7cedSKiran Kumar K } 331a07f7cedSKiran Kumar K 3321f669198SSatheesh Paul sz = npc->flow_max_priority * sizeof(struct npc_prio_flow_list_head); 3331f669198SSatheesh Paul npc->prio_flow_list = plt_zmalloc(sz, 0); 3341f669198SSatheesh Paul if (npc->prio_flow_list == NULL) { 3351f669198SSatheesh Paul plt_err("prio_flow_list alloc failed"); 3361f669198SSatheesh Paul rc = NPC_ERR_NO_MEM; 3371f669198SSatheesh Paul goto done; 3381f669198SSatheesh Paul } 3391f669198SSatheesh Paul 340a07f7cedSKiran Kumar K npc_mem = mem; 341df5cf15fSKiran Kumar K 342df5cf15fSKiran Kumar K TAILQ_INIT(&npc->ipsec_list); 343357f5ebcSAnkur Dwivedi TAILQ_INIT(&npc->age_flow_list); 344a07f7cedSKiran Kumar K for (idx = 0; idx < npc->flow_max_priority; idx++) { 345a07f7cedSKiran Kumar K TAILQ_INIT(&npc->flow_list[idx]); 3461f669198SSatheesh Paul TAILQ_INIT(&npc->prio_flow_list[idx]); 347a07f7cedSKiran Kumar K } 348a07f7cedSKiran Kumar K 349a07f7cedSKiran Kumar K npc->rss_grps = NPC_RSS_GRPS; 350a07f7cedSKiran Kumar K 351a07f7cedSKiran Kumar K bmap_sz = plt_bitmap_get_memory_footprint(npc->rss_grps); 352a07f7cedSKiran Kumar K nix_mem = plt_zmalloc(bmap_sz, 0); 353a07f7cedSKiran Kumar K if (nix_mem == NULL) { 354a07f7cedSKiran Kumar K plt_err("Bmap alloc failed"); 355a07f7cedSKiran Kumar K rc = NPC_ERR_NO_MEM; 356a07f7cedSKiran Kumar K goto done; 357a07f7cedSKiran Kumar K } 358a07f7cedSKiran Kumar K 359a07f7cedSKiran Kumar K npc->rss_grp_entries = plt_bitmap_init(npc->rss_grps, nix_mem, bmap_sz); 360a07f7cedSKiran Kumar K 361a07f7cedSKiran Kumar K if (!npc->rss_grp_entries) { 362a07f7cedSKiran Kumar K plt_err("bitmap init failed"); 363a07f7cedSKiran Kumar K rc = NPC_ERR_NO_MEM; 364a07f7cedSKiran Kumar K goto done; 365a07f7cedSKiran Kumar K } 366a07f7cedSKiran Kumar K 367a07f7cedSKiran Kumar K /* Group 0 will be used for RSS, 368a07f7cedSKiran Kumar K * 1 -7 will be used for npc_flow RSS action 369a07f7cedSKiran Kumar K */ 370a07f7cedSKiran Kumar K plt_bitmap_set(npc->rss_grp_entries, 0); 371a07f7cedSKiran Kumar K 3723ddc923bSAnkur Dwivedi roc_npc->flow_age.age_flow_refcnt = 0; 3733ddc923bSAnkur Dwivedi 374a07f7cedSKiran Kumar K return rc; 375a07f7cedSKiran Kumar K 376a07f7cedSKiran Kumar K done: 377a07f7cedSKiran Kumar K if (npc->flow_list) 378a07f7cedSKiran Kumar K plt_free(npc->flow_list); 3791f669198SSatheesh Paul if (npc->prio_flow_list) 3801f669198SSatheesh Paul plt_free(npc->prio_flow_list); 381a07f7cedSKiran Kumar K if (npc_mem) 382a07f7cedSKiran Kumar K plt_free(npc_mem); 383a07f7cedSKiran Kumar K return rc; 384a07f7cedSKiran Kumar K } 385a07f7cedSKiran Kumar K 386a07f7cedSKiran Kumar K int 387a07f7cedSKiran Kumar K roc_npc_fini(struct roc_npc *roc_npc) 388a07f7cedSKiran Kumar K { 389a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 390a07f7cedSKiran Kumar K int rc; 391a07f7cedSKiran Kumar K 392d1066ea6SHarman Kalra if (!roc_npc->flow_age.aged_flows_get_thread_exit) 39385e9542dSSatheesh Paul npc_aging_ctrl_thread_destroy(roc_npc); 39485e9542dSSatheesh Paul 395a07f7cedSKiran Kumar K rc = npc_flow_free_all_resources(npc); 396a07f7cedSKiran Kumar K if (rc) { 397a07f7cedSKiran Kumar K plt_err("Error when deleting NPC MCAM entries, counters"); 398a07f7cedSKiran Kumar K return rc; 399a07f7cedSKiran Kumar K } 400a07f7cedSKiran Kumar K 401a07f7cedSKiran Kumar K if (npc->flow_list) { 402a07f7cedSKiran Kumar K plt_free(npc->flow_list); 403a07f7cedSKiran Kumar K npc->flow_list = NULL; 404a07f7cedSKiran Kumar K } 405a07f7cedSKiran Kumar K 4061f669198SSatheesh Paul if (npc->prio_flow_list) { 4071f669198SSatheesh Paul plt_free(npc->prio_flow_list); 4081f669198SSatheesh Paul npc->prio_flow_list = NULL; 409a07f7cedSKiran Kumar K } 410a07f7cedSKiran Kumar K 411a07f7cedSKiran Kumar K return 0; 412a07f7cedSKiran Kumar K } 413a07f7cedSKiran Kumar K 41415f0b8a5SSatheesh Paul int 41515f0b8a5SSatheesh Paul roc_npc_validate_portid_action(struct roc_npc *roc_npc_src, 41615f0b8a5SSatheesh Paul struct roc_npc *roc_npc_dst) 41715f0b8a5SSatheesh Paul { 41815f0b8a5SSatheesh Paul struct roc_nix *roc_nix_src = roc_npc_src->roc_nix; 41915f0b8a5SSatheesh Paul struct nix *nix_src = roc_nix_to_nix_priv(roc_nix_src); 42015f0b8a5SSatheesh Paul struct roc_nix *roc_nix_dst = roc_npc_dst->roc_nix; 42115f0b8a5SSatheesh Paul struct nix *nix_dst = roc_nix_to_nix_priv(roc_nix_dst); 42215f0b8a5SSatheesh Paul 42315f0b8a5SSatheesh Paul if (roc_nix_is_pf(roc_npc_dst->roc_nix)) { 42415f0b8a5SSatheesh Paul plt_err("Output port should be VF"); 42515f0b8a5SSatheesh Paul return -EINVAL; 42615f0b8a5SSatheesh Paul } 42715f0b8a5SSatheesh Paul 42815f0b8a5SSatheesh Paul if (nix_dst->dev.vf >= nix_src->dev.maxvf) { 42915f0b8a5SSatheesh Paul plt_err("Invalid VF for output port"); 43015f0b8a5SSatheesh Paul return -EINVAL; 43115f0b8a5SSatheesh Paul } 43215f0b8a5SSatheesh Paul 43315f0b8a5SSatheesh Paul if (nix_src->dev.pf != nix_dst->dev.pf) { 43415f0b8a5SSatheesh Paul plt_err("Output port should be VF of ingress PF"); 43515f0b8a5SSatheesh Paul return -EINVAL; 43615f0b8a5SSatheesh Paul } 43715f0b8a5SSatheesh Paul return 0; 43815f0b8a5SSatheesh Paul } 43915f0b8a5SSatheesh Paul 440a07f7cedSKiran Kumar K static int 44104087b78SSatheesh Paul npc_parse_spi_to_sa_action(struct roc_npc *roc_npc, const struct roc_npc_action *act, 44204087b78SSatheesh Paul struct roc_npc_flow *flow, uint8_t *has_spi_to_sa_action) 443bbe8d1f1SKiran Kumar K { 444bbe8d1f1SKiran Kumar K const struct roc_npc_sec_action *sec_action; 44504087b78SSatheesh Paul struct nix_spi_to_sa_add_req *req; 44604087b78SSatheesh Paul struct nix_spi_to_sa_add_rsp *rsp; 44704087b78SSatheesh Paul struct nix_inl_dev *inl_dev; 44804087b78SSatheesh Paul struct idev_cfg *idev; 449bbe8d1f1SKiran Kumar K union { 450bbe8d1f1SKiran Kumar K uint64_t reg; 451bbe8d1f1SKiran Kumar K union nix_rx_vtag_action_u act; 452bbe8d1f1SKiran Kumar K } vtag_act; 45304087b78SSatheesh Paul struct mbox *mbox; 45404087b78SSatheesh Paul int rc; 455bbe8d1f1SKiran Kumar K 45604087b78SSatheesh Paul if (roc_npc->roc_nix->custom_sa_action == 0 || roc_model_is_cn9k() == 1 || 45704087b78SSatheesh Paul act->conf == NULL || flow->is_validate) 458bbe8d1f1SKiran Kumar K return 0; 459bbe8d1f1SKiran Kumar K 46004087b78SSatheesh Paul *has_spi_to_sa_action = true; 461bbe8d1f1SKiran Kumar K sec_action = act->conf; 462bbe8d1f1SKiran Kumar K 463bbe8d1f1SKiran Kumar K vtag_act.reg = 0; 464bbe8d1f1SKiran Kumar K vtag_act.act.sa_xor = sec_action->sa_xor; 465bbe8d1f1SKiran Kumar K vtag_act.act.sa_hi = sec_action->sa_hi; 466bbe8d1f1SKiran Kumar K vtag_act.act.sa_lo = sec_action->sa_lo; 467bbe8d1f1SKiran Kumar K 46804087b78SSatheesh Paul idev = idev_get_cfg(); 46904087b78SSatheesh Paul if (!idev) 47004087b78SSatheesh Paul return -1; 47104087b78SSatheesh Paul 47204087b78SSatheesh Paul inl_dev = idev->nix_inl_dev; 47304087b78SSatheesh Paul 474bbe8d1f1SKiran Kumar K switch (sec_action->alg) { 475bbe8d1f1SKiran Kumar K case ROC_NPC_SEC_ACTION_ALG0: 476bbe8d1f1SKiran Kumar K break; 477bbe8d1f1SKiran Kumar K case ROC_NPC_SEC_ACTION_ALG1: 478bbe8d1f1SKiran Kumar K vtag_act.act.vtag1_valid = false; 479bbe8d1f1SKiran Kumar K vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG1; 480bbe8d1f1SKiran Kumar K break; 481bbe8d1f1SKiran Kumar K case ROC_NPC_SEC_ACTION_ALG2: 482bbe8d1f1SKiran Kumar K vtag_act.act.vtag1_valid = false; 483bbe8d1f1SKiran Kumar K vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG2; 484bbe8d1f1SKiran Kumar K break; 48504087b78SSatheesh Paul case ROC_NPC_SEC_ACTION_ALG3: 48604087b78SSatheesh Paul vtag_act.act.vtag1_valid = false; 487bfc1fcceSKiran Kumar K vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG3; 488bfc1fcceSKiran Kumar K break; 489bfc1fcceSKiran Kumar K case ROC_NPC_SEC_ACTION_ALG4: 490bfc1fcceSKiran Kumar K vtag_act.act.vtag1_valid = false; 49104087b78SSatheesh Paul vtag_act.act.vtag1_lid = 0; 49204087b78SSatheesh Paul mbox = inl_dev->dev.mbox; 49304087b78SSatheesh Paul req = mbox_alloc_msg_nix_spi_to_sa_add(mbox); 49404087b78SSatheesh Paul if (req == NULL) 49504087b78SSatheesh Paul return -ENOSPC; 49604087b78SSatheesh Paul req->sa_index = sec_action->sa_index; 49704087b78SSatheesh Paul req->spi_index = plt_be_to_cpu_32(flow->spi_to_sa_info.spi); 49804087b78SSatheesh Paul req->match_id = flow->match_id; 49904087b78SSatheesh Paul req->valid = true; 50004087b78SSatheesh Paul rc = mbox_process_msg(mbox, (void *)&rsp); 50104087b78SSatheesh Paul if (rc) 50204087b78SSatheesh Paul return rc; 50304087b78SSatheesh Paul flow->spi_to_sa_info.hash_index = rsp->hash_index; 50404087b78SSatheesh Paul flow->spi_to_sa_info.way = rsp->way; 50504087b78SSatheesh Paul flow->spi_to_sa_info.duplicate = rsp->is_duplicate; 50604087b78SSatheesh Paul flow->spi_to_sa_info.has_action = true; 50704087b78SSatheesh Paul break; 508bbe8d1f1SKiran Kumar K default: 509bbe8d1f1SKiran Kumar K return -1; 510bbe8d1f1SKiran Kumar K } 511bbe8d1f1SKiran Kumar K 512bbe8d1f1SKiran Kumar K flow->vtag_action = vtag_act.reg; 513bbe8d1f1SKiran Kumar K 514bbe8d1f1SKiran Kumar K return 0; 515bbe8d1f1SKiran Kumar K } 516bbe8d1f1SKiran Kumar K 517bbe8d1f1SKiran Kumar K static int 518209188d1SSatheesh Paul roc_npc_process_sample_action(struct roc_npc *roc_npc, 519209188d1SSatheesh Paul const struct roc_npc_action_sample *sample_action, 520209188d1SSatheesh Paul struct roc_npc_flow *flow) 521209188d1SSatheesh Paul { 522209188d1SSatheesh Paul struct nix *nix = roc_nix_to_nix_priv(roc_npc->roc_nix); 523209188d1SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 524209188d1SSatheesh Paul 525209188d1SSatheesh Paul flow->is_sampling_rule = true; 526209188d1SSatheesh Paul 527209188d1SSatheesh Paul switch (sample_action->action_type) { 528209188d1SSatheesh Paul case ROC_NPC_ACTION_TYPE_PORT_ID: 529209188d1SSatheesh Paul flow->mcast_pf_funcs[0] = sample_action->pf_func; 530209188d1SSatheesh Paul flow->mcast_channels[0] = sample_action->channel; 531209188d1SSatheesh Paul break; 532209188d1SSatheesh Paul case ROC_NPC_ACTION_TYPE_PF: 533209188d1SSatheesh Paul flow->mcast_pf_funcs[0] = roc_npc->pf_func; 534209188d1SSatheesh Paul flow->mcast_channels[0] = npc->channel; 535209188d1SSatheesh Paul break; 536209188d1SSatheesh Paul case ROC_NPC_ACTION_TYPE_VF: 537209188d1SSatheesh Paul if (sample_action->pf_func >= nix->dev.maxvf) 538209188d1SSatheesh Paul return -EINVAL; 539209188d1SSatheesh Paul flow->mcast_pf_funcs[0] = 540209188d1SSatheesh Paul ((roc_npc->pf_func & 0xfc00) | (sample_action->pf_func + 1)); 541209188d1SSatheesh Paul flow->mcast_channels[0] = npc->channel; 542209188d1SSatheesh Paul break; 543209188d1SSatheesh Paul default: 544209188d1SSatheesh Paul return -EINVAL; 545209188d1SSatheesh Paul } 546209188d1SSatheesh Paul 547209188d1SSatheesh Paul return 0; 548209188d1SSatheesh Paul } 549209188d1SSatheesh Paul 550209188d1SSatheesh Paul static int 551ee48f711SNithin Dabilpuram npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, 552b7eb0e0cSSatheesh Paul const struct roc_npc_action actions[], struct roc_npc_flow *flow, 553b7eb0e0cSSatheesh Paul uint16_t dst_pf_func) 554a07f7cedSKiran Kumar K { 555ee48f711SNithin Dabilpuram struct npc *npc = roc_npc_to_npc_priv(roc_npc); 55604087b78SSatheesh Paul const struct roc_npc_action *sec_action = NULL; 557209188d1SSatheesh Paul const struct roc_npc_action_sample *act_sample; 558a07f7cedSKiran Kumar K const struct roc_npc_action_mark *act_mark; 5590ca63f1bSSunil Kumar Kori const struct roc_npc_action_meter *act_mtr; 560a07f7cedSKiran Kumar K const struct roc_npc_action_queue *act_q; 561a07f7cedSKiran Kumar K const struct roc_npc_action_vf *vf_act; 56219f3cc23SSatheesh Paul bool vlan_insert_action = false; 56304087b78SSatheesh Paul uint8_t has_spi_to_sa_act = 0; 564a07f7cedSKiran Kumar K int sel_act, req_act = 0; 565a07f7cedSKiran Kumar K uint16_t pf_func, vf_id; 5663c100e0eSNithin Dabilpuram struct roc_nix *roc_nix; 567a07f7cedSKiran Kumar K int errcode = 0; 568a07f7cedSKiran Kumar K int mark = 0; 569a07f7cedSKiran Kumar K int rq = 0; 570bbe8d1f1SKiran Kumar K int rc = 0; 571a07f7cedSKiran Kumar K 572a07f7cedSKiran Kumar K /* Initialize actions */ 573a07f7cedSKiran Kumar K flow->ctr_id = NPC_COUNTER_NONE; 57467e1cbf3SRakesh Kudurumalla flow->mtr_id = ROC_NIX_MTR_ID_INVALID; 575a07f7cedSKiran Kumar K pf_func = npc->pf_func; 576296e9040SKiran Kumar K if (flow->has_rep) 577296e9040SKiran Kumar K pf_func = flow->rep_pf_func; 578a07f7cedSKiran Kumar K 579a07f7cedSKiran Kumar K for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) { 580a07f7cedSKiran Kumar K switch (actions->type) { 581a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_VOID: 582a07f7cedSKiran Kumar K break; 583a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_MARK: 584a07f7cedSKiran Kumar K act_mark = (const struct roc_npc_action_mark *) 585a07f7cedSKiran Kumar K actions->conf; 586a07f7cedSKiran Kumar K if (act_mark->id > (NPC_FLOW_FLAG_VAL - 2)) { 587a07f7cedSKiran Kumar K plt_err("mark value must be < 0xfffe"); 588a07f7cedSKiran Kumar K goto err_exit; 589a07f7cedSKiran Kumar K } 590a07f7cedSKiran Kumar K mark = act_mark->id + 1; 591a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_MARK; 5928a44b2a5SHanumanth Pothula npc->mark_actions += 1; 59304087b78SSatheesh Paul flow->match_id = mark; 594a07f7cedSKiran Kumar K break; 595a07f7cedSKiran Kumar K 596a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_FLAG: 597a07f7cedSKiran Kumar K mark = NPC_FLOW_FLAG_VAL; 598a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_FLAG; 5998a44b2a5SHanumanth Pothula npc->mark_actions += 1; 600a07f7cedSKiran Kumar K break; 601a07f7cedSKiran Kumar K 602a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_COUNT: 603a07f7cedSKiran Kumar K /* Indicates, need a counter */ 60422d9d348SSatheesh Paul flow->use_ctr = 1; 605a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_COUNT; 606a07f7cedSKiran Kumar K break; 607a07f7cedSKiran Kumar K 608a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_DROP: 609a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_DROP; 610a07f7cedSKiran Kumar K break; 611a07f7cedSKiran Kumar K 612a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_PF: 613a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_PF; 614a07f7cedSKiran Kumar K pf_func &= (0xfc00); 615a07f7cedSKiran Kumar K break; 616a07f7cedSKiran Kumar K 617a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_VF: 618209188d1SSatheesh Paul vf_act = (const struct roc_npc_action_vf *)actions->conf; 619a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_VF; 6207816df79SHarman Kalra if (roc_model_is_cn20k()) 6217816df79SHarman Kalra vf_id = vf_act->id & RVU_PFVF_FUNC_MASK_CN20K; 6227816df79SHarman Kalra else 623a07f7cedSKiran Kumar K vf_id = vf_act->id & RVU_PFVF_FUNC_MASK; 624a07f7cedSKiran Kumar K pf_func &= (0xfc00); 625a07f7cedSKiran Kumar K pf_func = (pf_func | (vf_id + 1)); 626a07f7cedSKiran Kumar K break; 627a07f7cedSKiran Kumar K 62815f0b8a5SSatheesh Paul case ROC_NPC_ACTION_TYPE_PORT_ID: 629b7eb0e0cSSatheesh Paul pf_func = dst_pf_func; 63015f0b8a5SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_VF; 63115f0b8a5SSatheesh Paul break; 63215f0b8a5SSatheesh Paul 633a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_QUEUE: 634209188d1SSatheesh Paul act_q = (const struct roc_npc_action_queue *)actions->conf; 635209188d1SSatheesh Paul rq = act_q->index & 0xFFFFF; 636a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_QUEUE; 637a07f7cedSKiran Kumar K break; 638a07f7cedSKiran Kumar K 639a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_RSS: 640a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_RSS; 641a07f7cedSKiran Kumar K break; 642a07f7cedSKiran Kumar K 643a07f7cedSKiran Kumar K case ROC_NPC_ACTION_TYPE_SEC: 644a07f7cedSKiran Kumar K /* Assumes user has already configured security 645a07f7cedSKiran Kumar K * session for this flow. Associated conf is 646a07f7cedSKiran Kumar K * opaque. When security is implemented, 647a07f7cedSKiran Kumar K * we need to verify that for specified security 648a07f7cedSKiran Kumar K * session: 649a07f7cedSKiran Kumar K * action_type == 650a07f7cedSKiran Kumar K * NPC_SECURITY_ACTION_TYPE_INLINE_PROTOCOL && 651a07f7cedSKiran Kumar K * session_protocol == 652a07f7cedSKiran Kumar K * NPC_SECURITY_PROTOCOL_IPSEC 653a07f7cedSKiran Kumar K */ 654a07f7cedSKiran Kumar K req_act |= ROC_NPC_ACTION_TYPE_SEC; 655a07f7cedSKiran Kumar K rq = 0; 6563c100e0eSNithin Dabilpuram roc_nix = roc_npc->roc_nix; 657ee48f711SNithin Dabilpuram 658ee48f711SNithin Dabilpuram /* Special processing when with inline device */ 6593c100e0eSNithin Dabilpuram if (roc_nix_inb_is_with_inl_dev(roc_nix) && 660ee48f711SNithin Dabilpuram roc_nix_inl_dev_is_probed()) { 6613c100e0eSNithin Dabilpuram struct roc_nix_rq *inl_rq; 6623c100e0eSNithin Dabilpuram 6633c100e0eSNithin Dabilpuram inl_rq = roc_nix_inl_dev_rq(roc_nix); 6643c100e0eSNithin Dabilpuram if (!inl_rq) { 6653c100e0eSNithin Dabilpuram errcode = NPC_ERR_INTERNAL; 6663c100e0eSNithin Dabilpuram goto err_exit; 6673c100e0eSNithin Dabilpuram } 6683c100e0eSNithin Dabilpuram rq = inl_rq->qid; 669ee48f711SNithin Dabilpuram pf_func = nix_inl_dev_pffunc_get(); 670ee48f711SNithin Dabilpuram } 6712c7ea812SSatheesh Paul 6722c7ea812SSatheesh Paul if (roc_nix_inl_dev_is_probed()) 6732c7ea812SSatheesh Paul flow->is_inline_dev = 1; 67404087b78SSatheesh Paul sec_action = actions; 675a07f7cedSKiran Kumar K break; 67619f3cc23SSatheesh Paul case ROC_NPC_ACTION_TYPE_VLAN_STRIP: 67719f3cc23SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_VLAN_STRIP; 67819f3cc23SSatheesh Paul break; 67919f3cc23SSatheesh Paul case ROC_NPC_ACTION_TYPE_VLAN_INSERT: 68019f3cc23SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_VLAN_INSERT; 68119f3cc23SSatheesh Paul break; 68219f3cc23SSatheesh Paul case ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT: 68319f3cc23SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT; 68419f3cc23SSatheesh Paul break; 68519f3cc23SSatheesh Paul case ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT: 68619f3cc23SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT; 68719f3cc23SSatheesh Paul break; 6880ca63f1bSSunil Kumar Kori case ROC_NPC_ACTION_TYPE_METER: 6890ca63f1bSSunil Kumar Kori act_mtr = (const struct roc_npc_action_meter *) 6900ca63f1bSSunil Kumar Kori actions->conf; 6910ca63f1bSSunil Kumar Kori flow->mtr_id = act_mtr->mtr_id; 6920ca63f1bSSunil Kumar Kori req_act |= ROC_NPC_ACTION_TYPE_METER; 6930ca63f1bSSunil Kumar Kori break; 694357f5ebcSAnkur Dwivedi case ROC_NPC_ACTION_TYPE_AGE: 695357f5ebcSAnkur Dwivedi if (flow->is_validate == true) 696357f5ebcSAnkur Dwivedi break; 697357f5ebcSAnkur Dwivedi plt_seqcount_init(&roc_npc->flow_age.seq_cnt); 698357f5ebcSAnkur Dwivedi errcode = npc_aging_ctrl_thread_create(roc_npc, 699357f5ebcSAnkur Dwivedi actions->conf, 700357f5ebcSAnkur Dwivedi flow); 701357f5ebcSAnkur Dwivedi if (errcode != 0) 702357f5ebcSAnkur Dwivedi goto err_exit; 703357f5ebcSAnkur Dwivedi req_act |= ROC_NPC_ACTION_TYPE_AGE; 704357f5ebcSAnkur Dwivedi break; 705209188d1SSatheesh Paul case ROC_NPC_ACTION_TYPE_SAMPLE: 706209188d1SSatheesh Paul req_act |= ROC_NPC_ACTION_TYPE_SAMPLE; 707209188d1SSatheesh Paul act_sample = actions->conf; 708209188d1SSatheesh Paul errcode = roc_npc_process_sample_action(roc_npc, act_sample, flow); 709209188d1SSatheesh Paul if (errcode) 710209188d1SSatheesh Paul goto err_exit; 711209188d1SSatheesh Paul break; 712a07f7cedSKiran Kumar K default: 713a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 714a07f7cedSKiran Kumar K goto err_exit; 715a07f7cedSKiran Kumar K } 716a07f7cedSKiran Kumar K } 717a07f7cedSKiran Kumar K 71804087b78SSatheesh Paul if (sec_action) { 71904087b78SSatheesh Paul rc = npc_parse_spi_to_sa_action(roc_npc, sec_action, flow, &has_spi_to_sa_act); 72004087b78SSatheesh Paul if (rc) { 72104087b78SSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 72204087b78SSatheesh Paul goto err_exit; 72304087b78SSatheesh Paul } 72404087b78SSatheesh Paul } 72504087b78SSatheesh Paul 72604087b78SSatheesh Paul if (req_act & (ROC_NPC_ACTION_TYPE_VLAN_INSERT | ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | 72719f3cc23SSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT)) 72819f3cc23SSatheesh Paul vlan_insert_action = true; 72919f3cc23SSatheesh Paul 73004087b78SSatheesh Paul if ((req_act & (ROC_NPC_ACTION_TYPE_VLAN_INSERT | ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | 73119f3cc23SSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT)) == 73219f3cc23SSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT) { 73319f3cc23SSatheesh Paul plt_err("PCP insert action can't be supported alone"); 734a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 735a07f7cedSKiran Kumar K goto err_exit; 736a07f7cedSKiran Kumar K } 73719f3cc23SSatheesh Paul 73804087b78SSatheesh Paul if (has_spi_to_sa_act && (vlan_insert_action || 739bbe8d1f1SKiran Kumar K (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP))) { 740bbe8d1f1SKiran Kumar K plt_err("Both MSNS and VLAN insert/strip action can't be supported" 741bbe8d1f1SKiran Kumar K " together"); 742bbe8d1f1SKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 743bbe8d1f1SKiran Kumar K goto err_exit; 744bbe8d1f1SKiran Kumar K } 745bbe8d1f1SKiran Kumar K 74619f3cc23SSatheesh Paul /* Both STRIP and INSERT actions are not supported */ 74719f3cc23SSatheesh Paul if (vlan_insert_action && (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP)) { 74819f3cc23SSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 74919f3cc23SSatheesh Paul goto err_exit; 75019f3cc23SSatheesh Paul } 75119f3cc23SSatheesh Paul 752209188d1SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) { 753209188d1SSatheesh Paul /* One entry for the mce list PF and channel comes from the sample subaction. 754209188d1SSatheesh Paul * Another one is the action target of the flow rule getting created. 755209188d1SSatheesh Paul */ 756209188d1SSatheesh Paul flow->mcast_pf_funcs[1] = pf_func; 757209188d1SSatheesh Paul flow->mcast_channels[1] = npc->channel; 758209188d1SSatheesh Paul if (req_act & (ROC_NPC_ACTION_TYPE_DROP | ROC_NPC_ACTION_TYPE_SEC | 759209188d1SSatheesh Paul ROC_NPC_ACTION_TYPE_RSS)) { 760209188d1SSatheesh Paul plt_err("Drop/RSS/SEC not supported with action type sample"); 761209188d1SSatheesh Paul return -EINVAL; 762209188d1SSatheesh Paul } 763209188d1SSatheesh Paul if (flow->mcast_pf_funcs[0] == flow->mcast_pf_funcs[1]) { 764209188d1SSatheesh Paul plt_err("Sample destination and target cannot be same"); 765209188d1SSatheesh Paul return -EINVAL; 766209188d1SSatheesh Paul } 767209188d1SSatheesh Paul if ((attr->egress) && (flow->mcast_channels[0] == flow->mcast_channels[1])) { 768209188d1SSatheesh Paul plt_err("Mirroring within PF and VF not allowed"); 769209188d1SSatheesh Paul return -EINVAL; 770209188d1SSatheesh Paul } 771209188d1SSatheesh Paul } 772209188d1SSatheesh Paul 77319f3cc23SSatheesh Paul /* Check if actions specified are compatible */ 77419f3cc23SSatheesh Paul if (attr->egress) { 77519f3cc23SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP) { 77619f3cc23SSatheesh Paul plt_err("VLAN pop action is not supported on Egress"); 77719f3cc23SSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 77819f3cc23SSatheesh Paul goto err_exit; 77919f3cc23SSatheesh Paul } 78019f3cc23SSatheesh Paul 7818ca851cdSSatheesh Paul if (req_act & 782209188d1SSatheesh Paul ~(ROC_NPC_ACTION_TYPE_VLAN_INSERT | ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | 783209188d1SSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT | ROC_NPC_ACTION_TYPE_DROP | 784209188d1SSatheesh Paul ROC_NPC_ACTION_TYPE_COUNT | ROC_NPC_ACTION_TYPE_SAMPLE)) { 785209188d1SSatheesh Paul plt_err("Only VLAN insert, drop, count, sample supported on Egress"); 7868ca851cdSSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 7878ca851cdSSatheesh Paul goto err_exit; 7888ca851cdSSatheesh Paul } 7898ca851cdSSatheesh Paul 7908ca851cdSSatheesh Paul if (vlan_insert_action && 7918ca851cdSSatheesh Paul (req_act & ROC_NPC_ACTION_TYPE_DROP)) { 7928ca851cdSSatheesh Paul plt_err("Both VLAN insert and drop actions cannot be supported"); 7938ca851cdSSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 7948ca851cdSSatheesh Paul goto err_exit; 7958ca851cdSSatheesh Paul } 7968ca851cdSSatheesh Paul 79719f3cc23SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_DROP) { 798a07f7cedSKiran Kumar K flow->npc_action = NIX_TX_ACTIONOP_DROP; 799296e9040SKiran Kumar K } else if ((req_act & ROC_NPC_ACTION_TYPE_COUNT) || vlan_insert_action) { 80019f3cc23SSatheesh Paul flow->npc_action = NIX_TX_ACTIONOP_UCAST_DEFAULT; 801296e9040SKiran Kumar K if (flow->rep_act_rep) { 802296e9040SKiran Kumar K flow->npc_action = NIX_TX_ACTIONOP_UCAST_CHAN; 803296e9040SKiran Kumar K flow->npc_action |= (uint64_t)0x3f << 12; 804296e9040SKiran Kumar K } 80519f3cc23SSatheesh Paul } else { 80619f3cc23SSatheesh Paul plt_err("Unsupported action for egress"); 80719f3cc23SSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 80819f3cc23SSatheesh Paul goto err_exit; 80919f3cc23SSatheesh Paul } 81019f3cc23SSatheesh Paul 811209188d1SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) { 812209188d1SSatheesh Paul flow->mcast_pf_funcs[1] = pf_func; 813209188d1SSatheesh Paul flow->mcast_channels[1] = npc->channel; 814209188d1SSatheesh Paul } 815209188d1SSatheesh Paul 816296e9040SKiran Kumar K /* PF func who is sending the packet */ 817296e9040SKiran Kumar K flow->tx_pf_func = pf_func; 818296e9040SKiran Kumar K goto done; 81919f3cc23SSatheesh Paul } else { 82019f3cc23SSatheesh Paul if (vlan_insert_action) { 82119f3cc23SSatheesh Paul errcode = NPC_ERR_ACTION_NOTSUP; 82219f3cc23SSatheesh Paul goto err_exit; 82319f3cc23SSatheesh Paul } 824a07f7cedSKiran Kumar K } 825a07f7cedSKiran Kumar K 826a07f7cedSKiran Kumar K /* We have already verified the attr, this is ingress. 827a07f7cedSKiran Kumar K * - Exactly one terminating action is supported 828a07f7cedSKiran Kumar K * - Exactly one of MARK or FLAG is supported 829a07f7cedSKiran Kumar K * - If terminating action is DROP, only count is valid. 830a07f7cedSKiran Kumar K */ 831a07f7cedSKiran Kumar K sel_act = req_act & NPC_ACTION_TERM; 832a07f7cedSKiran Kumar K if ((sel_act & (sel_act - 1)) != 0) { 833a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 834a07f7cedSKiran Kumar K goto err_exit; 835a07f7cedSKiran Kumar K } 836a07f7cedSKiran Kumar K 837a07f7cedSKiran Kumar K if (req_act & ROC_NPC_ACTION_TYPE_DROP) { 838a07f7cedSKiran Kumar K sel_act = req_act & ~ROC_NPC_ACTION_TYPE_COUNT; 839a07f7cedSKiran Kumar K if ((sel_act & (sel_act - 1)) != 0) { 840a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 841a07f7cedSKiran Kumar K goto err_exit; 842a07f7cedSKiran Kumar K } 843a07f7cedSKiran Kumar K } 844a07f7cedSKiran Kumar K 845a07f7cedSKiran Kumar K if ((req_act & (ROC_NPC_ACTION_TYPE_FLAG | ROC_NPC_ACTION_TYPE_MARK)) == 846a07f7cedSKiran Kumar K (ROC_NPC_ACTION_TYPE_FLAG | ROC_NPC_ACTION_TYPE_MARK)) { 847a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 848a07f7cedSKiran Kumar K goto err_exit; 849a07f7cedSKiran Kumar K } 850a07f7cedSKiran Kumar K 85119f3cc23SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP) 8528ca851cdSSatheesh Paul npc->vtag_strip_actions++; 85319f3cc23SSatheesh Paul 854a07f7cedSKiran Kumar K /* Set NIX_RX_ACTIONOP */ 8558ca851cdSSatheesh Paul if (req_act == ROC_NPC_ACTION_TYPE_VLAN_STRIP) { 8568ca851cdSSatheesh Paul /* Only VLAN action is provided */ 8578ca851cdSSatheesh Paul flow->npc_action = NIX_RX_ACTIONOP_UCAST; 858b1f677d4SSatheesh Paul } else if (req_act & (ROC_NPC_ACTION_TYPE_PF | ROC_NPC_ACTION_TYPE_VF)) { 859b1f677d4SSatheesh Paul /* Check if any other action is set */ 860b1f677d4SSatheesh Paul if ((req_act == ROC_NPC_ACTION_TYPE_PF) || (req_act == ROC_NPC_ACTION_TYPE_VF)) { 861b1f677d4SSatheesh Paul flow->npc_action = NIX_RX_ACTIONOP_DEFAULT; 862b1f677d4SSatheesh Paul } else { 863a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST; 864a07f7cedSKiran Kumar K if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) 865209188d1SSatheesh Paul flow->recv_queue = rq; 866b1f677d4SSatheesh Paul } 867a07f7cedSKiran Kumar K } else if (req_act & ROC_NPC_ACTION_TYPE_DROP) { 868a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_DROP; 869a07f7cedSKiran Kumar K } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) { 870a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST; 871209188d1SSatheesh Paul flow->recv_queue = rq; 872a07f7cedSKiran Kumar K } else if (req_act & ROC_NPC_ACTION_TYPE_RSS) { 873a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST; 874a07f7cedSKiran Kumar K } else if (req_act & ROC_NPC_ACTION_TYPE_SEC) { 875a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST_IPSEC; 876a07f7cedSKiran Kumar K flow->npc_action |= (uint64_t)rq << 20; 877b1f677d4SSatheesh Paul } else if (req_act & (ROC_NPC_ACTION_TYPE_FLAG | ROC_NPC_ACTION_TYPE_MARK)) { 878a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST; 879a07f7cedSKiran Kumar K } else if (req_act & ROC_NPC_ACTION_TYPE_COUNT) { 880a07f7cedSKiran Kumar K /* Keep ROC_NPC_ACTION_TYPE_COUNT_ACT always at the end 881a07f7cedSKiran Kumar K * This is default action, when user specify only 882a07f7cedSKiran Kumar K * COUNT ACTION 883a07f7cedSKiran Kumar K */ 884a07f7cedSKiran Kumar K flow->npc_action = NIX_RX_ACTIONOP_UCAST; 885a07f7cedSKiran Kumar K } else { 886a07f7cedSKiran Kumar K /* Should never reach here */ 887a07f7cedSKiran Kumar K errcode = NPC_ERR_ACTION_NOTSUP; 888a07f7cedSKiran Kumar K goto err_exit; 889a07f7cedSKiran Kumar K } 890a07f7cedSKiran Kumar K 891209188d1SSatheesh Paul if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) 892209188d1SSatheesh Paul flow->npc_action = NIX_RX_ACTIONOP_MCAST; 893209188d1SSatheesh Paul 894a07f7cedSKiran Kumar K if (mark) 895a07f7cedSKiran Kumar K flow->npc_action |= (uint64_t)mark << 40; 896a07f7cedSKiran Kumar K 897a07f7cedSKiran Kumar K /* Ideally AF must ensure that correct pf_func is set */ 898a07f7cedSKiran Kumar K flow->npc_action |= (uint64_t)pf_func << 4; 899a07f7cedSKiran Kumar K 900296e9040SKiran Kumar K done: 901a07f7cedSKiran Kumar K return 0; 902a07f7cedSKiran Kumar K 903a07f7cedSKiran Kumar K err_exit: 904a07f7cedSKiran Kumar K return errcode; 905a07f7cedSKiran Kumar K } 906a07f7cedSKiran Kumar K 907a07f7cedSKiran Kumar K typedef int (*npc_parse_stage_func_t)(struct npc_parse_state *pst); 908a07f7cedSKiran Kumar K 909a07f7cedSKiran Kumar K static int 910a07f7cedSKiran Kumar K npc_parse_pattern(struct npc *npc, const struct roc_npc_item_info pattern[], 911a07f7cedSKiran Kumar K struct roc_npc_flow *flow, struct npc_parse_state *pst) 912a07f7cedSKiran Kumar K { 913a07f7cedSKiran Kumar K npc_parse_stage_func_t parse_stage_funcs[] = { 914296e9040SKiran Kumar K npc_parse_meta_items, npc_parse_port_representor_id, 915296e9040SKiran Kumar K npc_parse_mark_item, npc_parse_pre_l2, 916296e9040SKiran Kumar K npc_parse_cpt_hdr, npc_parse_higig2_hdr, 917296e9040SKiran Kumar K npc_parse_tx_queue, npc_parse_la, 918296e9040SKiran Kumar K npc_parse_lb, npc_parse_lc, 919296e9040SKiran Kumar K npc_parse_ld, npc_parse_le, 920296e9040SKiran Kumar K npc_parse_lf, npc_parse_lg, 921296e9040SKiran Kumar K npc_parse_lh, 922a07f7cedSKiran Kumar K }; 923a07f7cedSKiran Kumar K uint8_t layer = 0; 924a07f7cedSKiran Kumar K int key_offset; 925a07f7cedSKiran Kumar K int rc; 926a07f7cedSKiran Kumar K 927a07f7cedSKiran Kumar K if (pattern == NULL) 928a07f7cedSKiran Kumar K return NPC_ERR_PARAM; 929a07f7cedSKiran Kumar K 930a07f7cedSKiran Kumar K pst->npc = npc; 931a07f7cedSKiran Kumar K pst->flow = flow; 932b7fff4e4SSatheesh Paul pst->nix_intf = flow->nix_intf; 933a07f7cedSKiran Kumar K 934a07f7cedSKiran Kumar K /* Use integral byte offset */ 935a07f7cedSKiran Kumar K key_offset = pst->npc->keyx_len[flow->nix_intf]; 936a07f7cedSKiran Kumar K key_offset = (key_offset + 7) / 8; 937a07f7cedSKiran Kumar K 938a07f7cedSKiran Kumar K /* Location where LDATA would begin */ 939a07f7cedSKiran Kumar K pst->mcam_data = (uint8_t *)flow->mcam_data; 940a07f7cedSKiran Kumar K pst->mcam_mask = (uint8_t *)flow->mcam_mask; 941a07f7cedSKiran Kumar K 942a07f7cedSKiran Kumar K while (pattern->type != ROC_NPC_ITEM_TYPE_END && 943a07f7cedSKiran Kumar K layer < PLT_DIM(parse_stage_funcs)) { 944a07f7cedSKiran Kumar K /* Skip place-holders */ 945a07f7cedSKiran Kumar K pattern = npc_parse_skip_void_and_any_items(pattern); 946a07f7cedSKiran Kumar K 947a07f7cedSKiran Kumar K pst->pattern = pattern; 948a07f7cedSKiran Kumar K rc = parse_stage_funcs[layer](pst); 949a07f7cedSKiran Kumar K if (rc != 0) 950a07f7cedSKiran Kumar K return rc; 951a07f7cedSKiran Kumar K 952a07f7cedSKiran Kumar K layer++; 953a07f7cedSKiran Kumar K 954a07f7cedSKiran Kumar K /* 955a07f7cedSKiran Kumar K * Parse stage function sets pst->pattern to 956a07f7cedSKiran Kumar K * 1 past the last item it consumed. 957a07f7cedSKiran Kumar K */ 958a07f7cedSKiran Kumar K pattern = pst->pattern; 959a07f7cedSKiran Kumar K 960a07f7cedSKiran Kumar K if (pst->terminate) 961a07f7cedSKiran Kumar K break; 962a07f7cedSKiran Kumar K } 963a07f7cedSKiran Kumar K 964a07f7cedSKiran Kumar K /* Skip trailing place-holders */ 965a07f7cedSKiran Kumar K pattern = npc_parse_skip_void_and_any_items(pattern); 966a07f7cedSKiran Kumar K 967a07f7cedSKiran Kumar K /* Are there more items than what we can handle? */ 968a07f7cedSKiran Kumar K if (pattern->type != ROC_NPC_ITEM_TYPE_END) 969a07f7cedSKiran Kumar K return NPC_ERR_PATTERN_NOTSUP; 970a07f7cedSKiran Kumar K 971a07f7cedSKiran Kumar K return 0; 972a07f7cedSKiran Kumar K } 973a07f7cedSKiran Kumar K 974a07f7cedSKiran Kumar K static int 975a07f7cedSKiran Kumar K npc_parse_attr(struct npc *npc, const struct roc_npc_attr *attr, 976a07f7cedSKiran Kumar K struct roc_npc_flow *flow) 977a07f7cedSKiran Kumar K { 978a07f7cedSKiran Kumar K if (attr == NULL) 979a07f7cedSKiran Kumar K return NPC_ERR_PARAM; 980a07f7cedSKiran Kumar K else if (attr->priority >= npc->flow_max_priority) 981a07f7cedSKiran Kumar K return NPC_ERR_PARAM; 982a07f7cedSKiran Kumar K else if ((!attr->egress && !attr->ingress) || 983a07f7cedSKiran Kumar K (attr->egress && attr->ingress)) 984a07f7cedSKiran Kumar K return NPC_ERR_PARAM; 985a07f7cedSKiran Kumar K 986a07f7cedSKiran Kumar K if (attr->ingress) 987a07f7cedSKiran Kumar K flow->nix_intf = ROC_NPC_INTF_RX; 988a07f7cedSKiran Kumar K else 989a07f7cedSKiran Kumar K flow->nix_intf = ROC_NPC_INTF_TX; 990a07f7cedSKiran Kumar K 991a07f7cedSKiran Kumar K flow->priority = attr->priority; 992a07f7cedSKiran Kumar K return 0; 993a07f7cedSKiran Kumar K } 994a07f7cedSKiran Kumar K 995a07f7cedSKiran Kumar K static int 996ee48f711SNithin Dabilpuram npc_parse_rule(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, 997b7eb0e0cSSatheesh Paul const struct roc_npc_item_info pattern[], const struct roc_npc_action actions[], 998b7eb0e0cSSatheesh Paul struct roc_npc_flow *flow, struct npc_parse_state *pst) 999a07f7cedSKiran Kumar K { 1000ee48f711SNithin Dabilpuram struct npc *npc = roc_npc_to_npc_priv(roc_npc); 1001b7fff4e4SSatheesh Paul struct roc_nix *roc_nix = roc_npc->roc_nix; 1002b7fff4e4SSatheesh Paul struct nix *nix = roc_nix_to_nix_priv(roc_nix); 1003a07f7cedSKiran Kumar K int err; 1004a07f7cedSKiran Kumar K 1005b7fff4e4SSatheesh Paul pst->nb_tx_queues = nix->nb_tx_queues; 1006b7fff4e4SSatheesh Paul 1007a07f7cedSKiran Kumar K /* Check attr */ 1008a07f7cedSKiran Kumar K err = npc_parse_attr(npc, attr, flow); 1009a07f7cedSKiran Kumar K if (err) 1010a07f7cedSKiran Kumar K return err; 1011a07f7cedSKiran Kumar K 1012a07f7cedSKiran Kumar K /* Check pattern */ 1013a07f7cedSKiran Kumar K err = npc_parse_pattern(npc, pattern, flow, pst); 1014a07f7cedSKiran Kumar K if (err) 1015a07f7cedSKiran Kumar K return err; 1016a07f7cedSKiran Kumar K 1017a07f7cedSKiran Kumar K /* Check action */ 1018b7eb0e0cSSatheesh Paul err = npc_parse_actions(roc_npc, attr, actions, flow, pst->dst_pf_func); 1019a07f7cedSKiran Kumar K if (err) 1020a07f7cedSKiran Kumar K return err; 1021a07f7cedSKiran Kumar K return 0; 1022a07f7cedSKiran Kumar K } 1023a07f7cedSKiran Kumar K 1024a07f7cedSKiran Kumar K int 1025a07f7cedSKiran Kumar K roc_npc_flow_parse(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, 1026a07f7cedSKiran Kumar K const struct roc_npc_item_info pattern[], 1027a07f7cedSKiran Kumar K const struct roc_npc_action actions[], 1028a07f7cedSKiran Kumar K struct roc_npc_flow *flow) 1029a07f7cedSKiran Kumar K { 1030a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 1031a07f7cedSKiran Kumar K struct npc_parse_state parse_state = {0}; 1032a07f7cedSKiran Kumar K int rc; 1033a07f7cedSKiran Kumar K 1034b7eb0e0cSSatheesh Paul rc = npc_parse_rule(roc_npc, attr, pattern, actions, flow, &parse_state); 1035a07f7cedSKiran Kumar K if (rc) 1036a07f7cedSKiran Kumar K return rc; 1037a07f7cedSKiran Kumar K 1038a07f7cedSKiran Kumar K parse_state.is_vf = !roc_nix_is_pf(roc_npc->roc_nix); 1039a07f7cedSKiran Kumar K 1040a07f7cedSKiran Kumar K return npc_program_mcam(npc, &parse_state, 0); 1041a07f7cedSKiran Kumar K } 1042a07f7cedSKiran Kumar K 104351dc6a80SSatheesh Paul int 104451dc6a80SSatheesh Paul npc_rss_free_grp_get(struct npc *npc, uint32_t *pos) 104551dc6a80SSatheesh Paul { 104651dc6a80SSatheesh Paul struct plt_bitmap *bmap = npc->rss_grp_entries; 104751dc6a80SSatheesh Paul 104851dc6a80SSatheesh Paul for (*pos = 0; *pos < ROC_NIX_RSS_GRPS; ++*pos) { 104951dc6a80SSatheesh Paul if (!plt_bitmap_get(bmap, *pos)) 105051dc6a80SSatheesh Paul break; 105151dc6a80SSatheesh Paul } 105251dc6a80SSatheesh Paul return *pos < ROC_NIX_RSS_GRPS ? 0 : -1; 105351dc6a80SSatheesh Paul } 105451dc6a80SSatheesh Paul 105551dc6a80SSatheesh Paul int 1056*29a8df5cSHarman Kalra npc_rss_action_configure(struct roc_npc *roc_npc, const struct roc_npc_action_rss *rss, 1057*29a8df5cSHarman Kalra uint8_t *alg_idx, uint32_t *rss_grp, uint32_t mcam_id, 1058*29a8df5cSHarman Kalra uint16_t rss_repte_pf_func) 105951dc6a80SSatheesh Paul { 106051dc6a80SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 106151dc6a80SSatheesh Paul struct roc_nix *roc_nix = roc_npc->roc_nix; 106251dc6a80SSatheesh Paul struct nix *nix = roc_nix_to_nix_priv(roc_nix); 106351dc6a80SSatheesh Paul uint32_t flowkey_cfg, rss_grp_idx, i, rem; 106451dc6a80SSatheesh Paul uint8_t key[ROC_NIX_RSS_KEY_LEN]; 106551dc6a80SSatheesh Paul const uint8_t *key_ptr; 106651dc6a80SSatheesh Paul uint8_t flowkey_algx; 106756fa6f92SKiran Kumar K uint32_t key_len; 106851dc6a80SSatheesh Paul uint16_t *reta; 106951dc6a80SSatheesh Paul int rc; 107051dc6a80SSatheesh Paul 107156fa6f92SKiran Kumar K roc_nix_rss_key_get(roc_nix, key); 107256fa6f92SKiran Kumar K if (rss->key == NULL) { 107356fa6f92SKiran Kumar K key_ptr = key; 107456fa6f92SKiran Kumar K } else { 107556fa6f92SKiran Kumar K key_len = rss->key_len; 107656fa6f92SKiran Kumar K if (key_len > ROC_NIX_RSS_KEY_LEN) 107756fa6f92SKiran Kumar K key_len = ROC_NIX_RSS_KEY_LEN; 107856fa6f92SKiran Kumar K 107956fa6f92SKiran Kumar K for (i = 0; i < key_len; i++) { 108056fa6f92SKiran Kumar K if (key[i] != rss->key[i]) { 108156fa6f92SKiran Kumar K plt_err("RSS key config not supported"); 108256fa6f92SKiran Kumar K plt_err("New Key:"); 108356fa6f92SKiran Kumar K for (i = 0; i < key_len; i++) 108456fa6f92SKiran Kumar K plt_dump_no_nl("0x%.2x ", rss->key[i]); 108556fa6f92SKiran Kumar K plt_dump_no_nl("\n"); 108656fa6f92SKiran Kumar K plt_err("Configured Key:"); 108756fa6f92SKiran Kumar K for (i = 0; i < ROC_NIX_RSS_KEY_LEN; i++) 108856fa6f92SKiran Kumar K plt_dump_no_nl("0x%.2x ", key[i]); 108956fa6f92SKiran Kumar K plt_dump_no_nl("\n"); 109056fa6f92SKiran Kumar K return -ENOTSUP; 109156fa6f92SKiran Kumar K } 109256fa6f92SKiran Kumar K } 109356fa6f92SKiran Kumar K key_ptr = rss->key; 109456fa6f92SKiran Kumar K } 109556fa6f92SKiran Kumar K 109651dc6a80SSatheesh Paul rc = npc_rss_free_grp_get(npc, &rss_grp_idx); 109751dc6a80SSatheesh Paul /* RSS group :0 is not usable for flow rss action */ 109851dc6a80SSatheesh Paul if (rc < 0 || rss_grp_idx == 0) 109951dc6a80SSatheesh Paul return -ENOSPC; 110051dc6a80SSatheesh Paul 1101*29a8df5cSHarman Kalra for (i = 0; (i < rss->queue_num) && !rss_repte_pf_func; i++) { 110251dc6a80SSatheesh Paul if (rss->queue[i] >= nix->nb_rx_queues) { 110351dc6a80SSatheesh Paul plt_err("queue id > max number of queues"); 110451dc6a80SSatheesh Paul return -EINVAL; 110551dc6a80SSatheesh Paul } 110651dc6a80SSatheesh Paul } 110751dc6a80SSatheesh Paul 110851dc6a80SSatheesh Paul *rss_grp = rss_grp_idx; 110951dc6a80SSatheesh Paul 111051dc6a80SSatheesh Paul roc_nix_rss_key_set(roc_nix, key_ptr); 111151dc6a80SSatheesh Paul 111251dc6a80SSatheesh Paul /* If queue count passed in the rss action is less than 111351dc6a80SSatheesh Paul * HW configured reta size, replicate rss action reta 111451dc6a80SSatheesh Paul * across HW reta table. 111551dc6a80SSatheesh Paul */ 111651dc6a80SSatheesh Paul reta = nix->reta[rss_grp_idx]; 111751dc6a80SSatheesh Paul 111851dc6a80SSatheesh Paul if (rss->queue_num > nix->reta_sz) { 111951dc6a80SSatheesh Paul plt_err("too many queues for RSS context"); 112051dc6a80SSatheesh Paul return -ENOTSUP; 112151dc6a80SSatheesh Paul } 112251dc6a80SSatheesh Paul 112351dc6a80SSatheesh Paul for (i = 0; i < (nix->reta_sz / rss->queue_num); i++) 112451dc6a80SSatheesh Paul memcpy(reta + i * rss->queue_num, rss->queue, 112551dc6a80SSatheesh Paul sizeof(uint16_t) * rss->queue_num); 112651dc6a80SSatheesh Paul 112751dc6a80SSatheesh Paul rem = nix->reta_sz % rss->queue_num; 112851dc6a80SSatheesh Paul if (rem) 1129*29a8df5cSHarman Kalra memcpy(&reta[i * rss->queue_num], rss->queue, rem * sizeof(uint16_t)); 113051dc6a80SSatheesh Paul 1131*29a8df5cSHarman Kalra rc = nix_rss_reta_pffunc_set(roc_nix, *rss_grp, reta, rss_repte_pf_func); 113251dc6a80SSatheesh Paul if (rc) { 113351dc6a80SSatheesh Paul plt_err("Failed to init rss table rc = %d", rc); 113451dc6a80SSatheesh Paul return rc; 113551dc6a80SSatheesh Paul } 113651dc6a80SSatheesh Paul 113751dc6a80SSatheesh Paul flowkey_cfg = roc_npc->flowkey_cfg_state; 113851dc6a80SSatheesh Paul 1139*29a8df5cSHarman Kalra rc = nix_rss_flowkey_pffunc_set(roc_nix, &flowkey_algx, flowkey_cfg, *rss_grp, mcam_id, 1140*29a8df5cSHarman Kalra rss_repte_pf_func); 114151dc6a80SSatheesh Paul if (rc) { 114251dc6a80SSatheesh Paul plt_err("Failed to set rss hash function rc = %d", rc); 114351dc6a80SSatheesh Paul return rc; 114451dc6a80SSatheesh Paul } 114551dc6a80SSatheesh Paul 114651dc6a80SSatheesh Paul *alg_idx = flowkey_algx; 114751dc6a80SSatheesh Paul 114851dc6a80SSatheesh Paul plt_bitmap_set(npc->rss_grp_entries, *rss_grp); 114951dc6a80SSatheesh Paul 115051dc6a80SSatheesh Paul return 0; 115151dc6a80SSatheesh Paul } 115251dc6a80SSatheesh Paul 115351dc6a80SSatheesh Paul int 115451dc6a80SSatheesh Paul npc_rss_action_program(struct roc_npc *roc_npc, 115551dc6a80SSatheesh Paul const struct roc_npc_action actions[], 115651dc6a80SSatheesh Paul struct roc_npc_flow *flow) 115751dc6a80SSatheesh Paul { 115851dc6a80SSatheesh Paul const struct roc_npc_action_rss *rss; 1159296e9040SKiran Kumar K struct roc_npc *npc = roc_npc; 116051dc6a80SSatheesh Paul uint32_t rss_grp; 116151dc6a80SSatheesh Paul uint8_t alg_idx; 116251dc6a80SSatheesh Paul int rc; 116351dc6a80SSatheesh Paul 1164296e9040SKiran Kumar K if (flow->has_rep) { 1165296e9040SKiran Kumar K npc = roc_npc->rep_npc; 1166296e9040SKiran Kumar K npc->flowkey_cfg_state = roc_npc->flowkey_cfg_state; 1167296e9040SKiran Kumar K } 1168296e9040SKiran Kumar K 116951dc6a80SSatheesh Paul for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) { 117051dc6a80SSatheesh Paul if (actions->type == ROC_NPC_ACTION_TYPE_RSS) { 117151dc6a80SSatheesh Paul rss = (const struct roc_npc_action_rss *)actions->conf; 1172*29a8df5cSHarman Kalra rc = npc_rss_action_configure(npc, rss, &alg_idx, &rss_grp, flow->mcam_id, 1173*29a8df5cSHarman Kalra actions->rss_repte_pf_func); 117451dc6a80SSatheesh Paul if (rc) 117551dc6a80SSatheesh Paul return rc; 117651dc6a80SSatheesh Paul 117751dc6a80SSatheesh Paul flow->npc_action &= (~(0xfULL)); 117851dc6a80SSatheesh Paul flow->npc_action |= NIX_RX_ACTIONOP_RSS; 117951dc6a80SSatheesh Paul flow->npc_action |= 118051dc6a80SSatheesh Paul ((uint64_t)(alg_idx & NPC_RSS_ACT_ALG_MASK) 118151dc6a80SSatheesh Paul << NPC_RSS_ACT_ALG_OFFSET) | 118251dc6a80SSatheesh Paul ((uint64_t)(rss_grp & NPC_RSS_ACT_GRP_MASK) 118351dc6a80SSatheesh Paul << NPC_RSS_ACT_GRP_OFFSET); 118451dc6a80SSatheesh Paul break; 118551dc6a80SSatheesh Paul } 118651dc6a80SSatheesh Paul } 118751dc6a80SSatheesh Paul return 0; 118851dc6a80SSatheesh Paul } 118951dc6a80SSatheesh Paul 119019f3cc23SSatheesh Paul static int 119119f3cc23SSatheesh Paul npc_vtag_cfg_delete(struct roc_npc *roc_npc, struct roc_npc_flow *flow) 119219f3cc23SSatheesh Paul { 119319f3cc23SSatheesh Paul struct roc_nix *roc_nix = roc_npc->roc_nix; 119419f3cc23SSatheesh Paul struct nix_vtag_config *vtag_cfg; 119519f3cc23SSatheesh Paul struct nix_vtag_config_rsp *rsp; 1196296e9040SKiran Kumar K struct mbox *mbox, *ombox; 119719f3cc23SSatheesh Paul struct nix *nix; 119819f3cc23SSatheesh Paul int rc = 0; 119919f3cc23SSatheesh Paul 120019f3cc23SSatheesh Paul union { 120119f3cc23SSatheesh Paul uint64_t reg; 120219f3cc23SSatheesh Paul struct nix_tx_vtag_action_s act; 120319f3cc23SSatheesh Paul } tx_vtag_action; 120419f3cc23SSatheesh Paul 120519f3cc23SSatheesh Paul nix = roc_nix_to_nix_priv(roc_nix); 1206296e9040SKiran Kumar K ombox = (&nix->dev)->mbox; 1207296e9040SKiran Kumar K if (flow->has_rep) 1208296e9040SKiran Kumar K ombox = flow->rep_mbox; 1209296e9040SKiran Kumar K mbox = mbox_get(ombox); 121019f3cc23SSatheesh Paul 121119f3cc23SSatheesh Paul tx_vtag_action.reg = flow->vtag_action; 121219f3cc23SSatheesh Paul vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox); 121319f3cc23SSatheesh Paul 121444a9307cSRakesh Kudurumalla if (vtag_cfg == NULL) { 121544a9307cSRakesh Kudurumalla rc = -ENOSPC; 121644a9307cSRakesh Kudurumalla goto exit; 121744a9307cSRakesh Kudurumalla } 121819f3cc23SSatheesh Paul 121919f3cc23SSatheesh Paul vtag_cfg->cfg_type = VTAG_TX; 122019f3cc23SSatheesh Paul vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; 122119f3cc23SSatheesh Paul vtag_cfg->tx.vtag0_idx = tx_vtag_action.act.vtag0_def; 122219f3cc23SSatheesh Paul vtag_cfg->tx.free_vtag0 = true; 122319f3cc23SSatheesh Paul 12248ca851cdSSatheesh Paul if (flow->vtag_insert_count == 2) { 12258ca851cdSSatheesh Paul vtag_cfg->tx.vtag1_idx = tx_vtag_action.act.vtag1_def; 12268ca851cdSSatheesh Paul vtag_cfg->tx.free_vtag1 = true; 12278ca851cdSSatheesh Paul } 12288ca851cdSSatheesh Paul 122919f3cc23SSatheesh Paul rc = mbox_process_msg(mbox, (void *)&rsp); 123019f3cc23SSatheesh Paul if (rc) 123144a9307cSRakesh Kudurumalla goto exit; 123219f3cc23SSatheesh Paul 123344a9307cSRakesh Kudurumalla rc = 0; 123444a9307cSRakesh Kudurumalla exit: 123544a9307cSRakesh Kudurumalla mbox_put(mbox); 123644a9307cSRakesh Kudurumalla return rc; 123719f3cc23SSatheesh Paul } 123819f3cc23SSatheesh Paul 123919f3cc23SSatheesh Paul static int 12408ca851cdSSatheesh Paul npc_vtag_insert_action_parse(const struct roc_npc_action actions[], 12418ca851cdSSatheesh Paul struct roc_npc_flow *flow, 12428ca851cdSSatheesh Paul struct npc_action_vtag_info *vlan_info, 12438ca851cdSSatheesh Paul int *parsed_cnt) 124419f3cc23SSatheesh Paul { 12458ca851cdSSatheesh Paul bool vlan_id_found = false, ethtype_found = false, pcp_found = false; 12468ca851cdSSatheesh Paul int count = 0; 12478ca851cdSSatheesh Paul 12488ca851cdSSatheesh Paul *parsed_cnt = 0; 12498ca851cdSSatheesh Paul 12508ca851cdSSatheesh Paul /* This function parses parameters of one VLAN. When a parameter is 12518ca851cdSSatheesh Paul * found repeated, it treats it as the end of first VLAN's parameters 12528ca851cdSSatheesh Paul * and returns. The caller calls again to parse the parameters of the 12538ca851cdSSatheesh Paul * second VLAN. 12548ca851cdSSatheesh Paul */ 12558ca851cdSSatheesh Paul 12568ca851cdSSatheesh Paul for (; count < NPC_ACTION_MAX_VLAN_PARAMS; count++, actions++) { 12578ca851cdSSatheesh Paul if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_INSERT) { 12588ca851cdSSatheesh Paul if (vlan_id_found) 12598ca851cdSSatheesh Paul return 0; 12608ca851cdSSatheesh Paul 12618ca851cdSSatheesh Paul const struct roc_npc_action_of_set_vlan_vid *vtag = 12628ca851cdSSatheesh Paul (const struct roc_npc_action_of_set_vlan_vid *) 12638ca851cdSSatheesh Paul actions->conf; 12648ca851cdSSatheesh Paul 12658ca851cdSSatheesh Paul vlan_info->vlan_id = plt_be_to_cpu_16(vtag->vlan_vid); 12668ca851cdSSatheesh Paul 12678ca851cdSSatheesh Paul if (vlan_info->vlan_id > 0xfff) { 12688ca851cdSSatheesh Paul plt_err("Invalid vlan_id for set vlan action"); 12698ca851cdSSatheesh Paul return -EINVAL; 12708ca851cdSSatheesh Paul } 12718ca851cdSSatheesh Paul 12728ca851cdSSatheesh Paul flow->vtag_insert_enabled = true; 12738ca851cdSSatheesh Paul (*parsed_cnt)++; 12748ca851cdSSatheesh Paul vlan_id_found = true; 12758ca851cdSSatheesh Paul } else if (actions->type == 12768ca851cdSSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT) { 12778ca851cdSSatheesh Paul if (ethtype_found) 12788ca851cdSSatheesh Paul return 0; 12798ca851cdSSatheesh Paul 12808ca851cdSSatheesh Paul const struct roc_npc_action_of_push_vlan *ethtype = 12818ca851cdSSatheesh Paul (const struct roc_npc_action_of_push_vlan *) 12828ca851cdSSatheesh Paul actions->conf; 12838ca851cdSSatheesh Paul vlan_info->vlan_ethtype = 12848ca851cdSSatheesh Paul plt_be_to_cpu_16(ethtype->ethertype); 12858ca851cdSSatheesh Paul if (vlan_info->vlan_ethtype != ROC_ETHER_TYPE_VLAN && 12868ca851cdSSatheesh Paul vlan_info->vlan_ethtype != ROC_ETHER_TYPE_QINQ) { 12878ca851cdSSatheesh Paul plt_err("Invalid ethtype specified for push" 12888ca851cdSSatheesh Paul " vlan action"); 12898ca851cdSSatheesh Paul return -EINVAL; 12908ca851cdSSatheesh Paul } 12918ca851cdSSatheesh Paul flow->vtag_insert_enabled = true; 12928ca851cdSSatheesh Paul (*parsed_cnt)++; 12938ca851cdSSatheesh Paul ethtype_found = true; 12948ca851cdSSatheesh Paul } else if (actions->type == 12958ca851cdSSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT) { 12968ca851cdSSatheesh Paul if (pcp_found) 12978ca851cdSSatheesh Paul return 0; 12988ca851cdSSatheesh Paul const struct roc_npc_action_of_set_vlan_pcp *pcp = 12998ca851cdSSatheesh Paul (const struct roc_npc_action_of_set_vlan_pcp *) 13008ca851cdSSatheesh Paul actions->conf; 13018ca851cdSSatheesh Paul vlan_info->vlan_pcp = pcp->vlan_pcp; 13028ca851cdSSatheesh Paul if (vlan_info->vlan_pcp > 0x7) { 13038ca851cdSSatheesh Paul plt_err("Invalid PCP value for pcp action"); 13048ca851cdSSatheesh Paul return -EINVAL; 13058ca851cdSSatheesh Paul } 13068ca851cdSSatheesh Paul flow->vtag_insert_enabled = true; 13078ca851cdSSatheesh Paul (*parsed_cnt)++; 13088ca851cdSSatheesh Paul pcp_found = true; 13098ca851cdSSatheesh Paul } else { 13108ca851cdSSatheesh Paul return 0; 13118ca851cdSSatheesh Paul } 13128ca851cdSSatheesh Paul } 13138ca851cdSSatheesh Paul 13148ca851cdSSatheesh Paul return 0; 13158ca851cdSSatheesh Paul } 13168ca851cdSSatheesh Paul 13178ca851cdSSatheesh Paul static int 13188ca851cdSSatheesh Paul npc_vtag_insert_action_configure(struct mbox *mbox, struct roc_npc_flow *flow, 13198ca851cdSSatheesh Paul struct npc_action_vtag_info *vlan_info) 13208ca851cdSSatheesh Paul { 132119f3cc23SSatheesh Paul struct nix_vtag_config *vtag_cfg; 132219f3cc23SSatheesh Paul struct nix_vtag_config_rsp *rsp; 13238ca851cdSSatheesh Paul int rc = 0; 132419f3cc23SSatheesh Paul 132519f3cc23SSatheesh Paul union { 132619f3cc23SSatheesh Paul uint64_t reg; 132719f3cc23SSatheesh Paul struct nix_tx_vtag_action_s act; 132819f3cc23SSatheesh Paul } tx_vtag_action; 132919f3cc23SSatheesh Paul 133044a9307cSRakesh Kudurumalla vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox_get(mbox)); 133119f3cc23SSatheesh Paul 133244a9307cSRakesh Kudurumalla if (vtag_cfg == NULL) { 133344a9307cSRakesh Kudurumalla rc = -ENOSPC; 133444a9307cSRakesh Kudurumalla goto exit; 133544a9307cSRakesh Kudurumalla } 133619f3cc23SSatheesh Paul 13378ca851cdSSatheesh Paul vtag_cfg->cfg_type = VTAG_TX; 13388ca851cdSSatheesh Paul vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; 13398ca851cdSSatheesh Paul vtag_cfg->tx.vtag0 = 13402447b0b6SGowrishankar Muthukrishnan (((uint32_t)vlan_info[0].vlan_ethtype << 16) | 13418ca851cdSSatheesh Paul (vlan_info[0].vlan_pcp << 13) | vlan_info[0].vlan_id); 13428ca851cdSSatheesh Paul 13438ca851cdSSatheesh Paul vtag_cfg->tx.cfg_vtag0 = 1; 13448ca851cdSSatheesh Paul 13458ca851cdSSatheesh Paul if (flow->vtag_insert_count == 2) { 13468ca851cdSSatheesh Paul vtag_cfg->tx.vtag1 = 13472447b0b6SGowrishankar Muthukrishnan (((uint32_t)vlan_info[1].vlan_ethtype << 16) | 13488ca851cdSSatheesh Paul (vlan_info[1].vlan_pcp << 13) | vlan_info[1].vlan_id); 13498ca851cdSSatheesh Paul 13508ca851cdSSatheesh Paul vtag_cfg->tx.cfg_vtag1 = 1; 13518ca851cdSSatheesh Paul } 13528ca851cdSSatheesh Paul 13538ca851cdSSatheesh Paul rc = mbox_process_msg(mbox, (void *)&rsp); 13548ca851cdSSatheesh Paul if (rc) 135544a9307cSRakesh Kudurumalla goto exit; 13568ca851cdSSatheesh Paul 13578ca851cdSSatheesh Paul if (rsp->vtag0_idx < 0 || 13588ca851cdSSatheesh Paul ((flow->vtag_insert_count == 2) && (rsp->vtag1_idx < 0))) { 13598ca851cdSSatheesh Paul plt_err("Failed to config TX VTAG action"); 136044a9307cSRakesh Kudurumalla rc = -EINVAL; 136144a9307cSRakesh Kudurumalla goto exit; 13628ca851cdSSatheesh Paul } 13638ca851cdSSatheesh Paul 13648ca851cdSSatheesh Paul tx_vtag_action.reg = 0; 13658ca851cdSSatheesh Paul tx_vtag_action.act.vtag0_def = rsp->vtag0_idx; 13668ca851cdSSatheesh Paul tx_vtag_action.act.vtag0_lid = NPC_LID_LA; 13678ca851cdSSatheesh Paul tx_vtag_action.act.vtag0_op = NIX_TX_VTAGOP_INSERT; 13688ca851cdSSatheesh Paul tx_vtag_action.act.vtag0_relptr = NIX_TX_VTAGACTION_VTAG0_RELPTR; 13698ca851cdSSatheesh Paul 13708ca851cdSSatheesh Paul if (flow->vtag_insert_count == 2) { 13718ca851cdSSatheesh Paul tx_vtag_action.act.vtag1_def = rsp->vtag1_idx; 13728ca851cdSSatheesh Paul tx_vtag_action.act.vtag1_lid = NPC_LID_LA; 13738ca851cdSSatheesh Paul tx_vtag_action.act.vtag1_op = NIX_TX_VTAGOP_INSERT; 13748ca851cdSSatheesh Paul /* NIX_TX_VTAG_ACTION_S 13758ca851cdSSatheesh Paul * If Vtag 0 is inserted, hardware adjusts the Vtag 1 byte 13768ca851cdSSatheesh Paul * offset accordingly. Thus, if the two offsets are equal in 13778ca851cdSSatheesh Paul * the structure, hardware inserts Vtag 1 immediately after 13788ca851cdSSatheesh Paul * Vtag 0 in the packet. 13798ca851cdSSatheesh Paul */ 13808ca851cdSSatheesh Paul tx_vtag_action.act.vtag1_relptr = 13818ca851cdSSatheesh Paul NIX_TX_VTAGACTION_VTAG0_RELPTR; 13828ca851cdSSatheesh Paul } 13838ca851cdSSatheesh Paul 13848ca851cdSSatheesh Paul flow->vtag_action = tx_vtag_action.reg; 13858ca851cdSSatheesh Paul 138644a9307cSRakesh Kudurumalla rc = 0; 138744a9307cSRakesh Kudurumalla exit: 138844a9307cSRakesh Kudurumalla mbox_put(mbox); 138944a9307cSRakesh Kudurumalla return rc; 13908ca851cdSSatheesh Paul } 13918ca851cdSSatheesh Paul 13928ca851cdSSatheesh Paul static int 13938ca851cdSSatheesh Paul npc_vtag_strip_action_configure(struct mbox *mbox, 13948ca851cdSSatheesh Paul const struct roc_npc_action actions[], 13958ca851cdSSatheesh Paul struct roc_npc_flow *flow, int *strip_cnt) 13968ca851cdSSatheesh Paul { 13978ca851cdSSatheesh Paul struct nix_vtag_config *vtag_cfg; 13988ca851cdSSatheesh Paul uint64_t rx_vtag_action = 0; 13998ca851cdSSatheesh Paul int count = 0, rc = 0; 14008ca851cdSSatheesh Paul 14018ca851cdSSatheesh Paul *strip_cnt = 0; 14028ca851cdSSatheesh Paul 14038ca851cdSSatheesh Paul for (; count < NPC_ACTION_MAX_VLANS_STRIPPED; count++, actions++) { 14048ca851cdSSatheesh Paul if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_STRIP) 14058ca851cdSSatheesh Paul (*strip_cnt)++; 14068ca851cdSSatheesh Paul } 14078ca851cdSSatheesh Paul 140844a9307cSRakesh Kudurumalla vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox_get(mbox)); 140919f3cc23SSatheesh Paul 141044a9307cSRakesh Kudurumalla if (vtag_cfg == NULL) { 141144a9307cSRakesh Kudurumalla rc = -ENOSPC; 141244a9307cSRakesh Kudurumalla goto exit; 141344a9307cSRakesh Kudurumalla } 141419f3cc23SSatheesh Paul 141519f3cc23SSatheesh Paul vtag_cfg->cfg_type = VTAG_RX; 141619f3cc23SSatheesh Paul vtag_cfg->rx.strip_vtag = 1; 141719f3cc23SSatheesh Paul /* Always capture */ 141819f3cc23SSatheesh Paul vtag_cfg->rx.capture_vtag = 1; 141919f3cc23SSatheesh Paul vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; 142019f3cc23SSatheesh Paul vtag_cfg->rx.vtag_type = 0; 142119f3cc23SSatheesh Paul 142219f3cc23SSatheesh Paul rc = mbox_process(mbox); 142319f3cc23SSatheesh Paul if (rc) 142444a9307cSRakesh Kudurumalla goto exit; 142519f3cc23SSatheesh Paul 142619f3cc23SSatheesh Paul rx_vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 15); 142719f3cc23SSatheesh Paul rx_vtag_action |= ((uint64_t)NPC_LID_LB << 8); 1428296e9040SKiran Kumar K rx_vtag_action |= ((uint64_t)NIX_RX_VTAG_TYPE6 << 12); 142919f3cc23SSatheesh Paul rx_vtag_action |= NIX_RX_VTAGACTION_VTAG0_RELPTR; 14308ca851cdSSatheesh Paul 14318ca851cdSSatheesh Paul if (*strip_cnt == 2) { 14328ca851cdSSatheesh Paul rx_vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 47); 14338ca851cdSSatheesh Paul rx_vtag_action |= ((uint64_t)NPC_LID_LB << 40); 14348ca851cdSSatheesh Paul rx_vtag_action |= NIX_RX_VTAGACTION_VTAG0_RELPTR << 32; 14358ca851cdSSatheesh Paul } 143619f3cc23SSatheesh Paul flow->vtag_action = rx_vtag_action; 14378ca851cdSSatheesh Paul 143844a9307cSRakesh Kudurumalla rc = 0; 143944a9307cSRakesh Kudurumalla exit: 144044a9307cSRakesh Kudurumalla mbox_put(mbox); 144144a9307cSRakesh Kudurumalla return rc; 14428ca851cdSSatheesh Paul } 14438ca851cdSSatheesh Paul 14448ca851cdSSatheesh Paul static int 14458ca851cdSSatheesh Paul npc_vtag_action_program(struct roc_npc *roc_npc, 14468ca851cdSSatheesh Paul const struct roc_npc_action actions[], 14478ca851cdSSatheesh Paul struct roc_npc_flow *flow) 14488ca851cdSSatheesh Paul { 14498ca851cdSSatheesh Paul bool vlan_strip_parsed = false, vlan_insert_parsed = false; 14508ca851cdSSatheesh Paul const struct roc_npc_action *insert_actions; 14518ca851cdSSatheesh Paul struct roc_nix *roc_nix = roc_npc->roc_nix; 14528ca851cdSSatheesh Paul struct npc_action_vtag_info vlan_info[2]; 14538ca851cdSSatheesh Paul int parsed_cnt = 0, strip_cnt = 0; 14548ca851cdSSatheesh Paul int tot_vlan_params = 0; 14558ca851cdSSatheesh Paul struct mbox *mbox; 14568ca851cdSSatheesh Paul struct nix *nix; 14578ca851cdSSatheesh Paul int i, rc; 14588ca851cdSSatheesh Paul 14598ca851cdSSatheesh Paul nix = roc_nix_to_nix_priv(roc_nix); 14608ca851cdSSatheesh Paul mbox = (&nix->dev)->mbox; 1461296e9040SKiran Kumar K if (flow->has_rep) 1462296e9040SKiran Kumar K mbox = flow->rep_mbox; 14638ca851cdSSatheesh Paul 14648ca851cdSSatheesh Paul memset(vlan_info, 0, sizeof(vlan_info)); 14658ca851cdSSatheesh Paul 14668ca851cdSSatheesh Paul flow->vtag_insert_enabled = false; 14678ca851cdSSatheesh Paul 14688ca851cdSSatheesh Paul for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) { 14698ca851cdSSatheesh Paul if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_STRIP) { 14708ca851cdSSatheesh Paul if (vlan_strip_parsed) { 14718ca851cdSSatheesh Paul plt_err("Incorrect VLAN strip actions"); 147219f3cc23SSatheesh Paul return -EINVAL; 147319f3cc23SSatheesh Paul } 14748ca851cdSSatheesh Paul rc = npc_vtag_strip_action_configure(mbox, actions, 14758ca851cdSSatheesh Paul flow, &strip_cnt); 14768ca851cdSSatheesh Paul if (rc) 14778ca851cdSSatheesh Paul return rc; 14788ca851cdSSatheesh Paul 1479296e9040SKiran Kumar K plt_npc_dbg("VLAN strip action, strip_cnt %d", strip_cnt); 14808ca851cdSSatheesh Paul if (strip_cnt == 2) 14818ca851cdSSatheesh Paul actions++; 14828ca851cdSSatheesh Paul 14838ca851cdSSatheesh Paul vlan_strip_parsed = true; 14848ca851cdSSatheesh Paul } else if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_INSERT || 14858ca851cdSSatheesh Paul actions->type == 14868ca851cdSSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT || 14878ca851cdSSatheesh Paul actions->type == 148819f3cc23SSatheesh Paul ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT) { 14898ca851cdSSatheesh Paul if (vlan_insert_parsed) { 14908ca851cdSSatheesh Paul plt_err("Incorrect VLAN insert actions"); 149119f3cc23SSatheesh Paul return -EINVAL; 149219f3cc23SSatheesh Paul } 14938ca851cdSSatheesh Paul 14948ca851cdSSatheesh Paul insert_actions = actions; 14958ca851cdSSatheesh Paul 14968ca851cdSSatheesh Paul for (i = 0; i < 2; i++) { 14978ca851cdSSatheesh Paul rc = npc_vtag_insert_action_parse( 14988ca851cdSSatheesh Paul insert_actions, flow, &vlan_info[i], 14998ca851cdSSatheesh Paul &parsed_cnt); 15008ca851cdSSatheesh Paul 15018ca851cdSSatheesh Paul if (rc) 15028ca851cdSSatheesh Paul return rc; 15038ca851cdSSatheesh Paul 15048ca851cdSSatheesh Paul if (parsed_cnt) { 15058ca851cdSSatheesh Paul insert_actions += parsed_cnt; 15068ca851cdSSatheesh Paul tot_vlan_params += parsed_cnt; 15078ca851cdSSatheesh Paul flow->vtag_insert_count++; 15088ca851cdSSatheesh Paul } 15098ca851cdSSatheesh Paul } 15108ca851cdSSatheesh Paul actions += tot_vlan_params - 1; 15118ca851cdSSatheesh Paul vlan_insert_parsed = true; 151219f3cc23SSatheesh Paul } 151319f3cc23SSatheesh Paul } 151419f3cc23SSatheesh Paul 151519f3cc23SSatheesh Paul if (flow->vtag_insert_enabled) { 15168ca851cdSSatheesh Paul rc = npc_vtag_insert_action_configure(mbox, flow, vlan_info); 151719f3cc23SSatheesh Paul 151819f3cc23SSatheesh Paul if (rc) 151919f3cc23SSatheesh Paul return rc; 152019f3cc23SSatheesh Paul } 152119f3cc23SSatheesh Paul return 0; 152219f3cc23SSatheesh Paul } 152319f3cc23SSatheesh Paul 1524df5cf15fSKiran Kumar K static int 1525df5cf15fSKiran Kumar K npc_inline_dev_ipsec_action_free(struct npc *npc, struct roc_npc_flow *flow) 1526df5cf15fSKiran Kumar K { 1527df5cf15fSKiran Kumar K struct nix_inl_dev *inl_dev; 1528df5cf15fSKiran Kumar K struct idev_cfg *idev; 1529df5cf15fSKiran Kumar K int rc; 1530df5cf15fSKiran Kumar K 1531df5cf15fSKiran Kumar K PLT_SET_USED(npc); 1532df5cf15fSKiran Kumar K 1533df5cf15fSKiran Kumar K idev = idev_get_cfg(); 1534df5cf15fSKiran Kumar K if (!idev) 1535df5cf15fSKiran Kumar K return 1; 1536df5cf15fSKiran Kumar K 1537df5cf15fSKiran Kumar K inl_dev = idev->nix_inl_dev; 1538df5cf15fSKiran Kumar K 1539df5cf15fSKiran Kumar K if (flow->nix_intf == NIX_INTF_RX && inl_dev && inl_dev->ipsec_index && 1540df5cf15fSKiran Kumar K ((flow->npc_action & 0xF) == NIX_RX_ACTIONOP_UCAST_IPSEC)) { 1541df5cf15fSKiran Kumar K inl_dev->curr_ipsec_idx--; 1542df5cf15fSKiran Kumar K inl_dev->ipsec_index[inl_dev->curr_ipsec_idx] = flow->mcam_id; 1543df5cf15fSKiran Kumar K flow->enable = 0; 1544df5cf15fSKiran Kumar K if (flow->use_ctr) { 1545df5cf15fSKiran Kumar K rc = npc_mcam_clear_counter(inl_dev->dev.mbox, flow->ctr_id); 1546df5cf15fSKiran Kumar K if (rc) 1547df5cf15fSKiran Kumar K return rc; 1548df5cf15fSKiran Kumar K 1549df5cf15fSKiran Kumar K rc = npc_mcam_free_counter(inl_dev->dev.mbox, flow->ctr_id); 1550df5cf15fSKiran Kumar K if (rc) 1551df5cf15fSKiran Kumar K return rc; 1552df5cf15fSKiran Kumar K } 1553df5cf15fSKiran Kumar K return npc_mcam_write_entry(inl_dev->dev.mbox, flow); 1554df5cf15fSKiran Kumar K } 1555df5cf15fSKiran Kumar K 1556df5cf15fSKiran Kumar K return 1; 1557df5cf15fSKiran Kumar K } 1558df5cf15fSKiran Kumar K 1559fd493460SSatheesh Paul void 15602703f1faSSatheesh Paul roc_npc_sdp_channel_get(struct roc_npc *roc_npc, uint16_t *chan_base, uint16_t *chan_mask) 15612703f1faSSatheesh Paul { 15622703f1faSSatheesh Paul struct roc_nix *roc_nix = roc_npc->roc_nix; 15632703f1faSSatheesh Paul struct nix *nix = roc_nix_to_nix_priv(roc_nix); 15642703f1faSSatheesh Paul uint16_t num_chan, range, num_bits = 0; 15652703f1faSSatheesh Paul uint16_t mask = 0; 15662703f1faSSatheesh Paul 15672703f1faSSatheesh Paul *chan_base = nix->rx_chan_base; 15682703f1faSSatheesh Paul num_chan = nix->rx_chan_cnt - 1; 15692703f1faSSatheesh Paul if (num_chan) { 15702703f1faSSatheesh Paul range = *chan_base ^ (*chan_base + num_chan); 1571354bf671SJerin Jacob num_bits = (sizeof(uint32_t) * 8) - plt_clz32(range) - 1; 15722703f1faSSatheesh Paul /* Set mask for (15 - numbits) MSB bits */ 15732703f1faSSatheesh Paul *chan_mask = (uint16_t)~GENMASK(num_bits, 0); 1574fd493460SSatheesh Paul *chan_mask &= 0xFFF; 15752703f1faSSatheesh Paul } else { 1576fd493460SSatheesh Paul *chan_mask = (uint16_t)GENMASK(11, 0); 15772703f1faSSatheesh Paul } 15782703f1faSSatheesh Paul 15792703f1faSSatheesh Paul mask = (uint16_t)GENMASK(num_bits, 0); 15802703f1faSSatheesh Paul if (mask > num_chan + 1) 15812703f1faSSatheesh Paul plt_warn( 15822703f1faSSatheesh Paul "npc: SDP channel base:%x, channel count:%x. channel mask:%x covers more than channel count", 15832703f1faSSatheesh Paul *chan_base, nix->rx_chan_cnt, *chan_mask); 15842703f1faSSatheesh Paul } 15852703f1faSSatheesh Paul 1586a07f7cedSKiran Kumar K struct roc_npc_flow * 1587a07f7cedSKiran Kumar K roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, 1588b7eb0e0cSSatheesh Paul const struct roc_npc_item_info pattern[], const struct roc_npc_action actions[], 1589b7eb0e0cSSatheesh Paul uint16_t dst_pf_func, int *errcode) 1590a07f7cedSKiran Kumar K { 1591a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 15922703f1faSSatheesh Paul uint16_t sdp_chan_base = 0, sdp_chan_mask = 0; 1593a07f7cedSKiran Kumar K struct roc_npc_flow *flow, *flow_iter; 1594a07f7cedSKiran Kumar K struct npc_parse_state parse_state; 1595a07f7cedSKiran Kumar K struct npc_flow_list *list; 1596a07f7cedSKiran Kumar K int rc; 1597a07f7cedSKiran Kumar K 1598d43a7beeSSatheesh Paul npc->channel = roc_npc->channel; 1599f1375663SSatheesh Paul npc->is_sdp_link = roc_nix_is_sdp(roc_npc->roc_nix); 1600f1375663SSatheesh Paul if (npc->is_sdp_link) { 1601f1375663SSatheesh Paul if (roc_npc->is_sdp_mask_set) { 1602f1375663SSatheesh Paul npc->sdp_channel = roc_npc->sdp_channel; 1603f1375663SSatheesh Paul npc->sdp_channel_mask = roc_npc->sdp_channel_mask; 1604f1375663SSatheesh Paul } else { 16052703f1faSSatheesh Paul roc_npc_sdp_channel_get(roc_npc, &sdp_chan_base, &sdp_chan_mask); 16062703f1faSSatheesh Paul npc->sdp_channel = sdp_chan_base; 16072703f1faSSatheesh Paul npc->sdp_channel_mask = sdp_chan_mask; 1608f1375663SSatheesh Paul } 1609b182b227SSatheesh Paul } 1610d43a7beeSSatheesh Paul 1611a07f7cedSKiran Kumar K flow = plt_zmalloc(sizeof(*flow), 0); 1612a07f7cedSKiran Kumar K if (flow == NULL) { 1613a07f7cedSKiran Kumar K *errcode = NPC_ERR_NO_MEM; 1614a07f7cedSKiran Kumar K return NULL; 1615a07f7cedSKiran Kumar K } 1616a07f7cedSKiran Kumar K memset(flow, 0, sizeof(*flow)); 1617b7fff4e4SSatheesh Paul memset(&parse_state, 0, sizeof(parse_state)); 1618a07f7cedSKiran Kumar K 1619296e9040SKiran Kumar K flow->port_id = -1; 1620296e9040SKiran Kumar K if (roc_npc->rep_npc) { 1621296e9040SKiran Kumar K flow->rep_channel = 1622296e9040SKiran Kumar K (roc_npc->rep_rx_channel == 0) ? 1623296e9040SKiran Kumar K roc_nix_to_nix_priv(roc_npc->rep_npc->roc_nix)->rx_chan_base : 1624296e9040SKiran Kumar K roc_npc->rep_rx_channel; 1625296e9040SKiran Kumar K flow->rep_pf_func = roc_npc->rep_pf_func; 1626296e9040SKiran Kumar K flow->rep_act_pf_func = roc_npc->rep_act_pf_func; 1627296e9040SKiran Kumar K flow->rep_act_rep = roc_npc->rep_act_rep; 1628296e9040SKiran Kumar K flow->rep_mbox = roc_npc_to_npc_priv(roc_npc->rep_npc)->mbox; 1629296e9040SKiran Kumar K flow->has_rep = true; 1630296e9040SKiran Kumar K flow->is_rep_vf = !roc_nix_is_pf(roc_npc->rep_npc->roc_nix); 1631296e9040SKiran Kumar K flow->port_id = roc_npc->rep_port_id; 1632296e9040SKiran Kumar K flow->rep_npc = roc_npc_to_npc_priv(roc_npc->rep_npc); 1633296e9040SKiran Kumar K roc_npc->rep_act_rep = false; 1634296e9040SKiran Kumar K roc_npc->rep_act_pf_func = 0; 1635296e9040SKiran Kumar K roc_npc->rep_rx_channel = 0; 1636296e9040SKiran Kumar K } 1637296e9040SKiran Kumar K 1638b7eb0e0cSSatheesh Paul parse_state.dst_pf_func = dst_pf_func; 1639b7eb0e0cSSatheesh Paul 1640b7eb0e0cSSatheesh Paul rc = npc_parse_rule(roc_npc, attr, pattern, actions, flow, &parse_state); 1641a07f7cedSKiran Kumar K if (rc != 0) { 1642a07f7cedSKiran Kumar K *errcode = rc; 1643a07f7cedSKiran Kumar K goto err_exit; 1644a07f7cedSKiran Kumar K } 1645a07f7cedSKiran Kumar K 164619f3cc23SSatheesh Paul rc = npc_vtag_action_program(roc_npc, actions, flow); 164719f3cc23SSatheesh Paul if (rc != 0) { 164819f3cc23SSatheesh Paul *errcode = rc; 164919f3cc23SSatheesh Paul goto err_exit; 165019f3cc23SSatheesh Paul } 165119f3cc23SSatheesh Paul 1652a07f7cedSKiran Kumar K parse_state.is_vf = !roc_nix_is_pf(roc_npc->roc_nix); 1653a07f7cedSKiran Kumar K 1654a07f7cedSKiran Kumar K rc = npc_program_mcam(npc, &parse_state, 1); 1655a07f7cedSKiran Kumar K if (rc != 0) { 1656a07f7cedSKiran Kumar K *errcode = rc; 1657a07f7cedSKiran Kumar K goto err_exit; 1658a07f7cedSKiran Kumar K } 1659a07f7cedSKiran Kumar K 166031525923SSatha Rao /* If Egress mirror requested then enable TL3_TL2_LINK_CFG */ 166131525923SSatha Rao if (flow->is_sampling_rule && (flow->nix_intf == NIX_INTF_TX)) { 166231525923SSatha Rao if (flow->mcast_pf_funcs[0] == npc->pf_func) 166331525923SSatha Rao rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, 166431525923SSatha Rao flow->mcast_pf_funcs[1], true); 166531525923SSatha Rao else 166631525923SSatha Rao rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, 166731525923SSatha Rao flow->mcast_pf_funcs[0], true); 166831525923SSatha Rao if (rc) { 166931525923SSatha Rao plt_err("Adding egress mirror failed"); 167031525923SSatha Rao *errcode = rc; 167131525923SSatha Rao goto err_exit; 167231525923SSatha Rao } 167331525923SSatha Rao } 167431525923SSatha Rao 167551dc6a80SSatheesh Paul rc = npc_rss_action_program(roc_npc, actions, flow); 167651dc6a80SSatheesh Paul if (rc != 0) { 167751dc6a80SSatheesh Paul *errcode = rc; 167851dc6a80SSatheesh Paul goto set_rss_failed; 167951dc6a80SSatheesh Paul } 1680296e9040SKiran Kumar K roc_npc->rep_npc = NULL; 1681*29a8df5cSHarman Kalra roc_npc->rep_act_pf_func = 0; 168251dc6a80SSatheesh Paul 1683c436ab84SAnkur Dwivedi if (flow->has_age_action) 1684c436ab84SAnkur Dwivedi npc_age_flow_list_entry_add(roc_npc, flow); 1685c436ab84SAnkur Dwivedi 1686df5cf15fSKiran Kumar K if (flow->use_pre_alloc == 0) 1687a07f7cedSKiran Kumar K list = &npc->flow_list[flow->priority]; 1688df5cf15fSKiran Kumar K else 1689df5cf15fSKiran Kumar K list = &npc->ipsec_list; 1690a07f7cedSKiran Kumar K /* List in ascending order of mcam entries */ 1691a07f7cedSKiran Kumar K TAILQ_FOREACH(flow_iter, list, next) { 1692a07f7cedSKiran Kumar K if (flow_iter->mcam_id > flow->mcam_id) { 1693a07f7cedSKiran Kumar K TAILQ_INSERT_BEFORE(flow_iter, flow, next); 1694296e9040SKiran Kumar K roc_npc->rep_npc = NULL; 1695a07f7cedSKiran Kumar K return flow; 1696a07f7cedSKiran Kumar K } 1697a07f7cedSKiran Kumar K } 1698a07f7cedSKiran Kumar K TAILQ_INSERT_TAIL(list, flow, next); 1699357f5ebcSAnkur Dwivedi 1700a07f7cedSKiran Kumar K return flow; 1701a07f7cedSKiran Kumar K 170251dc6a80SSatheesh Paul set_rss_failed: 1703296e9040SKiran Kumar K roc_npc->rep_npc = NULL; 1704*29a8df5cSHarman Kalra roc_npc->rep_act_pf_func = 0; 1705df5cf15fSKiran Kumar K if (flow->use_pre_alloc == 0) { 170622d9d348SSatheesh Paul rc = roc_npc_mcam_free_entry(roc_npc, flow->mcam_id); 170751dc6a80SSatheesh Paul if (rc != 0) { 170851dc6a80SSatheesh Paul *errcode = rc; 170951dc6a80SSatheesh Paul plt_free(flow); 171051dc6a80SSatheesh Paul return NULL; 171151dc6a80SSatheesh Paul } 1712df5cf15fSKiran Kumar K } else { 1713df5cf15fSKiran Kumar K npc_inline_dev_ipsec_action_free(npc, flow); 1714df5cf15fSKiran Kumar K } 1715a07f7cedSKiran Kumar K err_exit: 1716296e9040SKiran Kumar K roc_npc->rep_npc = NULL; 1717*29a8df5cSHarman Kalra roc_npc->rep_act_pf_func = 0; 1718a07f7cedSKiran Kumar K plt_free(flow); 1719a07f7cedSKiran Kumar K return NULL; 1720a07f7cedSKiran Kumar K } 1721a07f7cedSKiran Kumar K 1722a07f7cedSKiran Kumar K int 172351dc6a80SSatheesh Paul npc_rss_group_free(struct npc *npc, struct roc_npc_flow *flow) 172451dc6a80SSatheesh Paul { 1725296e9040SKiran Kumar K struct npc *lnpc = npc; 172651dc6a80SSatheesh Paul uint32_t rss_grp; 172751dc6a80SSatheesh Paul 1728296e9040SKiran Kumar K if (flow->has_rep) 1729296e9040SKiran Kumar K lnpc = flow->rep_npc; 1730296e9040SKiran Kumar K 173151dc6a80SSatheesh Paul if ((flow->npc_action & 0xF) == NIX_RX_ACTIONOP_RSS) { 173251dc6a80SSatheesh Paul rss_grp = (flow->npc_action >> NPC_RSS_ACT_GRP_OFFSET) & 173351dc6a80SSatheesh Paul NPC_RSS_ACT_GRP_MASK; 173451dc6a80SSatheesh Paul if (rss_grp == 0 || rss_grp >= npc->rss_grps) 173551dc6a80SSatheesh Paul return -EINVAL; 173651dc6a80SSatheesh Paul 1737296e9040SKiran Kumar K plt_bitmap_clear(lnpc->rss_grp_entries, rss_grp); 173851dc6a80SSatheesh Paul } 173951dc6a80SSatheesh Paul 174051dc6a80SSatheesh Paul return 0; 174151dc6a80SSatheesh Paul } 174251dc6a80SSatheesh Paul 174304087b78SSatheesh Paul static int 174404087b78SSatheesh Paul roc_npc_delete_spi_to_sa_action(struct roc_npc *roc_npc, struct roc_npc_flow *flow) 174504087b78SSatheesh Paul { 174604087b78SSatheesh Paul struct nix_spi_to_sa_delete_req *req; 174760f0cf50SSatheesh Paul struct nix_inl_dev *inl_dev; 174860f0cf50SSatheesh Paul struct idev_cfg *idev; 174904087b78SSatheesh Paul struct mbox *mbox; 175060f0cf50SSatheesh Paul 175160f0cf50SSatheesh Paul PLT_SET_USED(roc_npc); 175204087b78SSatheesh Paul 175304087b78SSatheesh Paul if (!flow->spi_to_sa_info.has_action || flow->spi_to_sa_info.duplicate) 175404087b78SSatheesh Paul return 0; 175504087b78SSatheesh Paul 175660f0cf50SSatheesh Paul idev = idev_get_cfg(); 175760f0cf50SSatheesh Paul if (!idev) 175860f0cf50SSatheesh Paul return -1; 175960f0cf50SSatheesh Paul 176060f0cf50SSatheesh Paul inl_dev = idev->nix_inl_dev; 176160f0cf50SSatheesh Paul mbox = inl_dev->dev.mbox; 176204087b78SSatheesh Paul req = mbox_alloc_msg_nix_spi_to_sa_delete(mbox); 176304087b78SSatheesh Paul if (req == NULL) 176404087b78SSatheesh Paul return -ENOSPC; 176504087b78SSatheesh Paul req->hash_index = flow->spi_to_sa_info.hash_index; 176604087b78SSatheesh Paul req->way = flow->spi_to_sa_info.way; 176704087b78SSatheesh Paul return mbox_process_msg(mbox, NULL); 176804087b78SSatheesh Paul } 176904087b78SSatheesh Paul 177051dc6a80SSatheesh Paul int 1771a07f7cedSKiran Kumar K roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow) 1772a07f7cedSKiran Kumar K { 1773a07f7cedSKiran Kumar K struct npc *npc = roc_npc_to_npc_priv(roc_npc); 1774a07f7cedSKiran Kumar K int rc; 1775a07f7cedSKiran Kumar K 177604087b78SSatheesh Paul rc = roc_npc_delete_spi_to_sa_action(roc_npc, flow); 177704087b78SSatheesh Paul if (rc) 177804087b78SSatheesh Paul return rc; 177904087b78SSatheesh Paul 1780df5cf15fSKiran Kumar K if (npc_inline_dev_ipsec_action_free(npc, flow) == 0) { 1781df5cf15fSKiran Kumar K TAILQ_REMOVE(&npc->ipsec_list, flow, next); 1782df5cf15fSKiran Kumar K goto done; 1783df5cf15fSKiran Kumar K } 1784df5cf15fSKiran Kumar K 178551dc6a80SSatheesh Paul rc = npc_rss_group_free(npc, flow); 178651dc6a80SSatheesh Paul if (rc != 0) { 178751dc6a80SSatheesh Paul plt_err("Failed to free rss action rc = %d", rc); 178851dc6a80SSatheesh Paul return rc; 178951dc6a80SSatheesh Paul } 179051dc6a80SSatheesh Paul 179119f3cc23SSatheesh Paul if (flow->vtag_insert_enabled) { 179219f3cc23SSatheesh Paul rc = npc_vtag_cfg_delete(roc_npc, flow); 179319f3cc23SSatheesh Paul if (rc != 0) 179419f3cc23SSatheesh Paul return rc; 179519f3cc23SSatheesh Paul } 179619f3cc23SSatheesh Paul 179731525923SSatha Rao /* Disable egress mirror rule */ 179831525923SSatha Rao if (flow->is_sampling_rule && (flow->nix_intf == NIX_INTF_TX)) { 179931525923SSatha Rao if (flow->mcast_pf_funcs[0] == npc->pf_func) 180031525923SSatha Rao rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, 180131525923SSatha Rao flow->mcast_pf_funcs[1], false); 180231525923SSatha Rao else 180331525923SSatha Rao rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, 180431525923SSatha Rao flow->mcast_pf_funcs[0], false); 180531525923SSatha Rao if (rc) 180631525923SSatha Rao plt_err("Failed to remove egress mirror rule"); 180731525923SSatha Rao } 1808209188d1SSatheesh Paul if (flow->is_sampling_rule) 1809209188d1SSatheesh Paul roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index); 1810209188d1SSatheesh Paul 181122d9d348SSatheesh Paul rc = roc_npc_mcam_free(roc_npc, flow); 1812a07f7cedSKiran Kumar K if (rc != 0) 1813a07f7cedSKiran Kumar K return rc; 1814a07f7cedSKiran Kumar K 1815a07f7cedSKiran Kumar K TAILQ_REMOVE(&npc->flow_list[flow->priority], flow, next); 1816a07f7cedSKiran Kumar K 18171f669198SSatheesh Paul npc_delete_prio_list_entry(npc, flow); 1818a07f7cedSKiran Kumar K 1819c436ab84SAnkur Dwivedi if (flow->has_age_action) 1820357f5ebcSAnkur Dwivedi npc_age_flow_list_entry_delete(roc_npc, flow); 1821c436ab84SAnkur Dwivedi 182285e9542dSSatheesh Paul if (roc_npc->flow_age.age_flow_refcnt == 0) 1823357f5ebcSAnkur Dwivedi npc_aging_ctrl_thread_destroy(roc_npc); 1824357f5ebcSAnkur Dwivedi 1825df5cf15fSKiran Kumar K done: 1826a07f7cedSKiran Kumar K plt_free(flow); 1827a07f7cedSKiran Kumar K return 0; 1828a07f7cedSKiran Kumar K } 18299869c399SSatheesh Paul 18309869c399SSatheesh Paul void 1831296e9040SKiran Kumar K roc_npc_flow_dump(FILE *file, struct roc_npc *roc_npc, int rep_port_id) 18329869c399SSatheesh Paul { 18339869c399SSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 18349869c399SSatheesh Paul struct roc_npc_flow *flow_iter; 18359869c399SSatheesh Paul struct npc_flow_list *list; 18369869c399SSatheesh Paul uint32_t max_prio, i; 18379869c399SSatheesh Paul 18389869c399SSatheesh Paul max_prio = npc->flow_max_priority; 18399869c399SSatheesh Paul 18409869c399SSatheesh Paul for (i = 0; i < max_prio; i++) { 18419869c399SSatheesh Paul list = &npc->flow_list[i]; 18429869c399SSatheesh Paul 18439869c399SSatheesh Paul /* List in ascending order of mcam entries */ 18449869c399SSatheesh Paul TAILQ_FOREACH(flow_iter, list, next) { 1845296e9040SKiran Kumar K if (rep_port_id == -1 || rep_port_id == flow_iter->port_id) 18469869c399SSatheesh Paul roc_npc_flow_mcam_dump(file, roc_npc, flow_iter); 18479869c399SSatheesh Paul } 18489869c399SSatheesh Paul } 184944550b64SSatheesh Paul 185044550b64SSatheesh Paul TAILQ_FOREACH(flow_iter, &npc->ipsec_list, next) { 1851296e9040SKiran Kumar K if (rep_port_id == -1 || rep_port_id == flow_iter->port_id) 185244550b64SSatheesh Paul roc_npc_flow_mcam_dump(file, roc_npc, flow_iter); 185344550b64SSatheesh Paul } 18549869c399SSatheesh Paul } 18550cc909ccSSatheesh Paul 18560cc909ccSSatheesh Paul int 185744550b64SSatheesh Paul roc_npc_mcam_merge_base_steering_rule(struct roc_npc *roc_npc, struct roc_npc_flow *flow) 18580cc909ccSSatheesh Paul { 18590cc909ccSSatheesh Paul struct npc_mcam_read_base_rule_rsp *base_rule_rsp; 18600cc909ccSSatheesh Paul struct npc *npc = roc_npc_to_npc_priv(roc_npc); 18610cc909ccSSatheesh Paul struct mcam_entry *base_entry; 186244a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(npc->mbox); 18630cc909ccSSatheesh Paul int idx, rc; 18640cc909ccSSatheesh Paul 186544a9307cSRakesh Kudurumalla if (roc_nix_is_pf(roc_npc->roc_nix)) { 186644a9307cSRakesh Kudurumalla rc = 0; 186744a9307cSRakesh Kudurumalla goto exit; 186844a9307cSRakesh Kudurumalla } 18690cc909ccSSatheesh Paul 187044a9307cSRakesh Kudurumalla (void)mbox_alloc_msg_npc_read_base_steer_rule(mbox); 187144a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void *)&base_rule_rsp); 18720cc909ccSSatheesh Paul if (rc) { 18730cc909ccSSatheesh Paul plt_err("Failed to fetch VF's base MCAM entry"); 187444a9307cSRakesh Kudurumalla goto exit; 18750cc909ccSSatheesh Paul } 18760cc909ccSSatheesh Paul base_entry = &base_rule_rsp->entry_data; 18770cc909ccSSatheesh Paul for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) { 18780cc909ccSSatheesh Paul flow->mcam_data[idx] |= base_entry->kw[idx]; 18790cc909ccSSatheesh Paul flow->mcam_mask[idx] |= base_entry->kw_mask[idx]; 18800cc909ccSSatheesh Paul } 18810cc909ccSSatheesh Paul 188244a9307cSRakesh Kudurumalla rc = 0; 188344a9307cSRakesh Kudurumalla exit: 188444a9307cSRakesh Kudurumalla mbox_put(mbox); 188544a9307cSRakesh Kudurumalla return rc; 18860cc909ccSSatheesh Paul } 1887