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