1f9af9080SKiran Kumar K /* SPDX-License-Identifier: BSD-3-Clause
2f9af9080SKiran Kumar K * Copyright(C) 2021 Marvell.
3f9af9080SKiran Kumar K */
4f9af9080SKiran Kumar K #include "roc_api.h"
5f9af9080SKiran Kumar K #include "roc_priv.h"
6f9af9080SKiran Kumar K
7df29c91cSHarman Kalra int
npc_mcam_alloc_counter(struct mbox * mbox,uint16_t * ctr)8df5cf15fSKiran Kumar K npc_mcam_alloc_counter(struct mbox *mbox, uint16_t *ctr)
9f9af9080SKiran Kumar K {
10f9af9080SKiran Kumar K struct npc_mcam_alloc_counter_req *req;
11f9af9080SKiran Kumar K struct npc_mcam_alloc_counter_rsp *rsp;
12f9af9080SKiran Kumar K int rc = -ENOSPC;
13f9af9080SKiran Kumar K
1444a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_alloc_counter(mbox_get(mbox));
15f9af9080SKiran Kumar K if (req == NULL)
1644a9307cSRakesh Kudurumalla goto exit;
17f9af9080SKiran Kumar K req->count = 1;
18f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&rsp);
19f9af9080SKiran Kumar K if (rc)
2044a9307cSRakesh Kudurumalla goto exit;
21f9af9080SKiran Kumar K *ctr = rsp->cntr_list[0];
2244a9307cSRakesh Kudurumalla exit:
2344a9307cSRakesh Kudurumalla mbox_put(mbox);
24f9af9080SKiran Kumar K return rc;
25f9af9080SKiran Kumar K }
26f9af9080SKiran Kumar K
27f9af9080SKiran Kumar K int
npc_mcam_free_counter(struct mbox * mbox,uint16_t ctr_id)28df5cf15fSKiran Kumar K npc_mcam_free_counter(struct mbox *mbox, uint16_t ctr_id)
29f9af9080SKiran Kumar K {
30f9af9080SKiran Kumar K struct npc_mcam_oper_counter_req *req;
31f9af9080SKiran Kumar K int rc = -ENOSPC;
32f9af9080SKiran Kumar K
3344a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_free_counter(mbox_get(mbox));
34f9af9080SKiran Kumar K if (req == NULL)
3544a9307cSRakesh Kudurumalla goto exit;
36f9af9080SKiran Kumar K req->cntr = ctr_id;
3744a9307cSRakesh Kudurumalla rc = mbox_process(mbox);
3844a9307cSRakesh Kudurumalla exit:
3944a9307cSRakesh Kudurumalla mbox_put(mbox);
4044a9307cSRakesh Kudurumalla return rc;
41f9af9080SKiran Kumar K }
42f9af9080SKiran Kumar K
43f9af9080SKiran Kumar K int
npc_mcam_read_counter(struct mbox * mbox,uint32_t ctr_id,uint64_t * count)44df5cf15fSKiran Kumar K npc_mcam_read_counter(struct mbox *mbox, uint32_t ctr_id, uint64_t *count)
45f9af9080SKiran Kumar K {
46f9af9080SKiran Kumar K struct npc_mcam_oper_counter_req *req;
47f9af9080SKiran Kumar K struct npc_mcam_oper_counter_rsp *rsp;
48f9af9080SKiran Kumar K int rc = -ENOSPC;
49f9af9080SKiran Kumar K
5044a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_counter_stats(mbox_get(mbox));
51f9af9080SKiran Kumar K if (req == NULL)
5244a9307cSRakesh Kudurumalla goto exit;
53f9af9080SKiran Kumar K req->cntr = ctr_id;
54f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&rsp);
55f9af9080SKiran Kumar K if (rc)
5644a9307cSRakesh Kudurumalla goto exit;
57f9af9080SKiran Kumar K *count = rsp->stat;
5844a9307cSRakesh Kudurumalla exit:
5944a9307cSRakesh Kudurumalla mbox_put(mbox);
60f9af9080SKiran Kumar K return rc;
61f9af9080SKiran Kumar K }
62f9af9080SKiran Kumar K
63f9af9080SKiran Kumar K int
npc_mcam_clear_counter(struct mbox * mbox,uint32_t ctr_id)64df5cf15fSKiran Kumar K npc_mcam_clear_counter(struct mbox *mbox, uint32_t ctr_id)
65f9af9080SKiran Kumar K {
66f9af9080SKiran Kumar K struct npc_mcam_oper_counter_req *req;
67f9af9080SKiran Kumar K int rc = -ENOSPC;
68f9af9080SKiran Kumar K
6944a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_clear_counter(mbox_get(mbox));
70f9af9080SKiran Kumar K if (req == NULL)
7144a9307cSRakesh Kudurumalla goto exit;
72f9af9080SKiran Kumar K req->cntr = ctr_id;
7344a9307cSRakesh Kudurumalla rc = mbox_process(mbox);
7444a9307cSRakesh Kudurumalla exit:
7544a9307cSRakesh Kudurumalla mbox_put(mbox);
7644a9307cSRakesh Kudurumalla return rc;
77f9af9080SKiran Kumar K }
78f9af9080SKiran Kumar K
79f9af9080SKiran Kumar K int
npc_mcam_free_entry(struct mbox * mbox,uint32_t entry)80df5cf15fSKiran Kumar K npc_mcam_free_entry(struct mbox *mbox, uint32_t entry)
81f9af9080SKiran Kumar K {
82f9af9080SKiran Kumar K struct npc_mcam_free_entry_req *req;
83f9af9080SKiran Kumar K int rc = -ENOSPC;
84f9af9080SKiran Kumar K
8544a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_free_entry(mbox_get(mbox));
86f9af9080SKiran Kumar K if (req == NULL)
8744a9307cSRakesh Kudurumalla goto exit;
88f9af9080SKiran Kumar K req->entry = entry;
8944a9307cSRakesh Kudurumalla rc = mbox_process(mbox);
9044a9307cSRakesh Kudurumalla exit:
9144a9307cSRakesh Kudurumalla mbox_put(mbox);
9244a9307cSRakesh Kudurumalla return rc;
93f9af9080SKiran Kumar K }
94f9af9080SKiran Kumar K
95f9af9080SKiran Kumar K int
npc_mcam_free_all_entries(struct npc * npc)96f9af9080SKiran Kumar K npc_mcam_free_all_entries(struct npc *npc)
97f9af9080SKiran Kumar K {
98f9af9080SKiran Kumar K struct npc_mcam_free_entry_req *req;
9960f0cf50SSatheesh Paul struct mbox *mbox = mbox_get(npc->mbox);
100f9af9080SKiran Kumar K int rc = -ENOSPC;
101f9af9080SKiran Kumar K
10260f0cf50SSatheesh Paul req = mbox_alloc_msg_npc_mcam_free_entry(mbox);
103f9af9080SKiran Kumar K if (req == NULL)
10444a9307cSRakesh Kudurumalla goto exit;
105f9af9080SKiran Kumar K req->all = 1;
10644a9307cSRakesh Kudurumalla rc = mbox_process(mbox);
10744a9307cSRakesh Kudurumalla exit:
10844a9307cSRakesh Kudurumalla mbox_put(mbox);
10944a9307cSRakesh Kudurumalla return rc;
110f9af9080SKiran Kumar K }
111f9af9080SKiran Kumar K
112f9af9080SKiran Kumar K static int
npc_supp_key_len(uint32_t supp_mask)113f9af9080SKiran Kumar K npc_supp_key_len(uint32_t supp_mask)
114f9af9080SKiran Kumar K {
115f9af9080SKiran Kumar K int nib_count = 0;
116f9af9080SKiran Kumar K
117f9af9080SKiran Kumar K while (supp_mask) {
118f9af9080SKiran Kumar K nib_count++;
119f9af9080SKiran Kumar K supp_mask &= (supp_mask - 1);
120f9af9080SKiran Kumar K }
121f9af9080SKiran Kumar K return nib_count * 4;
122f9af9080SKiran Kumar K }
123f9af9080SKiran Kumar K
124f9af9080SKiran Kumar K /**
125f9af9080SKiran Kumar K * Returns true if any LDATA bits are extracted for specific LID+LTYPE.
126f9af9080SKiran Kumar K *
127f9af9080SKiran Kumar K * No LFLAG extraction is taken into account.
128f9af9080SKiran Kumar K */
129f9af9080SKiran Kumar K static int
npc_lid_lt_in_kex(struct npc * npc,uint8_t lid,uint8_t lt)130f9af9080SKiran Kumar K npc_lid_lt_in_kex(struct npc *npc, uint8_t lid, uint8_t lt)
131f9af9080SKiran Kumar K {
132f9af9080SKiran Kumar K struct npc_xtract_info *x_info;
133f9af9080SKiran Kumar K int i;
134f9af9080SKiran Kumar K
135f9af9080SKiran Kumar K for (i = 0; i < NPC_MAX_LD; i++) {
136f9af9080SKiran Kumar K x_info = &npc->prx_dxcfg[NIX_INTF_RX][lid][lt].xtract[i];
137f9af9080SKiran Kumar K /* Check for LDATA */
138f9af9080SKiran Kumar K if (x_info->enable && x_info->len > 0)
139f9af9080SKiran Kumar K return true;
140f9af9080SKiran Kumar K }
141f9af9080SKiran Kumar K
142f9af9080SKiran Kumar K return false;
143f9af9080SKiran Kumar K }
144f9af9080SKiran Kumar K
145f9af9080SKiran Kumar K static void
npc_construct_ldata_mask(struct npc * npc,struct plt_bitmap * bmap,uint8_t lid,uint8_t lt,uint8_t ld)146*296e9040SKiran Kumar K npc_construct_ldata_mask(struct npc *npc, struct plt_bitmap *bmap, uint8_t lid, uint8_t lt,
147*296e9040SKiran Kumar K uint8_t ld)
148f9af9080SKiran Kumar K {
149f9af9080SKiran Kumar K struct npc_xtract_info *x_info, *infoflag;
150f9af9080SKiran Kumar K int hdr_off, keylen;
151f9af9080SKiran Kumar K npc_dxcfg_t *p;
152f9af9080SKiran Kumar K npc_fxcfg_t *q;
153f9af9080SKiran Kumar K int i, j;
154f9af9080SKiran Kumar K
155f9af9080SKiran Kumar K p = &npc->prx_dxcfg;
156f9af9080SKiran Kumar K x_info = &(*p)[0][lid][lt].xtract[ld];
157f9af9080SKiran Kumar K
158f9af9080SKiran Kumar K if (x_info->enable == 0)
159f9af9080SKiran Kumar K return;
160f9af9080SKiran Kumar K
161f9af9080SKiran Kumar K hdr_off = x_info->hdr_off * 8;
162f9af9080SKiran Kumar K keylen = x_info->len * 8;
163f9af9080SKiran Kumar K for (i = hdr_off; i < (hdr_off + keylen); i++)
164f9af9080SKiran Kumar K plt_bitmap_set(bmap, i);
165f9af9080SKiran Kumar K
166f9af9080SKiran Kumar K if (x_info->flags_enable == 0)
167f9af9080SKiran Kumar K return;
168f9af9080SKiran Kumar K
169f9af9080SKiran Kumar K if ((npc->prx_lfcfg[0].i & 0x7) != lid)
170f9af9080SKiran Kumar K return;
171f9af9080SKiran Kumar K
172f9af9080SKiran Kumar K q = &npc->prx_fxcfg;
173f9af9080SKiran Kumar K for (j = 0; j < NPC_MAX_LFL; j++) {
174f9af9080SKiran Kumar K infoflag = &(*q)[0][ld][j].xtract[0];
175f9af9080SKiran Kumar K if (infoflag->enable) {
176f9af9080SKiran Kumar K hdr_off = infoflag->hdr_off * 8;
177f9af9080SKiran Kumar K keylen = infoflag->len * 8;
178f9af9080SKiran Kumar K for (i = hdr_off; i < (hdr_off + keylen); i++)
179f9af9080SKiran Kumar K plt_bitmap_set(bmap, i);
180f9af9080SKiran Kumar K }
181f9af9080SKiran Kumar K }
182f9af9080SKiran Kumar K }
183f9af9080SKiran Kumar K
184f9af9080SKiran Kumar K /**
185f9af9080SKiran Kumar K * Check if given LID+LTYPE combination is present in KEX
186f9af9080SKiran Kumar K *
187f9af9080SKiran Kumar K * len is non-zero, this function will return true if KEX extracts len bytes
188f9af9080SKiran Kumar K * at given offset. Otherwise it'll return true if any bytes are extracted
189f9af9080SKiran Kumar K * specifically for given LID+LTYPE combination (meaning not LFLAG based).
190f9af9080SKiran Kumar K * The second case increases flexibility for custom frames whose extracted
191f9af9080SKiran Kumar K * bits may change depending on KEX profile loaded.
192f9af9080SKiran Kumar K *
193f9af9080SKiran Kumar K * @param npc NPC context structure
194f9af9080SKiran Kumar K * @param lid Layer ID to check for
195f9af9080SKiran Kumar K * @param lt Layer Type to check for
196f9af9080SKiran Kumar K * @param offset offset into the layer header to match
197f9af9080SKiran Kumar K * @param len length of the match
198f9af9080SKiran Kumar K */
199f9af9080SKiran Kumar K static bool
npc_is_kex_enabled(struct npc * npc,uint8_t lid,uint8_t lt,int offset,int len)200*296e9040SKiran Kumar K npc_is_kex_enabled(struct npc *npc, uint8_t lid, uint8_t lt, int offset, int len)
201f9af9080SKiran Kumar K {
202f9af9080SKiran Kumar K struct plt_bitmap *bmap;
203f9af9080SKiran Kumar K uint32_t bmap_sz;
204f9af9080SKiran Kumar K uint8_t *mem;
205f9af9080SKiran Kumar K int i;
206f9af9080SKiran Kumar K
207f9af9080SKiran Kumar K if (!len)
208f9af9080SKiran Kumar K return npc_lid_lt_in_kex(npc, lid, lt);
209f9af9080SKiran Kumar K
210f9af9080SKiran Kumar K bmap_sz = plt_bitmap_get_memory_footprint(300 * 8);
211f9af9080SKiran Kumar K mem = plt_zmalloc(bmap_sz, 0);
212f9af9080SKiran Kumar K if (mem == NULL) {
213f9af9080SKiran Kumar K plt_err("mem alloc failed");
214f9af9080SKiran Kumar K return false;
215f9af9080SKiran Kumar K }
216f9af9080SKiran Kumar K bmap = plt_bitmap_init(300 * 8, mem, bmap_sz);
217f9af9080SKiran Kumar K if (bmap == NULL) {
218f9af9080SKiran Kumar K plt_err("mem alloc failed");
219f9af9080SKiran Kumar K plt_free(mem);
220f9af9080SKiran Kumar K return false;
221f9af9080SKiran Kumar K }
222f9af9080SKiran Kumar K
223f9af9080SKiran Kumar K npc_construct_ldata_mask(npc, bmap, lid, lt, 0);
224f9af9080SKiran Kumar K npc_construct_ldata_mask(npc, bmap, lid, lt, 1);
225f9af9080SKiran Kumar K
226f9af9080SKiran Kumar K for (i = offset; i < (offset + len); i++) {
227f9af9080SKiran Kumar K if (plt_bitmap_get(bmap, i) != 0x1) {
228f9af9080SKiran Kumar K plt_free(mem);
229f9af9080SKiran Kumar K return false;
230f9af9080SKiran Kumar K }
231f9af9080SKiran Kumar K }
232f9af9080SKiran Kumar K
233f9af9080SKiran Kumar K plt_free(mem);
234f9af9080SKiran Kumar K return true;
235f9af9080SKiran Kumar K }
236f9af9080SKiran Kumar K
237f9af9080SKiran Kumar K uint64_t
npc_get_kex_capability(struct npc * npc)238f9af9080SKiran Kumar K npc_get_kex_capability(struct npc *npc)
239f9af9080SKiran Kumar K {
240f9af9080SKiran Kumar K npc_kex_cap_terms_t kex_cap;
241f9af9080SKiran Kumar K
242f9af9080SKiran Kumar K memset(&kex_cap, 0, sizeof(kex_cap));
243f9af9080SKiran Kumar K
244f9af9080SKiran Kumar K /* Ethtype: Offset 12B, len 2B */
24573fc72e1SSatheesh Paul kex_cap.bit.ethtype_0 = npc_is_kex_enabled(npc, NPC_LID_LA, NPC_LT_LA_ETHER, 12 * 8, 2 * 8);
2467be78d02SJosh Soref /* QINQ VLAN Ethtype: offset 8B, len 2B */
24773fc72e1SSatheesh Paul kex_cap.bit.ethtype_x =
24873fc72e1SSatheesh Paul npc_is_kex_enabled(npc, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8 * 8, 2 * 8);
249f9af9080SKiran Kumar K /* VLAN ID0 : Outer VLAN: Offset 2B, len 2B */
25073fc72e1SSatheesh Paul kex_cap.bit.vlan_id_0 = npc_is_kex_enabled(npc, NPC_LID_LB, NPC_LT_LB_CTAG, 2 * 8, 2 * 8);
25173fc72e1SSatheesh Paul /* VLAN PCP0 : Outer VLAN: Offset 2B, len 1B */
25273fc72e1SSatheesh Paul kex_cap.bit.vlan_pcp_0 = npc_is_kex_enabled(npc, NPC_LID_LB, NPC_LT_LB_CTAG, 2 * 8, 2 * 1);
25373fc72e1SSatheesh Paul /* VLAN IDX : Inner VLAN: offset 6B, len 2B */
25473fc72e1SSatheesh Paul kex_cap.bit.vlan_id_x =
25573fc72e1SSatheesh Paul npc_is_kex_enabled(npc, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 6 * 8, 2 * 8);
256f9af9080SKiran Kumar K /* DMCA: offset 0B, len 6B */
25773fc72e1SSatheesh Paul kex_cap.bit.dmac = npc_is_kex_enabled(npc, NPC_LID_LA, NPC_LT_LA_ETHER, 0 * 8, 6 * 8);
258f9af9080SKiran Kumar K /* IP proto: offset 9B, len 1B */
25973fc72e1SSatheesh Paul kex_cap.bit.ip_proto = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP, 9 * 8, 1 * 8);
26073fc72e1SSatheesh Paul /* IPv4 dscp: offset 1B, len 1B, IPv6 dscp: offset 0B, len 2B */
26173fc72e1SSatheesh Paul kex_cap.bit.ip_dscp = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP, 1 * 8, 1 * 8) &&
26273fc72e1SSatheesh Paul npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP6, 0, 2 * 8);
263f9af9080SKiran Kumar K /* UDP dport: offset 2B, len 2B */
26473fc72e1SSatheesh Paul kex_cap.bit.udp_dport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_UDP, 2 * 8, 2 * 8);
265f9af9080SKiran Kumar K /* UDP sport: offset 0B, len 2B */
26673fc72e1SSatheesh Paul kex_cap.bit.udp_sport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_UDP, 0 * 8, 2 * 8);
267f9af9080SKiran Kumar K /* TCP dport: offset 2B, len 2B */
26873fc72e1SSatheesh Paul kex_cap.bit.tcp_dport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_TCP, 2 * 8, 2 * 8);
269f9af9080SKiran Kumar K /* TCP sport: offset 0B, len 2B */
27073fc72e1SSatheesh Paul kex_cap.bit.tcp_sport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_TCP, 0 * 8, 2 * 8);
271f9af9080SKiran Kumar K /* IP SIP: offset 12B, len 4B */
27273fc72e1SSatheesh Paul kex_cap.bit.sip_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP, 12 * 8, 4 * 8);
273f9af9080SKiran Kumar K /* IP DIP: offset 14B, len 4B */
27473fc72e1SSatheesh Paul kex_cap.bit.dip_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP, 14 * 8, 4 * 8);
275f9af9080SKiran Kumar K /* IP6 SIP: offset 8B, len 16B */
27673fc72e1SSatheesh Paul kex_cap.bit.sip6_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP6, 8 * 8, 16 * 8);
277f9af9080SKiran Kumar K /* IP6 DIP: offset 24B, len 16B */
27873fc72e1SSatheesh Paul kex_cap.bit.dip6_addr = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_IP6, 24 * 8, 16 * 8);
279f9af9080SKiran Kumar K /* ESP SPI: offset 0B, len 4B */
28073fc72e1SSatheesh Paul kex_cap.bit.ipsec_spi = npc_is_kex_enabled(npc, NPC_LID_LE, NPC_LT_LE_ESP, 0 * 8, 4 * 8);
281f9af9080SKiran Kumar K /* VXLAN VNI: offset 4B, len 3B */
28273fc72e1SSatheesh Paul kex_cap.bit.ld_vni = npc_is_kex_enabled(npc, NPC_LID_LE, NPC_LT_LE_VXLAN, 0 * 8, 3 * 8);
283f9af9080SKiran Kumar K
284f9af9080SKiran Kumar K /* Custom L3 frame: varied offset and lengths */
28573fc72e1SSatheesh Paul kex_cap.bit.custom_l3 = npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM0, 0, 0);
28673fc72e1SSatheesh Paul kex_cap.bit.custom_l3 |=
28773fc72e1SSatheesh Paul (uint64_t)npc_is_kex_enabled(npc, NPC_LID_LC, NPC_LT_LC_CUSTOM1, 0, 0);
288f9af9080SKiran Kumar K /* SCTP sport : offset 0B, len 2B */
28973fc72e1SSatheesh Paul kex_cap.bit.sctp_sport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_SCTP, 0 * 8, 2 * 8);
290f9af9080SKiran Kumar K /* SCTP dport : offset 2B, len 2B */
29173fc72e1SSatheesh Paul kex_cap.bit.sctp_dport = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_SCTP, 2 * 8, 2 * 8);
292f9af9080SKiran Kumar K /* ICMP type : offset 0B, len 1B */
29373fc72e1SSatheesh Paul kex_cap.bit.icmp_type = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_ICMP, 0 * 8, 1 * 8);
294f9af9080SKiran Kumar K /* ICMP code : offset 1B, len 1B */
29573fc72e1SSatheesh Paul kex_cap.bit.icmp_code = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_ICMP, 1 * 8, 1 * 8);
296f9af9080SKiran Kumar K /* ICMP id : offset 4B, len 2B */
29773fc72e1SSatheesh Paul kex_cap.bit.icmp_id = npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_ICMP, 4 * 8, 2 * 8);
298f9af9080SKiran Kumar K /* IGMP grp_addr : offset 4B, len 4B */
29973fc72e1SSatheesh Paul kex_cap.bit.igmp_grp_addr =
30073fc72e1SSatheesh Paul npc_is_kex_enabled(npc, NPC_LID_LD, NPC_LT_LD_IGMP, 4 * 8, 4 * 8);
301f9af9080SKiran Kumar K /* GTPU teid : offset 4B, len 4B */
30273fc72e1SSatheesh Paul kex_cap.bit.gtpv1_teid = npc_is_kex_enabled(npc, NPC_LID_LE, NPC_LT_LE_GTPU, 4 * 8, 4 * 8);
303f9af9080SKiran Kumar K return kex_cap.all_bits;
304f9af9080SKiran Kumar K }
305f9af9080SKiran Kumar K
306f9af9080SKiran Kumar K #define BYTESM1_SHIFT 16
307f9af9080SKiran Kumar K #define HDR_OFF_SHIFT 8
308f9af9080SKiran Kumar K static void
npc_update_kex_info(struct npc_xtract_info * xtract_info,uint64_t val)309f9af9080SKiran Kumar K npc_update_kex_info(struct npc_xtract_info *xtract_info, uint64_t val)
310f9af9080SKiran Kumar K {
311e3315630SSatheesh Paul xtract_info->use_hash = ((val >> 20) & 0x1);
312f9af9080SKiran Kumar K xtract_info->len = ((val >> BYTESM1_SHIFT) & 0xf) + 1;
313f9af9080SKiran Kumar K xtract_info->hdr_off = (val >> HDR_OFF_SHIFT) & 0xff;
314f9af9080SKiran Kumar K xtract_info->key_off = val & 0x3f;
315f9af9080SKiran Kumar K xtract_info->enable = ((val >> 7) & 0x1);
316f9af9080SKiran Kumar K xtract_info->flags_enable = ((val >> 6) & 0x1);
317f9af9080SKiran Kumar K }
318f9af9080SKiran Kumar K
319f9af9080SKiran Kumar K int
npc_mcam_alloc_entries(struct mbox * mbox,int ref_mcam,int * alloc_entry,int req_count,int prio,int * resp_count,bool is_conti)320df5cf15fSKiran Kumar K npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int req_count, int prio,
321df5cf15fSKiran Kumar K int *resp_count, bool is_conti)
322f9af9080SKiran Kumar K {
323f9af9080SKiran Kumar K struct npc_mcam_alloc_entry_req *req;
324f9af9080SKiran Kumar K struct npc_mcam_alloc_entry_rsp *rsp;
325f9af9080SKiran Kumar K int rc = -ENOSPC;
326f9af9080SKiran Kumar K int i;
327f9af9080SKiran Kumar K
32844a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox_get(mbox));
329f9af9080SKiran Kumar K if (req == NULL)
33044a9307cSRakesh Kudurumalla goto exit;
331df5cf15fSKiran Kumar K req->contig = is_conti;
332f9af9080SKiran Kumar K req->count = req_count;
333f9af9080SKiran Kumar K req->priority = prio;
334f9af9080SKiran Kumar K req->ref_entry = ref_mcam;
335f9af9080SKiran Kumar K
336f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&rsp);
337f9af9080SKiran Kumar K if (rc)
33844a9307cSRakesh Kudurumalla goto exit;
339f9af9080SKiran Kumar K for (i = 0; i < rsp->count; i++)
340f9af9080SKiran Kumar K alloc_entry[i] = rsp->entry_list[i];
341f9af9080SKiran Kumar K *resp_count = rsp->count;
342df5cf15fSKiran Kumar K if (is_conti)
343df5cf15fSKiran Kumar K alloc_entry[0] = rsp->entry;
34444a9307cSRakesh Kudurumalla rc = 0;
34544a9307cSRakesh Kudurumalla exit:
34644a9307cSRakesh Kudurumalla mbox_put(mbox);
34744a9307cSRakesh Kudurumalla return rc;
348f9af9080SKiran Kumar K }
349f9af9080SKiran Kumar K
350f9af9080SKiran Kumar K int
npc_mcam_alloc_entry(struct npc * npc,struct roc_npc_flow * mcam,struct roc_npc_flow * ref_mcam,int prio,int * resp_count)351*296e9040SKiran Kumar K npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, struct roc_npc_flow *ref_mcam,
352*296e9040SKiran Kumar K int prio, int *resp_count)
353f9af9080SKiran Kumar K {
354f9af9080SKiran Kumar K struct npc_mcam_alloc_entry_req *req;
355f9af9080SKiran Kumar K struct npc_mcam_alloc_entry_rsp *rsp;
35660f0cf50SSatheesh Paul struct mbox *mbox = mbox_get(npc->mbox);
357f9af9080SKiran Kumar K int rc = -ENOSPC;
358f9af9080SKiran Kumar K
35960f0cf50SSatheesh Paul req = mbox_alloc_msg_npc_mcam_alloc_entry(mbox);
360f9af9080SKiran Kumar K if (req == NULL)
36144a9307cSRakesh Kudurumalla goto exit;
362f9af9080SKiran Kumar K req->contig = 1;
363f9af9080SKiran Kumar K req->count = 1;
364f9af9080SKiran Kumar K req->priority = prio;
365f9af9080SKiran Kumar K req->ref_entry = ref_mcam->mcam_id;
366f9af9080SKiran Kumar K
367f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&rsp);
368f9af9080SKiran Kumar K if (rc)
36944a9307cSRakesh Kudurumalla goto exit;
370f9af9080SKiran Kumar K memset(mcam, 0, sizeof(struct roc_npc_flow));
371f9af9080SKiran Kumar K mcam->mcam_id = rsp->entry;
372f9af9080SKiran Kumar K mcam->nix_intf = ref_mcam->nix_intf;
373f9af9080SKiran Kumar K *resp_count = rsp->count;
37444a9307cSRakesh Kudurumalla rc = 0;
37544a9307cSRakesh Kudurumalla exit:
37644a9307cSRakesh Kudurumalla mbox_put(mbox);
37744a9307cSRakesh Kudurumalla return rc;
378f9af9080SKiran Kumar K }
379f9af9080SKiran Kumar K
380f9af9080SKiran Kumar K int
npc_mcam_ena_dis_entry(struct npc * npc,struct roc_npc_flow * mcam,bool enable)381f9af9080SKiran Kumar K npc_mcam_ena_dis_entry(struct npc *npc, struct roc_npc_flow *mcam, bool enable)
382f9af9080SKiran Kumar K {
383f9af9080SKiran Kumar K struct npc_mcam_ena_dis_entry_req *req;
38444a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(npc->mbox);
385f9af9080SKiran Kumar K int rc = -ENOSPC;
386f9af9080SKiran Kumar K
387f9af9080SKiran Kumar K if (enable)
388f9af9080SKiran Kumar K req = mbox_alloc_msg_npc_mcam_ena_entry(mbox);
389f9af9080SKiran Kumar K else
390f9af9080SKiran Kumar K req = mbox_alloc_msg_npc_mcam_dis_entry(mbox);
391f9af9080SKiran Kumar K
392f9af9080SKiran Kumar K if (req == NULL)
39344a9307cSRakesh Kudurumalla goto exit;
394f9af9080SKiran Kumar K req->entry = mcam->mcam_id;
395f9af9080SKiran Kumar K mcam->enable = enable;
39644a9307cSRakesh Kudurumalla rc = mbox_process(mbox);
39744a9307cSRakesh Kudurumalla exit:
39844a9307cSRakesh Kudurumalla mbox_put(mbox);
39944a9307cSRakesh Kudurumalla return rc;
400f9af9080SKiran Kumar K }
401f9af9080SKiran Kumar K
402f9af9080SKiran Kumar K int
npc_mcam_write_entry(struct mbox * mbox,struct roc_npc_flow * mcam)403df5cf15fSKiran Kumar K npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam)
404f9af9080SKiran Kumar K {
405f9af9080SKiran Kumar K struct npc_mcam_write_entry_req *req;
406f9af9080SKiran Kumar K struct mbox_msghdr *rsp;
407f9af9080SKiran Kumar K int rc = -ENOSPC;
40822d9d348SSatheesh Paul uint16_t ctr = 0;
409f9af9080SKiran Kumar K int i;
410f9af9080SKiran Kumar K
41122d9d348SSatheesh Paul if (mcam->use_ctr && mcam->ctr_id == NPC_COUNTER_NONE) {
412df5cf15fSKiran Kumar K rc = npc_mcam_alloc_counter(mbox, &ctr);
41322d9d348SSatheesh Paul if (rc)
414f9af9080SKiran Kumar K return rc;
41522d9d348SSatheesh Paul mcam->ctr_id = ctr;
41622d9d348SSatheesh Paul
417df5cf15fSKiran Kumar K rc = npc_mcam_clear_counter(mbox, mcam->ctr_id);
41822d9d348SSatheesh Paul if (rc)
41922d9d348SSatheesh Paul return rc;
42022d9d348SSatheesh Paul }
42122d9d348SSatheesh Paul
42244a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
42322d9d348SSatheesh Paul if (req == NULL) {
42444a9307cSRakesh Kudurumalla mbox_put(mbox);
42522d9d348SSatheesh Paul if (mcam->use_ctr)
426df5cf15fSKiran Kumar K npc_mcam_free_counter(mbox, ctr);
42722d9d348SSatheesh Paul
42822d9d348SSatheesh Paul return rc;
42922d9d348SSatheesh Paul }
430f9af9080SKiran Kumar K req->entry = mcam->mcam_id;
431f9af9080SKiran Kumar K req->intf = mcam->nix_intf;
432f9af9080SKiran Kumar K req->enable_entry = mcam->enable;
433f9af9080SKiran Kumar K req->entry_data.action = mcam->npc_action;
434f9af9080SKiran Kumar K req->entry_data.vtag_action = mcam->vtag_action;
43522d9d348SSatheesh Paul if (mcam->use_ctr) {
43622d9d348SSatheesh Paul req->set_cntr = 1;
43722d9d348SSatheesh Paul req->cntr = mcam->ctr_id;
43822d9d348SSatheesh Paul }
43922d9d348SSatheesh Paul
440f9af9080SKiran Kumar K for (i = 0; i < NPC_MCAM_KEY_X4_WORDS; i++) {
441f9af9080SKiran Kumar K req->entry_data.kw[i] = mcam->mcam_data[i];
442f9af9080SKiran Kumar K req->entry_data.kw_mask[i] = mcam->mcam_mask[i];
443f9af9080SKiran Kumar K }
44444a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void *)&rsp);
44544a9307cSRakesh Kudurumalla mbox_put(mbox);
44644a9307cSRakesh Kudurumalla return rc;
447f9af9080SKiran Kumar K }
448f9af9080SKiran Kumar K
449f9af9080SKiran Kumar K static void
npc_mcam_process_mkex_cfg(struct npc * npc,struct npc_get_kex_cfg_rsp * kex_rsp)450f9af9080SKiran Kumar K npc_mcam_process_mkex_cfg(struct npc *npc, struct npc_get_kex_cfg_rsp *kex_rsp)
451f9af9080SKiran Kumar K {
452*296e9040SKiran Kumar K volatile uint64_t(*q)[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
453f9af9080SKiran Kumar K struct npc_xtract_info *x_info = NULL;
454f9af9080SKiran Kumar K int lid, lt, ld, fl, ix;
455f9af9080SKiran Kumar K npc_dxcfg_t *p;
456f9af9080SKiran Kumar K uint64_t keyw;
457f9af9080SKiran Kumar K uint64_t val;
458f9af9080SKiran Kumar K
459*296e9040SKiran Kumar K npc->keyx_supp_nmask[NPC_MCAM_RX] = kex_rsp->rx_keyx_cfg & 0x7fffffffULL;
460*296e9040SKiran Kumar K npc->keyx_supp_nmask[NPC_MCAM_TX] = kex_rsp->tx_keyx_cfg & 0x7fffffffULL;
461*296e9040SKiran Kumar K npc->keyx_len[NPC_MCAM_RX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_RX]);
462*296e9040SKiran Kumar K npc->keyx_len[NPC_MCAM_TX] = npc_supp_key_len(npc->keyx_supp_nmask[NPC_MCAM_TX]);
463f9af9080SKiran Kumar K
464f9af9080SKiran Kumar K keyw = (kex_rsp->rx_keyx_cfg >> 32) & 0x7ULL;
465f9af9080SKiran Kumar K npc->keyw[NPC_MCAM_RX] = keyw;
466f9af9080SKiran Kumar K keyw = (kex_rsp->tx_keyx_cfg >> 32) & 0x7ULL;
467f9af9080SKiran Kumar K npc->keyw[NPC_MCAM_TX] = keyw;
468f9af9080SKiran Kumar K
469f9af9080SKiran Kumar K /* Update KEX_LD_FLAG */
470f9af9080SKiran Kumar K for (ix = 0; ix < NPC_MAX_INTF; ix++) {
471f9af9080SKiran Kumar K for (ld = 0; ld < NPC_MAX_LD; ld++) {
472f9af9080SKiran Kumar K for (fl = 0; fl < NPC_MAX_LFL; fl++) {
473f9af9080SKiran Kumar K x_info = &npc->prx_fxcfg[ix][ld][fl].xtract[0];
474f9af9080SKiran Kumar K val = kex_rsp->intf_ld_flags[ix][ld][fl];
475f9af9080SKiran Kumar K npc_update_kex_info(x_info, val);
476f9af9080SKiran Kumar K }
477f9af9080SKiran Kumar K }
478f9af9080SKiran Kumar K }
479f9af9080SKiran Kumar K
480f9af9080SKiran Kumar K /* Update LID, LT and LDATA cfg */
481f9af9080SKiran Kumar K p = &npc->prx_dxcfg;
482*296e9040SKiran Kumar K q = (volatile uint64_t(*)[][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD])(&kex_rsp->intf_lid_lt_ld);
483f9af9080SKiran Kumar K for (ix = 0; ix < NPC_MAX_INTF; ix++) {
484f9af9080SKiran Kumar K for (lid = 0; lid < NPC_MAX_LID; lid++) {
485f9af9080SKiran Kumar K for (lt = 0; lt < NPC_MAX_LT; lt++) {
486f9af9080SKiran Kumar K for (ld = 0; ld < NPC_MAX_LD; ld++) {
487f9af9080SKiran Kumar K x_info = &(*p)[ix][lid][lt].xtract[ld];
488f9af9080SKiran Kumar K val = (*q)[ix][lid][lt][ld];
489f9af9080SKiran Kumar K npc_update_kex_info(x_info, val);
490f9af9080SKiran Kumar K }
491f9af9080SKiran Kumar K }
492f9af9080SKiran Kumar K }
493f9af9080SKiran Kumar K }
494f9af9080SKiran Kumar K /* Update LDATA Flags cfg */
495f9af9080SKiran Kumar K npc->prx_lfcfg[0].i = kex_rsp->kex_ld_flags[0];
496f9af9080SKiran Kumar K npc->prx_lfcfg[1].i = kex_rsp->kex_ld_flags[1];
497f9af9080SKiran Kumar K }
498f9af9080SKiran Kumar K
499f9af9080SKiran Kumar K int
npc_mcam_fetch_hw_cap(struct npc * npc,uint8_t * npc_hw_cap)500e3315630SSatheesh Paul npc_mcam_fetch_hw_cap(struct npc *npc, uint8_t *npc_hw_cap)
501e3315630SSatheesh Paul {
502e3315630SSatheesh Paul struct get_hw_cap_rsp *hw_cap_rsp;
503e3315630SSatheesh Paul struct mbox *mbox = mbox_get(npc->mbox);
504e3315630SSatheesh Paul int rc = 0;
505e3315630SSatheesh Paul
506e3315630SSatheesh Paul *npc_hw_cap = 0;
507e3315630SSatheesh Paul
508e3315630SSatheesh Paul mbox_alloc_msg_get_hw_cap(mbox);
509e3315630SSatheesh Paul rc = mbox_process_msg(mbox, (void *)&hw_cap_rsp);
510e3315630SSatheesh Paul if (rc) {
511e3315630SSatheesh Paul plt_err("Failed to fetch NPC HW capability");
512e3315630SSatheesh Paul goto done;
513e3315630SSatheesh Paul }
514e3315630SSatheesh Paul
515e3315630SSatheesh Paul *npc_hw_cap = hw_cap_rsp->npc_hash_extract;
516e3315630SSatheesh Paul done:
517e3315630SSatheesh Paul mbox_put(mbox);
518e3315630SSatheesh Paul return rc;
519e3315630SSatheesh Paul }
520e3315630SSatheesh Paul
521e3315630SSatheesh Paul int
npc_mcam_fetch_kex_cfg(struct npc * npc)522f9af9080SKiran Kumar K npc_mcam_fetch_kex_cfg(struct npc *npc)
523f9af9080SKiran Kumar K {
524f9af9080SKiran Kumar K struct npc_get_kex_cfg_rsp *kex_rsp;
52544a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(npc->mbox);
526f9af9080SKiran Kumar K int rc = 0;
527f9af9080SKiran Kumar K
528f9af9080SKiran Kumar K mbox_alloc_msg_npc_get_kex_cfg(mbox);
529f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&kex_rsp);
530f9af9080SKiran Kumar K if (rc) {
531f9af9080SKiran Kumar K plt_err("Failed to fetch NPC KEX config");
532f9af9080SKiran Kumar K goto done;
533f9af9080SKiran Kumar K }
534f9af9080SKiran Kumar K
535*296e9040SKiran Kumar K mbox_memcpy((char *)npc->profile_name, kex_rsp->mkex_pfl_name, MKEX_NAME_LEN);
536f9af9080SKiran Kumar K
537a9064972SNithin Dabilpuram npc->exact_match_ena = (kex_rsp->rx_keyx_cfg >> 40) & 0xF;
538f9af9080SKiran Kumar K npc_mcam_process_mkex_cfg(npc, kex_rsp);
539f9af9080SKiran Kumar K
540f9af9080SKiran Kumar K done:
54144a9307cSRakesh Kudurumalla mbox_put(mbox);
542f9af9080SKiran Kumar K return rc;
543f9af9080SKiran Kumar K }
544f9af9080SKiran Kumar K
5454968b362SSatheesh Paul static void
npc_mcam_set_channel(struct roc_npc_flow * flow,struct npc_mcam_write_entry_req * req,uint16_t channel,uint16_t chan_mask,bool is_second_pass)546*296e9040SKiran Kumar K npc_mcam_set_channel(struct roc_npc_flow *flow, struct npc_mcam_write_entry_req *req,
547*296e9040SKiran Kumar K uint16_t channel, uint16_t chan_mask, bool is_second_pass)
5484968b362SSatheesh Paul {
5494968b362SSatheesh Paul uint16_t chan = 0, mask = 0;
5504968b362SSatheesh Paul
5514968b362SSatheesh Paul req->entry_data.kw[0] &= ~(GENMASK(11, 0));
5524968b362SSatheesh Paul req->entry_data.kw_mask[0] &= ~(GENMASK(11, 0));
5534968b362SSatheesh Paul flow->mcam_data[0] &= ~(GENMASK(11, 0));
5544968b362SSatheesh Paul flow->mcam_mask[0] &= ~(GENMASK(11, 0));
55567069219SSatheesh Paul chan = channel;
55667069219SSatheesh Paul mask = chan_mask;
5574968b362SSatheesh Paul
55867069219SSatheesh Paul if (roc_model_runtime_is_cn10k()) {
5594968b362SSatheesh Paul if (is_second_pass) {
5604968b362SSatheesh Paul chan = (channel | NIX_CHAN_CPT_CH_START);
5614968b362SSatheesh Paul mask = (chan_mask | NIX_CHAN_CPT_CH_START);
5624968b362SSatheesh Paul } else {
56367069219SSatheesh Paul if (!(flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC)) {
5644968b362SSatheesh Paul /*
5654968b362SSatheesh Paul * Clear bits 10 & 11 corresponding to CPT
5664968b362SSatheesh Paul * channel. By default, rules should match
5674968b362SSatheesh Paul * both first pass packets and second pass
5684968b362SSatheesh Paul * packets from CPT.
5694968b362SSatheesh Paul */
5704968b362SSatheesh Paul chan = (channel & NIX_CHAN_CPT_X2P_MASK);
5714968b362SSatheesh Paul mask = (chan_mask & NIX_CHAN_CPT_X2P_MASK);
5724968b362SSatheesh Paul }
57367069219SSatheesh Paul }
57467069219SSatheesh Paul }
5754968b362SSatheesh Paul
5764968b362SSatheesh Paul req->entry_data.kw[0] |= (uint64_t)chan;
5774968b362SSatheesh Paul req->entry_data.kw_mask[0] |= (uint64_t)mask;
5784968b362SSatheesh Paul flow->mcam_data[0] |= (uint64_t)chan;
5794968b362SSatheesh Paul flow->mcam_mask[0] |= (uint64_t)mask;
5804968b362SSatheesh Paul }
5814968b362SSatheesh Paul
582b7fff4e4SSatheesh Paul static int
npc_mcam_set_pf_func(struct npc * npc,struct roc_npc_flow * flow,uint16_t pf_func)583b7fff4e4SSatheesh Paul npc_mcam_set_pf_func(struct npc *npc, struct roc_npc_flow *flow, uint16_t pf_func)
584b7fff4e4SSatheesh Paul {
585b7fff4e4SSatheesh Paul #define NPC_PF_FUNC_WIDTH 2
586b7fff4e4SSatheesh Paul #define NPC_KEX_PF_FUNC_MASK 0xFFFF
587b7fff4e4SSatheesh Paul uint16_t nr_bytes, hdr_offset, key_offset, pf_func_offset;
588b7fff4e4SSatheesh Paul uint8_t *flow_mcam_data, *flow_mcam_mask;
589b7fff4e4SSatheesh Paul struct npc_lid_lt_xtract_info *xinfo;
590b7fff4e4SSatheesh Paul bool pffunc_found = false;
591b7fff4e4SSatheesh Paul uint16_t mask = 0xFFFF;
592b7fff4e4SSatheesh Paul int i;
593b7fff4e4SSatheesh Paul
594b7fff4e4SSatheesh Paul flow_mcam_data = (uint8_t *)flow->mcam_data;
595b7fff4e4SSatheesh Paul flow_mcam_mask = (uint8_t *)flow->mcam_mask;
596b7fff4e4SSatheesh Paul
597b7fff4e4SSatheesh Paul xinfo = &npc->prx_dxcfg[NIX_INTF_TX][NPC_LID_LA][NPC_LT_LA_IH_NIX_ETHER];
598b7fff4e4SSatheesh Paul
599b7fff4e4SSatheesh Paul for (i = 0; i < NPC_MAX_LD; i++) {
600b7fff4e4SSatheesh Paul nr_bytes = xinfo->xtract[i].len;
601b7fff4e4SSatheesh Paul hdr_offset = xinfo->xtract[i].hdr_off;
602b7fff4e4SSatheesh Paul key_offset = xinfo->xtract[i].key_off;
603b7fff4e4SSatheesh Paul
604b7fff4e4SSatheesh Paul if (hdr_offset > 0 || nr_bytes < NPC_PF_FUNC_WIDTH)
605b7fff4e4SSatheesh Paul continue;
606b7fff4e4SSatheesh Paul else
607b7fff4e4SSatheesh Paul pffunc_found = true;
608b7fff4e4SSatheesh Paul
609b7fff4e4SSatheesh Paul pf_func_offset = key_offset + nr_bytes - NPC_PF_FUNC_WIDTH;
610b7fff4e4SSatheesh Paul memcpy((void *)&flow_mcam_data[pf_func_offset], (uint8_t *)&pf_func,
611b7fff4e4SSatheesh Paul NPC_PF_FUNC_WIDTH);
612b7fff4e4SSatheesh Paul memcpy((void *)&flow_mcam_mask[pf_func_offset], (uint8_t *)&mask,
613b7fff4e4SSatheesh Paul NPC_PF_FUNC_WIDTH);
614b7fff4e4SSatheesh Paul }
615b7fff4e4SSatheesh Paul if (!pffunc_found)
616b7fff4e4SSatheesh Paul return -EINVAL;
617b7fff4e4SSatheesh Paul
618b7fff4e4SSatheesh Paul return 0;
619b7fff4e4SSatheesh Paul }
620b7fff4e4SSatheesh Paul
621f9af9080SKiran Kumar K int
npc_mcam_alloc_and_write(struct npc * npc,struct roc_npc_flow * flow,struct npc_parse_state * pst)622b7fff4e4SSatheesh Paul npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_parse_state *pst)
623f9af9080SKiran Kumar K {
624f9af9080SKiran Kumar K struct npc_mcam_write_entry_req *req;
62557f7b982SSatheesh Paul struct nix_inl_dev *inl_dev = NULL;
626f9af9080SKiran Kumar K struct mbox *mbox = npc->mbox;
627f9af9080SKiran Kumar K struct mbox_msghdr *rsp;
62857f7b982SSatheesh Paul struct idev_cfg *idev;
62957f7b982SSatheesh Paul uint16_t pf_func = 0;
630f9af9080SKiran Kumar K uint16_t ctr = ~(0);
63178c78d87SKiran Kumar K uint32_t la_offset;
63278c78d87SKiran Kumar K uint64_t mask;
633f9af9080SKiran Kumar K int rc, idx;
634f9af9080SKiran Kumar K int entry;
635f9af9080SKiran Kumar K
636f9af9080SKiran Kumar K PLT_SET_USED(pst);
637f9af9080SKiran Kumar K
638df5cf15fSKiran Kumar K idev = idev_get_cfg();
639df5cf15fSKiran Kumar K if (idev)
640df5cf15fSKiran Kumar K inl_dev = idev->nix_inl_dev;
641df5cf15fSKiran Kumar K
642df5cf15fSKiran Kumar K if (inl_dev && inl_dev->ipsec_index) {
643df5cf15fSKiran Kumar K if (flow->is_inline_dev)
644df5cf15fSKiran Kumar K mbox = inl_dev->dev.mbox;
645df5cf15fSKiran Kumar K }
646df5cf15fSKiran Kumar K
64722d9d348SSatheesh Paul if (flow->use_ctr) {
648df5cf15fSKiran Kumar K rc = npc_mcam_alloc_counter(mbox, &ctr);
649f9af9080SKiran Kumar K if (rc)
650f9af9080SKiran Kumar K return rc;
65122d9d348SSatheesh Paul
65222d9d348SSatheesh Paul flow->ctr_id = ctr;
653df5cf15fSKiran Kumar K rc = npc_mcam_clear_counter(mbox, flow->ctr_id);
65422d9d348SSatheesh Paul if (rc)
65522d9d348SSatheesh Paul return rc;
656f9af9080SKiran Kumar K }
657f9af9080SKiran Kumar K
658df5cf15fSKiran Kumar K if (flow->nix_intf == NIX_INTF_RX && flow->is_inline_dev && inl_dev &&
659df5cf15fSKiran Kumar K inl_dev->ipsec_index && inl_dev->is_multi_channel) {
660df5cf15fSKiran Kumar K if (inl_dev->curr_ipsec_idx >= inl_dev->alloc_ipsec_rules)
661df5cf15fSKiran Kumar K return NPC_ERR_MCAM_ALLOC;
662df5cf15fSKiran Kumar K entry = inl_dev->ipsec_index[inl_dev->curr_ipsec_idx];
663df5cf15fSKiran Kumar K inl_dev->curr_ipsec_idx++;
664df5cf15fSKiran Kumar K flow->use_pre_alloc = 1;
665df5cf15fSKiran Kumar K } else {
6661f669198SSatheesh Paul entry = npc_get_free_mcam_entry(mbox, flow, npc);
667f9af9080SKiran Kumar K if (entry < 0) {
66822d9d348SSatheesh Paul if (flow->use_ctr)
669df5cf15fSKiran Kumar K npc_mcam_free_counter(mbox, ctr);
670f9af9080SKiran Kumar K return NPC_ERR_MCAM_ALLOC;
671f9af9080SKiran Kumar K }
672df5cf15fSKiran Kumar K }
673f9af9080SKiran Kumar K
674209188d1SSatheesh Paul if (flow->nix_intf == NIX_INTF_TX) {
675*296e9040SKiran Kumar K uint16_t pf_func = flow->tx_pf_func;
676*296e9040SKiran Kumar K
677*296e9040SKiran Kumar K if (flow->has_rep)
678*296e9040SKiran Kumar K pf_func = flow->rep_pf_func;
679209188d1SSatheesh Paul
680209188d1SSatheesh Paul pf_func = plt_cpu_to_be_16(pf_func);
681209188d1SSatheesh Paul
682209188d1SSatheesh Paul rc = npc_mcam_set_pf_func(npc, flow, pf_func);
683209188d1SSatheesh Paul if (rc)
684209188d1SSatheesh Paul return rc;
685209188d1SSatheesh Paul }
686209188d1SSatheesh Paul
687209188d1SSatheesh Paul if (flow->is_sampling_rule) {
688209188d1SSatheesh Paul /* Save and restore any mark value set */
689209188d1SSatheesh Paul uint16_t mark = (flow->npc_action >> 40) & 0xffff;
690209188d1SSatheesh Paul uint16_t mce_index = 0;
691209188d1SSatheesh Paul uint32_t rqs[2] = {};
692209188d1SSatheesh Paul
693209188d1SSatheesh Paul rqs[1] = flow->recv_queue;
694209188d1SSatheesh Paul rc = roc_nix_mcast_list_setup(npc->mbox, flow->nix_intf, 2, flow->mcast_pf_funcs,
695209188d1SSatheesh Paul flow->mcast_channels, rqs, &flow->mcast_grp_index,
696209188d1SSatheesh Paul &flow->mce_start_index);
697209188d1SSatheesh Paul if (rc)
698209188d1SSatheesh Paul return rc;
699209188d1SSatheesh Paul
700209188d1SSatheesh Paul flow->npc_action = NIX_RX_ACTIONOP_MCAST;
701209188d1SSatheesh Paul mce_index = flow->mce_start_index;
702209188d1SSatheesh Paul if (flow->nix_intf == NIX_INTF_TX) {
703209188d1SSatheesh Paul flow->npc_action |= (uint64_t)mce_index << 12;
704209188d1SSatheesh Paul flow->npc_action |= (uint64_t)mark << 32;
705209188d1SSatheesh Paul } else {
706209188d1SSatheesh Paul flow->npc_action |= (uint64_t)mce_index << 20;
707209188d1SSatheesh Paul flow->npc_action |= (uint64_t)mark << 40;
708209188d1SSatheesh Paul }
709209188d1SSatheesh Paul }
710209188d1SSatheesh Paul
71144a9307cSRakesh Kudurumalla req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox));
71244a9307cSRakesh Kudurumalla if (req == NULL) {
71344a9307cSRakesh Kudurumalla rc = -ENOSPC;
71444a9307cSRakesh Kudurumalla goto exit;
71544a9307cSRakesh Kudurumalla }
71622d9d348SSatheesh Paul req->set_cntr = flow->use_ctr;
71722d9d348SSatheesh Paul req->cntr = flow->ctr_id;
718f9af9080SKiran Kumar K req->entry = entry;
719f9af9080SKiran Kumar K
720f9af9080SKiran Kumar K req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX;
721f9af9080SKiran Kumar K req->enable_entry = 1;
722209188d1SSatheesh Paul if (flow->nix_intf == NIX_INTF_RX)
723209188d1SSatheesh Paul flow->npc_action |= (uint64_t)flow->recv_queue << 20;
724f9af9080SKiran Kumar K req->entry_data.action = flow->npc_action;
725f9af9080SKiran Kumar K
726f9af9080SKiran Kumar K /*
727f9af9080SKiran Kumar K * Driver sets vtag action on per interface basis, not
728f9af9080SKiran Kumar K * per flow basis. It is a matter of how we decide to support
729f9af9080SKiran Kumar K * this pmd specific behavior. There are two ways:
730f9af9080SKiran Kumar K * 1. Inherit the vtag action from the one configured
731f9af9080SKiran Kumar K * for this interface. This can be read from the
732f9af9080SKiran Kumar K * vtag_action configured for default mcam entry of
733f9af9080SKiran Kumar K * this pf_func.
734f9af9080SKiran Kumar K * 2. Do not support vtag action with npc_flow.
735f9af9080SKiran Kumar K *
736f9af9080SKiran Kumar K * Second approach is used now.
737f9af9080SKiran Kumar K */
73819f3cc23SSatheesh Paul req->entry_data.vtag_action = flow->vtag_action;
739f9af9080SKiran Kumar K
740f9af9080SKiran Kumar K for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
741f9af9080SKiran Kumar K req->entry_data.kw[idx] = flow->mcam_data[idx];
742f9af9080SKiran Kumar K req->entry_data.kw_mask[idx] = flow->mcam_mask[idx];
743f9af9080SKiran Kumar K }
744f9af9080SKiran Kumar K
745f9af9080SKiran Kumar K if (flow->nix_intf == NIX_INTF_RX) {
74657f7b982SSatheesh Paul if (inl_dev && inl_dev->is_multi_channel &&
74757f7b982SSatheesh Paul (flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC)) {
74857f7b982SSatheesh Paul pf_func = nix_inl_dev_pffunc_get();
74957f7b982SSatheesh Paul req->entry_data.action &= ~(GENMASK(19, 4));
75057f7b982SSatheesh Paul req->entry_data.action |= (uint64_t)pf_func << 4;
75157f7b982SSatheesh Paul flow->npc_action &= ~(GENMASK(19, 4));
75257f7b982SSatheesh Paul flow->npc_action |= (uint64_t)pf_func << 4;
7534968b362SSatheesh Paul
75478c78d87SKiran Kumar K npc_mcam_set_channel(flow, req, inl_dev->channel, inl_dev->chan_mask,
75578c78d87SKiran Kumar K false);
756*296e9040SKiran Kumar K } else if (flow->has_rep) {
757*296e9040SKiran Kumar K pf_func = (flow->rep_act_pf_func == 0) ? flow->rep_pf_func :
758*296e9040SKiran Kumar K flow->rep_act_pf_func;
759*296e9040SKiran Kumar K req->entry_data.action &= ~(GENMASK(19, 4));
760*296e9040SKiran Kumar K req->entry_data.action |= (uint64_t)pf_func << 4;
761*296e9040SKiran Kumar K flow->npc_action &= ~(GENMASK(19, 4));
762*296e9040SKiran Kumar K flow->npc_action |= (uint64_t)pf_func << 4;
763*296e9040SKiran Kumar K npc_mcam_set_channel(flow, req, flow->rep_channel, (BIT_ULL(12) - 1),
764*296e9040SKiran Kumar K false);
765f1375663SSatheesh Paul } else if (npc->is_sdp_link) {
76678c78d87SKiran Kumar K npc_mcam_set_channel(flow, req, npc->sdp_channel, npc->sdp_channel_mask,
7674968b362SSatheesh Paul pst->is_second_pass_rule);
76857f7b982SSatheesh Paul } else {
76978c78d87SKiran Kumar K npc_mcam_set_channel(flow, req, npc->channel, (BIT_ULL(12) - 1),
7704968b362SSatheesh Paul pst->is_second_pass_rule);
77157f7b982SSatheesh Paul }
772a0c837adSSatheesh Paul /*
773a0c837adSSatheesh Paul * For second pass rule, set LA LTYPE to CPT_HDR.
774a0c837adSSatheesh Paul * For all other rules, set LA LTYPE to match both 1st pass and 2nd pass ltypes.
775a0c837adSSatheesh Paul */
776a0c837adSSatheesh Paul if (pst->is_second_pass_rule || (!pst->is_second_pass_rule && pst->has_eth_type)) {
777354bf671SJerin Jacob la_offset = plt_popcount32(npc->keyx_supp_nmask[flow->nix_intf] &
77878c78d87SKiran Kumar K ((1ULL << 9 /* LA offset */) - 1));
77978c78d87SKiran Kumar K la_offset *= 4;
78078c78d87SKiran Kumar K
78178c78d87SKiran Kumar K mask = ~((0xfULL << la_offset));
78278c78d87SKiran Kumar K req->entry_data.kw[0] &= mask;
78378c78d87SKiran Kumar K req->entry_data.kw_mask[0] &= mask;
78478c78d87SKiran Kumar K flow->mcam_data[0] &= mask;
78578c78d87SKiran Kumar K flow->mcam_mask[0] &= mask;
786a0c837adSSatheesh Paul if (pst->is_second_pass_rule) {
787a0c837adSSatheesh Paul req->entry_data.kw[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
788a0c837adSSatheesh Paul req->entry_data.kw_mask[0] |= (0xFULL << la_offset);
789a0c837adSSatheesh Paul flow->mcam_data[0] |= ((uint64_t)NPC_LT_LA_CPT_HDR) << la_offset;
790a0c837adSSatheesh Paul flow->mcam_mask[0] |= (0xFULL << la_offset);
791a0c837adSSatheesh Paul } else {
792a0c837adSSatheesh Paul /* Mask ltype ETHER (0x2) and CPT_HDR (0xa) */
793a0c837adSSatheesh Paul req->entry_data.kw[0] |= (0x2ULL << la_offset);
794a0c837adSSatheesh Paul req->entry_data.kw_mask[0] |= (0x7ULL << la_offset);
79578c78d87SKiran Kumar K flow->mcam_data[0] |= (0x2ULL << la_offset);
79678c78d87SKiran Kumar K flow->mcam_mask[0] |= (0x7ULL << la_offset);
79778c78d87SKiran Kumar K }
798a0c837adSSatheesh Paul }
799f9af9080SKiran Kumar K }
800f9af9080SKiran Kumar K
801f9af9080SKiran Kumar K rc = mbox_process_msg(mbox, (void *)&rsp);
802f9af9080SKiran Kumar K if (rc != 0)
80344a9307cSRakesh Kudurumalla goto exit;
804f9af9080SKiran Kumar K
805f9af9080SKiran Kumar K flow->mcam_id = entry;
8061f669198SSatheesh Paul
80722d9d348SSatheesh Paul if (flow->use_ctr)
808f9af9080SKiran Kumar K flow->ctr_id = ctr;
80944a9307cSRakesh Kudurumalla rc = 0;
810209188d1SSatheesh Paul
81144a9307cSRakesh Kudurumalla exit:
81244a9307cSRakesh Kudurumalla mbox_put(mbox);
813209188d1SSatheesh Paul if (rc)
814209188d1SSatheesh Paul roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index);
81544a9307cSRakesh Kudurumalla return rc;
816f9af9080SKiran Kumar K }
817f9af9080SKiran Kumar K
818b8ac8b08SSatheesh Paul static void
npc_set_vlan_ltype(struct npc_parse_state * pst)819b8ac8b08SSatheesh Paul npc_set_vlan_ltype(struct npc_parse_state *pst)
820b8ac8b08SSatheesh Paul {
821b8ac8b08SSatheesh Paul uint64_t val, mask;
822b8ac8b08SSatheesh Paul uint8_t lb_offset;
823b8ac8b08SSatheesh Paul
824b8ac8b08SSatheesh Paul lb_offset =
825354bf671SJerin Jacob plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
826b8ac8b08SSatheesh Paul ((1ULL << NPC_LTYPE_LB_OFFSET) - 1));
827b8ac8b08SSatheesh Paul lb_offset *= 4;
828b8ac8b08SSatheesh Paul
829b8ac8b08SSatheesh Paul mask = ~((0xfULL << lb_offset));
830b8ac8b08SSatheesh Paul pst->flow->mcam_data[0] &= mask;
831b8ac8b08SSatheesh Paul pst->flow->mcam_mask[0] &= mask;
832b8ac8b08SSatheesh Paul /* NPC_LT_LB_CTAG: 0b0010, NPC_LT_LB_STAG_QINQ: 0b0011
833b8ac8b08SSatheesh Paul * Set LB layertype/mask as 0b0010/0b1110 to match both.
834b8ac8b08SSatheesh Paul */
835b8ac8b08SSatheesh Paul val = ((uint64_t)(NPC_LT_LB_CTAG & NPC_LT_LB_STAG_QINQ)) << lb_offset;
836b8ac8b08SSatheesh Paul pst->flow->mcam_data[0] |= val;
837b8ac8b08SSatheesh Paul pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
838b8ac8b08SSatheesh Paul }
839b8ac8b08SSatheesh Paul
840474e275bSSatheesh Paul static void
npc_set_ipv6ext_ltype_mask(struct npc_parse_state * pst)841474e275bSSatheesh Paul npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
842474e275bSSatheesh Paul {
843474e275bSSatheesh Paul uint8_t lc_offset, lcflag_offset;
844474e275bSSatheesh Paul uint64_t val, mask;
845474e275bSSatheesh Paul
846474e275bSSatheesh Paul lc_offset =
847354bf671SJerin Jacob plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
848474e275bSSatheesh Paul ((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
849474e275bSSatheesh Paul lc_offset *= 4;
850474e275bSSatheesh Paul
851474e275bSSatheesh Paul mask = ~((0xfULL << lc_offset));
852474e275bSSatheesh Paul pst->flow->mcam_data[0] &= mask;
853474e275bSSatheesh Paul pst->flow->mcam_mask[0] &= mask;
854474e275bSSatheesh Paul /* NPC_LT_LC_IP6: 0b0100, NPC_LT_LC_IP6_EXT: 0b0101
855474e275bSSatheesh Paul * Set LC layertype/mask as 0b0100/0b1110 to match both.
856474e275bSSatheesh Paul */
857474e275bSSatheesh Paul val = ((uint64_t)(NPC_LT_LC_IP6 & NPC_LT_LC_IP6_EXT)) << lc_offset;
858474e275bSSatheesh Paul pst->flow->mcam_data[0] |= val;
859474e275bSSatheesh Paul pst->flow->mcam_mask[0] |= (0xeULL << lc_offset);
860474e275bSSatheesh Paul
861474e275bSSatheesh Paul /* If LC LFLAG is non-zero, set the LC LFLAG mask to 0xF. In general
862474e275bSSatheesh Paul * case flag mask is set same as the value in data. For example, to
863474e275bSSatheesh Paul * match 3 VLANs, flags have to match a range of values. But, for IPv6
864474e275bSSatheesh Paul * extended attributes matching, we need an exact match. Hence, set the
865474e275bSSatheesh Paul * mask as 0xF. This is done only if LC LFLAG value is non-zero,
866474e275bSSatheesh Paul * because for AH and ESP, LC LFLAG is zero and we don't want to match
867474e275bSSatheesh Paul * zero in LFLAG.
868474e275bSSatheesh Paul */
869a9b37decSKiran Kumar K if (pst->npc->keyx_supp_nmask[pst->nix_intf] & (1ULL << NPC_LFLAG_LC_OFFSET)) {
870354bf671SJerin Jacob lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] &
871474e275bSSatheesh Paul ((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
872474e275bSSatheesh Paul lcflag_offset *= 4;
873474e275bSSatheesh Paul
874474e275bSSatheesh Paul mask = (0xfULL << lcflag_offset);
875474e275bSSatheesh Paul val = pst->flow->mcam_data[0] & mask;
876474e275bSSatheesh Paul if (val)
877474e275bSSatheesh Paul pst->flow->mcam_mask[0] |= mask;
878474e275bSSatheesh Paul }
879a9b37decSKiran Kumar K }
880474e275bSSatheesh Paul
881f9af9080SKiran Kumar K int
npc_program_mcam(struct npc * npc,struct npc_parse_state * pst,bool mcam_alloc)882f9af9080SKiran Kumar K npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
883f9af9080SKiran Kumar K {
884f9af9080SKiran Kumar K struct npc_mcam_read_base_rule_rsp *base_rule_rsp;
885f9af9080SKiran Kumar K /* This is non-LDATA part in search key */
886f9af9080SKiran Kumar K uint64_t key_data[2] = {0ULL, 0ULL};
887f9af9080SKiran Kumar K uint64_t key_mask[2] = {0ULL, 0ULL};
888f9af9080SKiran Kumar K int key_len, bit = 0, index, rc = 0;
889e5d0e3c7SKiran Kumar K struct nix_inl_dev *inl_dev = NULL;
890f9af9080SKiran Kumar K int intf = pst->flow->nix_intf;
891f9af9080SKiran Kumar K struct mcam_entry *base_entry;
892e5d0e3c7SKiran Kumar K bool skip_base_rule = false;
893f9af9080SKiran Kumar K int off, idx, data_off = 0;
894f9af9080SKiran Kumar K uint8_t lid, mask, data;
895e5d0e3c7SKiran Kumar K struct idev_cfg *idev;
896f9af9080SKiran Kumar K uint16_t layer_info;
897f9af9080SKiran Kumar K uint64_t lt, flags;
89844a9307cSRakesh Kudurumalla struct mbox *mbox;
899f9af9080SKiran Kumar K
900f9af9080SKiran Kumar K /* Skip till Layer A data start */
901f9af9080SKiran Kumar K while (bit < NPC_PARSE_KEX_S_LA_OFFSET) {
902f9af9080SKiran Kumar K if (npc->keyx_supp_nmask[intf] & (1 << bit))
903f9af9080SKiran Kumar K data_off++;
904f9af9080SKiran Kumar K bit++;
905f9af9080SKiran Kumar K }
906f9af9080SKiran Kumar K
907f9af9080SKiran Kumar K /* Each bit represents 1 nibble */
908f9af9080SKiran Kumar K data_off *= 4;
909f9af9080SKiran Kumar K
910f9af9080SKiran Kumar K index = 0;
911f9af9080SKiran Kumar K for (lid = 0; lid < NPC_MAX_LID; lid++) {
912f9af9080SKiran Kumar K /* Offset in key */
913f9af9080SKiran Kumar K off = NPC_PARSE_KEX_S_LID_OFFSET(lid);
914f9af9080SKiran Kumar K lt = pst->lt[lid] & 0xf;
915f9af9080SKiran Kumar K flags = pst->flags[lid] & 0xff;
916f9af9080SKiran Kumar K
917f9af9080SKiran Kumar K /* NPC_LAYER_KEX_S */
918f9af9080SKiran Kumar K layer_info = ((npc->keyx_supp_nmask[intf] >> off) & 0x7);
919f9af9080SKiran Kumar K
920f9af9080SKiran Kumar K if (layer_info) {
921f9af9080SKiran Kumar K for (idx = 0; idx <= 2; idx++) {
922f9af9080SKiran Kumar K if (layer_info & (1 << idx)) {
923b8ac8b08SSatheesh Paul if (idx == 2) {
924f9af9080SKiran Kumar K data = lt;
925b8ac8b08SSatheesh Paul mask = 0xf;
926b8ac8b08SSatheesh Paul } else if (idx == 1) {
927f9af9080SKiran Kumar K data = ((flags >> 4) & 0xf);
928b8ac8b08SSatheesh Paul mask = ((flags >> 4) & 0xf);
929b8ac8b08SSatheesh Paul } else {
930f9af9080SKiran Kumar K data = (flags & 0xf);
931b8ac8b08SSatheesh Paul mask = (flags & 0xf);
932b8ac8b08SSatheesh Paul }
933f9af9080SKiran Kumar K
934f9af9080SKiran Kumar K if (data_off >= 64) {
935f9af9080SKiran Kumar K data_off = 0;
936f9af9080SKiran Kumar K index++;
937f9af9080SKiran Kumar K }
938*296e9040SKiran Kumar K key_data[index] |= ((uint64_t)data << data_off);
939b8ac8b08SSatheesh Paul
940f9af9080SKiran Kumar K if (lt == 0)
941f9af9080SKiran Kumar K mask = 0;
942*296e9040SKiran Kumar K key_mask[index] |= ((uint64_t)mask << data_off);
943f9af9080SKiran Kumar K data_off += 4;
944f9af9080SKiran Kumar K }
945f9af9080SKiran Kumar K }
946f9af9080SKiran Kumar K }
947f9af9080SKiran Kumar K }
948f9af9080SKiran Kumar K
949f9af9080SKiran Kumar K /* Copy this into mcam string */
950f9af9080SKiran Kumar K key_len = (pst->npc->keyx_len[intf] + 7) / 8;
951f9af9080SKiran Kumar K memcpy(pst->flow->mcam_data, key_data, key_len);
952f9af9080SKiran Kumar K memcpy(pst->flow->mcam_mask, key_mask, key_len);
953f9af9080SKiran Kumar K
954b8ac8b08SSatheesh Paul if (pst->set_vlan_ltype_mask)
955b8ac8b08SSatheesh Paul npc_set_vlan_ltype(pst);
956b8ac8b08SSatheesh Paul
957474e275bSSatheesh Paul if (pst->set_ipv6ext_ltype_mask)
958474e275bSSatheesh Paul npc_set_ipv6ext_ltype_mask(pst);
959474e275bSSatheesh Paul
960e5d0e3c7SKiran Kumar K idev = idev_get_cfg();
961e5d0e3c7SKiran Kumar K if (idev)
962e5d0e3c7SKiran Kumar K inl_dev = idev->nix_inl_dev;
963e5d0e3c7SKiran Kumar K if (inl_dev && inl_dev->is_multi_channel &&
964e5d0e3c7SKiran Kumar K (pst->flow->npc_action & NIX_RX_ACTIONOP_UCAST_IPSEC))
965e5d0e3c7SKiran Kumar K skip_base_rule = true;
966e5d0e3c7SKiran Kumar K
967*296e9040SKiran Kumar K if ((pst->is_vf || pst->flow->is_rep_vf) && pst->flow->nix_intf == NIX_INTF_RX &&
968*296e9040SKiran Kumar K !skip_base_rule) {
969*296e9040SKiran Kumar K if (pst->flow->has_rep)
970*296e9040SKiran Kumar K mbox = mbox_get(pst->flow->rep_mbox);
971*296e9040SKiran Kumar K else
97244a9307cSRakesh Kudurumalla mbox = mbox_get(npc->mbox);
97344a9307cSRakesh Kudurumalla (void)mbox_alloc_msg_npc_read_base_steer_rule(mbox);
97444a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void *)&base_rule_rsp);
975f9af9080SKiran Kumar K if (rc) {
97644a9307cSRakesh Kudurumalla mbox_put(mbox);
977f9af9080SKiran Kumar K plt_err("Failed to fetch VF's base MCAM entry");
978f9af9080SKiran Kumar K return rc;
979f9af9080SKiran Kumar K }
98044a9307cSRakesh Kudurumalla mbox_put(mbox);
981f9af9080SKiran Kumar K base_entry = &base_rule_rsp->entry_data;
982f9af9080SKiran Kumar K for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) {
983f9af9080SKiran Kumar K pst->flow->mcam_data[idx] |= base_entry->kw[idx];
984f9af9080SKiran Kumar K pst->flow->mcam_mask[idx] |= base_entry->kw_mask[idx];
985f9af9080SKiran Kumar K }
986f9af9080SKiran Kumar K }
987f9af9080SKiran Kumar K
988f9af9080SKiran Kumar K /*
989f9af9080SKiran Kumar K * Now we have mcam data and mask formatted as
990f9af9080SKiran Kumar K * [Key_len/4 nibbles][0 or 1 nibble hole][data]
991f9af9080SKiran Kumar K * hole is present if key_len is odd number of nibbles.
992f9af9080SKiran Kumar K * mcam data must be split into 64 bits + 48 bits segments
993f9af9080SKiran Kumar K * for each back W0, W1.
994f9af9080SKiran Kumar K */
995f9af9080SKiran Kumar K
996f9af9080SKiran Kumar K if (mcam_alloc)
997f9af9080SKiran Kumar K return npc_mcam_alloc_and_write(npc, pst->flow, pst);
998f9af9080SKiran Kumar K else
999f9af9080SKiran Kumar K return 0;
1000f9af9080SKiran Kumar K }
1001f9af9080SKiran Kumar K
1002f9af9080SKiran Kumar K int
npc_flow_enable_all_entries(struct npc * npc,bool enable)1003fbc0fa74SKiran Kumar K npc_flow_enable_all_entries(struct npc *npc, bool enable)
1004fbc0fa74SKiran Kumar K {
1005df5cf15fSKiran Kumar K struct nix_inl_dev *inl_dev;
1006fbc0fa74SKiran Kumar K struct npc_flow_list *list;
1007fbc0fa74SKiran Kumar K struct roc_npc_flow *flow;
1008df5cf15fSKiran Kumar K struct idev_cfg *idev;
1009fbc0fa74SKiran Kumar K int rc = 0, idx;
1010fbc0fa74SKiran Kumar K
1011fbc0fa74SKiran Kumar K /* Free any MCAM counters and delete flow list */
1012fbc0fa74SKiran Kumar K for (idx = 0; idx < npc->flow_max_priority; idx++) {
1013fbc0fa74SKiran Kumar K list = &npc->flow_list[idx];
1014fbc0fa74SKiran Kumar K TAILQ_FOREACH(flow, list, next) {
1015fbc0fa74SKiran Kumar K flow->enable = enable;
1016df5cf15fSKiran Kumar K rc = npc_mcam_write_entry(npc->mbox, flow);
1017df5cf15fSKiran Kumar K if (rc)
1018df5cf15fSKiran Kumar K return rc;
1019df5cf15fSKiran Kumar K }
1020df5cf15fSKiran Kumar K }
1021df5cf15fSKiran Kumar K
1022df5cf15fSKiran Kumar K list = &npc->ipsec_list;
1023df5cf15fSKiran Kumar K idev = idev_get_cfg();
1024df5cf15fSKiran Kumar K if (!idev)
1025df5cf15fSKiran Kumar K return 0;
1026df5cf15fSKiran Kumar K inl_dev = idev->nix_inl_dev;
1027df5cf15fSKiran Kumar K
1028df5cf15fSKiran Kumar K if (inl_dev) {
1029df5cf15fSKiran Kumar K TAILQ_FOREACH(flow, list, next) {
1030df5cf15fSKiran Kumar K flow->enable = enable;
1031df5cf15fSKiran Kumar K rc = npc_mcam_write_entry(inl_dev->dev.mbox, flow);
1032fbc0fa74SKiran Kumar K if (rc)
1033fbc0fa74SKiran Kumar K return rc;
1034fbc0fa74SKiran Kumar K }
1035fbc0fa74SKiran Kumar K }
1036fbc0fa74SKiran Kumar K return rc;
1037fbc0fa74SKiran Kumar K }
1038fbc0fa74SKiran Kumar K
1039fbc0fa74SKiran Kumar K int
npc_flow_free_all_resources(struct npc * npc)1040f9af9080SKiran Kumar K npc_flow_free_all_resources(struct npc *npc)
1041f9af9080SKiran Kumar K {
1042f9af9080SKiran Kumar K struct roc_npc_flow *flow;
1043f9af9080SKiran Kumar K int rc, idx;
1044f9af9080SKiran Kumar K
1045f9af9080SKiran Kumar K /* Free all MCAM entries allocated */
1046f9af9080SKiran Kumar K rc = npc_mcam_free_all_entries(npc);
1047f9af9080SKiran Kumar K
1048f9af9080SKiran Kumar K /* Free any MCAM counters and delete flow list */
1049f9af9080SKiran Kumar K for (idx = 0; idx < npc->flow_max_priority; idx++) {
1050f9af9080SKiran Kumar K while ((flow = TAILQ_FIRST(&npc->flow_list[idx])) != NULL) {
105151dc6a80SSatheesh Paul npc_rss_group_free(npc, flow);
1052b4948072SSatheesh Paul if (flow->ctr_id != NPC_COUNTER_NONE) {
1053df5cf15fSKiran Kumar K rc |= npc_mcam_clear_counter(npc->mbox, flow->ctr_id);
1054df5cf15fSKiran Kumar K rc |= npc_mcam_free_counter(npc->mbox, flow->ctr_id);
1055b4948072SSatheesh Paul }
1056f9af9080SKiran Kumar K
1057209188d1SSatheesh Paul if (flow->is_sampling_rule)
1058209188d1SSatheesh Paul roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index);
1059209188d1SSatheesh Paul
10601f669198SSatheesh Paul npc_delete_prio_list_entry(npc, flow);
10611f669198SSatheesh Paul
1062f9af9080SKiran Kumar K TAILQ_REMOVE(&npc->flow_list[idx], flow, next);
1063f9af9080SKiran Kumar K plt_free(flow);
1064f9af9080SKiran Kumar K }
1065f9af9080SKiran Kumar K }
1066f9af9080SKiran Kumar K return rc;
1067f9af9080SKiran Kumar K }
1068