xref: /dpdk/drivers/net/sfc/sfc_mae_ct.c (revision c0db99c5329b13f17617a7a73a7530c2a59ac79a)
1*c0db99c5SDenis Pryazhennikov /* SPDX-License-Identifier: BSD-3-Clause
2*c0db99c5SDenis Pryazhennikov  *
3*c0db99c5SDenis Pryazhennikov  * Copyright (c) 2023 Advanced Micro Devices, Inc.
4*c0db99c5SDenis Pryazhennikov  */
5*c0db99c5SDenis Pryazhennikov 
6*c0db99c5SDenis Pryazhennikov #include "sfc.h"
7*c0db99c5SDenis Pryazhennikov #include "sfc_mae_ct.h"
8*c0db99c5SDenis Pryazhennikov 
9*c0db99c5SDenis Pryazhennikov /* SF-123102-TC-1A § 10.6.3: Conntrack_Table key */
10*c0db99c5SDenis Pryazhennikov static void
sfc_mae_ct_key_to_mcdi_key(const sfc_mae_conntrack_key_t * key,const efx_table_field_descriptor_t * fields,unsigned int n_fields,uint32_t * mcdi_key,unsigned int key_size)11*c0db99c5SDenis Pryazhennikov sfc_mae_ct_key_to_mcdi_key(const sfc_mae_conntrack_key_t *key,
12*c0db99c5SDenis Pryazhennikov 			   const efx_table_field_descriptor_t *fields,
13*c0db99c5SDenis Pryazhennikov 			   unsigned int n_fields, uint32_t *mcdi_key,
14*c0db99c5SDenis Pryazhennikov 			   unsigned int key_size)
15*c0db99c5SDenis Pryazhennikov {
16*c0db99c5SDenis Pryazhennikov 	unsigned int i;
17*c0db99c5SDenis Pryazhennikov 
18*c0db99c5SDenis Pryazhennikov 	for (i = 0; i < n_fields; i++) {
19*c0db99c5SDenis Pryazhennikov 		const efx_table_field_descriptor_t *desc = &fields[i];
20*c0db99c5SDenis Pryazhennikov 
21*c0db99c5SDenis Pryazhennikov 		if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER)
22*c0db99c5SDenis Pryazhennikov 			continue;
23*c0db99c5SDenis Pryazhennikov 
24*c0db99c5SDenis Pryazhennikov 		switch (desc->field_id) {
25*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_IP_PROTO:
26*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u8(mcdi_key, key_size, desc->lbn,
27*c0db99c5SDenis Pryazhennikov 					      desc->width, key->ip_proto);
28*c0db99c5SDenis Pryazhennikov 			break;
29*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_ETHER_TYPE:
30*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
31*c0db99c5SDenis Pryazhennikov 					       desc->width, key->ether_type_le);
32*c0db99c5SDenis Pryazhennikov 			break;
33*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_SRC_PORT:
34*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
35*c0db99c5SDenis Pryazhennikov 					       desc->width, key->src_port_le);
36*c0db99c5SDenis Pryazhennikov 			break;
37*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_DST_PORT:
38*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
39*c0db99c5SDenis Pryazhennikov 					       desc->width, key->dst_port_le);
40*c0db99c5SDenis Pryazhennikov 			break;
41*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_SRC_IP:
42*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn,
43*c0db99c5SDenis Pryazhennikov 					      desc->width,
44*c0db99c5SDenis Pryazhennikov 					      (const uint32_t *)key->src_addr_le);
45*c0db99c5SDenis Pryazhennikov 			break;
46*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_DST_IP:
47*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn,
48*c0db99c5SDenis Pryazhennikov 					      desc->width,
49*c0db99c5SDenis Pryazhennikov 					      (const uint32_t *)key->dst_addr_le);
50*c0db99c5SDenis Pryazhennikov 			break;
51*c0db99c5SDenis Pryazhennikov 
52*c0db99c5SDenis Pryazhennikov 		default:
53*c0db99c5SDenis Pryazhennikov 			break;
54*c0db99c5SDenis Pryazhennikov 		}
55*c0db99c5SDenis Pryazhennikov 	}
56*c0db99c5SDenis Pryazhennikov }
57*c0db99c5SDenis Pryazhennikov 
58*c0db99c5SDenis Pryazhennikov /* SF-123102-TC-1A § 10.6.4: Conntrack_Table response */
59*c0db99c5SDenis Pryazhennikov static void
sfc_mae_ct_response_to_mcdi_response(const sfc_mae_conntrack_response_t * response,const efx_table_field_descriptor_t * fields,unsigned int n_fields,uint32_t * mcdi_resp,unsigned int resp_size)60*c0db99c5SDenis Pryazhennikov sfc_mae_ct_response_to_mcdi_response(const sfc_mae_conntrack_response_t *response,
61*c0db99c5SDenis Pryazhennikov 				     const efx_table_field_descriptor_t *fields,
62*c0db99c5SDenis Pryazhennikov 				     unsigned int n_fields, uint32_t *mcdi_resp,
63*c0db99c5SDenis Pryazhennikov 				     unsigned int resp_size)
64*c0db99c5SDenis Pryazhennikov {
65*c0db99c5SDenis Pryazhennikov 	unsigned int i;
66*c0db99c5SDenis Pryazhennikov 
67*c0db99c5SDenis Pryazhennikov 	for (i = 0; i < n_fields; i++) {
68*c0db99c5SDenis Pryazhennikov 		const efx_table_field_descriptor_t *desc = &fields[i];
69*c0db99c5SDenis Pryazhennikov 
70*c0db99c5SDenis Pryazhennikov 		if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER)
71*c0db99c5SDenis Pryazhennikov 			continue;
72*c0db99c5SDenis Pryazhennikov 
73*c0db99c5SDenis Pryazhennikov 		/* Fields of responses are always reported with the EXACT type. */
74*c0db99c5SDenis Pryazhennikov 		SFC_ASSERT(desc->mask_type == EFX_TABLE_FIELD_MASK_EXACT);
75*c0db99c5SDenis Pryazhennikov 
76*c0db99c5SDenis Pryazhennikov 		switch (desc->field_id) {
77*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_CT_MARK:
78*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
79*c0db99c5SDenis Pryazhennikov 					       desc->width, response->ct_mark);
80*c0db99c5SDenis Pryazhennikov 			break;
81*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_COUNTER_ID:
82*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
83*c0db99c5SDenis Pryazhennikov 					       desc->width, response->counter_id);
84*c0db99c5SDenis Pryazhennikov 			break;
85*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_NAT_DIR:
86*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u8(mcdi_resp, resp_size, desc->lbn,
87*c0db99c5SDenis Pryazhennikov 					      desc->width, response->nat.dir_is_dst);
88*c0db99c5SDenis Pryazhennikov 			break;
89*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_NAT_IP:
90*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
91*c0db99c5SDenis Pryazhennikov 					       desc->width, response->nat.ip_le);
92*c0db99c5SDenis Pryazhennikov 			break;
93*c0db99c5SDenis Pryazhennikov 		case EFX_TABLE_FIELD_ID_NAT_PORT:
94*c0db99c5SDenis Pryazhennikov 			sfc_tbls_field_set_u16(mcdi_resp, resp_size, desc->lbn,
95*c0db99c5SDenis Pryazhennikov 					       desc->width, response->nat.port_le);
96*c0db99c5SDenis Pryazhennikov 			break;
97*c0db99c5SDenis Pryazhennikov 
98*c0db99c5SDenis Pryazhennikov 		default:
99*c0db99c5SDenis Pryazhennikov 			break;
100*c0db99c5SDenis Pryazhennikov 		}
101*c0db99c5SDenis Pryazhennikov 	}
102*c0db99c5SDenis Pryazhennikov }
103*c0db99c5SDenis Pryazhennikov 
104*c0db99c5SDenis Pryazhennikov int
sfc_mae_conntrack_insert(struct sfc_adapter * sa,const sfc_mae_conntrack_key_t * key,const sfc_mae_conntrack_response_t * response)105*c0db99c5SDenis Pryazhennikov sfc_mae_conntrack_insert(struct sfc_adapter *sa,
106*c0db99c5SDenis Pryazhennikov 			 const sfc_mae_conntrack_key_t *key,
107*c0db99c5SDenis Pryazhennikov 			 const sfc_mae_conntrack_response_t *response)
108*c0db99c5SDenis Pryazhennikov {
109*c0db99c5SDenis Pryazhennikov 	const struct sfc_tbls *tables = &sa->hw_tables;
110*c0db99c5SDenis Pryazhennikov 	uint8_t data[EFX_TABLE_ENTRY_LENGTH_MAX] = {0};
111*c0db99c5SDenis Pryazhennikov 	const struct sfc_tbl_meta *meta = NULL;
112*c0db99c5SDenis Pryazhennikov 	unsigned int response_size;
113*c0db99c5SDenis Pryazhennikov 	uint32_t *response_data;
114*c0db99c5SDenis Pryazhennikov 	unsigned int data_size;
115*c0db99c5SDenis Pryazhennikov 	unsigned int key_size;
116*c0db99c5SDenis Pryazhennikov 	uint32_t *start_data;
117*c0db99c5SDenis Pryazhennikov 	uint16_t resp_width;
118*c0db99c5SDenis Pryazhennikov 	uint16_t key_width;
119*c0db99c5SDenis Pryazhennikov 	uint32_t *key_data;
120*c0db99c5SDenis Pryazhennikov 	uint32_t *end_data;
121*c0db99c5SDenis Pryazhennikov 	int rc = 0;
122*c0db99c5SDenis Pryazhennikov 
123*c0db99c5SDenis Pryazhennikov 	if (tables->status != SFC_TBLS_STATUS_SUPPORTED)
124*c0db99c5SDenis Pryazhennikov 		return -ENOTSUP;
125*c0db99c5SDenis Pryazhennikov 
126*c0db99c5SDenis Pryazhennikov 	if (!sfc_mae_conntrack_is_supported(sa))
127*c0db99c5SDenis Pryazhennikov 		return -ENOTSUP;
128*c0db99c5SDenis Pryazhennikov 
129*c0db99c5SDenis Pryazhennikov 	meta = sfc_mae_conntrack_meta_lookup(sa);
130*c0db99c5SDenis Pryazhennikov 	if (meta == NULL)
131*c0db99c5SDenis Pryazhennikov 		return -ENOENT;
132*c0db99c5SDenis Pryazhennikov 
133*c0db99c5SDenis Pryazhennikov 	key_width = meta->descriptor.key_width;
134*c0db99c5SDenis Pryazhennikov 	resp_width = meta->descriptor.resp_width;
135*c0db99c5SDenis Pryazhennikov 
136*c0db99c5SDenis Pryazhennikov 	start_data = (uint32_t *)data;
137*c0db99c5SDenis Pryazhennikov 	key_data = start_data;
138*c0db99c5SDenis Pryazhennikov 	response_data = sfc_tbls_next_req_fields(key_data, key_width);
139*c0db99c5SDenis Pryazhennikov 	end_data = sfc_tbls_next_req_fields(response_data, resp_width);
140*c0db99c5SDenis Pryazhennikov 
141*c0db99c5SDenis Pryazhennikov 	key_size = RTE_PTR_DIFF(response_data, key_data);
142*c0db99c5SDenis Pryazhennikov 	response_size = RTE_PTR_DIFF(end_data, response_data);
143*c0db99c5SDenis Pryazhennikov 	data_size = RTE_PTR_DIFF(end_data, start_data);
144*c0db99c5SDenis Pryazhennikov 	SFC_ASSERT(data_size <= sizeof(data));
145*c0db99c5SDenis Pryazhennikov 
146*c0db99c5SDenis Pryazhennikov 	sfc_mae_ct_key_to_mcdi_key(key, meta->keys,
147*c0db99c5SDenis Pryazhennikov 				   meta->descriptor.n_key_fields, key_data,
148*c0db99c5SDenis Pryazhennikov 				   key_size);
149*c0db99c5SDenis Pryazhennikov 	sfc_mae_ct_response_to_mcdi_response(response, meta->responses,
150*c0db99c5SDenis Pryazhennikov 					     meta->descriptor.n_resp_fields,
151*c0db99c5SDenis Pryazhennikov 					     response_data, response_size);
152*c0db99c5SDenis Pryazhennikov 
153*c0db99c5SDenis Pryazhennikov 	rc = sfc_tbls_bcam_entry_insert(sa->nic, EFX_TABLE_ID_CONNTRACK,
154*c0db99c5SDenis Pryazhennikov 					key_width, resp_width, data,
155*c0db99c5SDenis Pryazhennikov 					data_size);
156*c0db99c5SDenis Pryazhennikov 
157*c0db99c5SDenis Pryazhennikov 	return rc;
158*c0db99c5SDenis Pryazhennikov }
159*c0db99c5SDenis Pryazhennikov 
160*c0db99c5SDenis Pryazhennikov int
sfc_mae_conntrack_delete(struct sfc_adapter * sa,const sfc_mae_conntrack_key_t * key)161*c0db99c5SDenis Pryazhennikov sfc_mae_conntrack_delete(struct sfc_adapter *sa,
162*c0db99c5SDenis Pryazhennikov 			 const sfc_mae_conntrack_key_t *key)
163*c0db99c5SDenis Pryazhennikov {
164*c0db99c5SDenis Pryazhennikov 	const struct sfc_tbls *tables = &sa->hw_tables;
165*c0db99c5SDenis Pryazhennikov 	uint8_t data[EFX_TABLE_ENTRY_LENGTH_MAX] = {0};
166*c0db99c5SDenis Pryazhennikov 	const struct sfc_tbl_meta *meta = NULL;
167*c0db99c5SDenis Pryazhennikov 	unsigned int data_size;
168*c0db99c5SDenis Pryazhennikov 	uint32_t *start_data;
169*c0db99c5SDenis Pryazhennikov 	uint16_t key_width;
170*c0db99c5SDenis Pryazhennikov 	uint32_t *key_data;
171*c0db99c5SDenis Pryazhennikov 	uint32_t *end_data;
172*c0db99c5SDenis Pryazhennikov 	int rc = 0;
173*c0db99c5SDenis Pryazhennikov 
174*c0db99c5SDenis Pryazhennikov 	if (tables->status != SFC_TBLS_STATUS_SUPPORTED)
175*c0db99c5SDenis Pryazhennikov 		return -ENOTSUP;
176*c0db99c5SDenis Pryazhennikov 
177*c0db99c5SDenis Pryazhennikov 	if (!sfc_mae_conntrack_is_supported(sa))
178*c0db99c5SDenis Pryazhennikov 		return -ENOTSUP;
179*c0db99c5SDenis Pryazhennikov 
180*c0db99c5SDenis Pryazhennikov 	meta = sfc_mae_conntrack_meta_lookup(sa);
181*c0db99c5SDenis Pryazhennikov 	if (meta == NULL)
182*c0db99c5SDenis Pryazhennikov 		return -ENOENT;
183*c0db99c5SDenis Pryazhennikov 
184*c0db99c5SDenis Pryazhennikov 	key_width = meta->descriptor.key_width;
185*c0db99c5SDenis Pryazhennikov 
186*c0db99c5SDenis Pryazhennikov 	start_data = (uint32_t *)data;
187*c0db99c5SDenis Pryazhennikov 	key_data = start_data;
188*c0db99c5SDenis Pryazhennikov 	end_data = sfc_tbls_next_req_fields(key_data, key_width);
189*c0db99c5SDenis Pryazhennikov 
190*c0db99c5SDenis Pryazhennikov 	data_size = RTE_PTR_DIFF(end_data, start_data);
191*c0db99c5SDenis Pryazhennikov 	SFC_ASSERT(data_size <= sizeof(data));
192*c0db99c5SDenis Pryazhennikov 
193*c0db99c5SDenis Pryazhennikov 	sfc_mae_ct_key_to_mcdi_key(key, meta->keys,
194*c0db99c5SDenis Pryazhennikov 				   meta->descriptor.n_key_fields,
195*c0db99c5SDenis Pryazhennikov 				   key_data, data_size);
196*c0db99c5SDenis Pryazhennikov 
197*c0db99c5SDenis Pryazhennikov 	rc = sfc_tbls_bcam_entry_delete(sa->nic, EFX_TABLE_ID_CONNTRACK,
198*c0db99c5SDenis Pryazhennikov 					key_width, data, data_size);
199*c0db99c5SDenis Pryazhennikov 
200*c0db99c5SDenis Pryazhennikov 	return rc;
201*c0db99c5SDenis Pryazhennikov }
202