Branch data Line data Source code
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
11 : 0 : 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 [ # # ]: 0 : for (i = 0; i < n_fields; i++) {
19 : 0 : const efx_table_field_descriptor_t *desc = &fields[i];
20 : :
21 [ # # ]: 0 : if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER)
22 : 0 : continue;
23 : :
24 [ # # # # : 0 : switch (desc->field_id) {
# # # ]
25 : 0 : case EFX_TABLE_FIELD_ID_IP_PROTO:
26 : 0 : sfc_tbls_field_set_u8(mcdi_key, key_size, desc->lbn,
27 : 0 : desc->width, key->ip_proto);
28 : 0 : break;
29 : 0 : case EFX_TABLE_FIELD_ID_ETHER_TYPE:
30 : 0 : sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
31 : 0 : desc->width, key->ether_type_le);
32 : 0 : break;
33 : 0 : case EFX_TABLE_FIELD_ID_SRC_PORT:
34 : 0 : sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
35 : 0 : desc->width, key->src_port_le);
36 : 0 : break;
37 : 0 : case EFX_TABLE_FIELD_ID_DST_PORT:
38 : 0 : sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn,
39 : 0 : desc->width, key->dst_port_le);
40 : 0 : break;
41 : 0 : case EFX_TABLE_FIELD_ID_SRC_IP:
42 : 0 : sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn,
43 : 0 : desc->width,
44 : 0 : (const uint32_t *)key->src_addr_le);
45 : 0 : break;
46 : 0 : case EFX_TABLE_FIELD_ID_DST_IP:
47 : 0 : sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn,
48 : 0 : desc->width,
49 : 0 : (const uint32_t *)key->dst_addr_le);
50 : 0 : break;
51 : :
52 : : default:
53 : : break;
54 : : }
55 : : }
56 : 0 : }
57 : :
58 : : /* SF-123102-TC-1A § 10.6.4: Conntrack_Table response */
59 : : static void
60 : 0 : 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 [ # # ]: 0 : for (i = 0; i < n_fields; i++) {
68 : 0 : const efx_table_field_descriptor_t *desc = &fields[i];
69 : :
70 [ # # ]: 0 : if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER)
71 : 0 : 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 [ # # # # : 0 : switch (desc->field_id) {
# # ]
77 : 0 : case EFX_TABLE_FIELD_ID_CT_MARK:
78 : 0 : sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
79 : 0 : desc->width, response->ct_mark);
80 : 0 : break;
81 : 0 : case EFX_TABLE_FIELD_ID_COUNTER_ID:
82 : 0 : sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
83 : 0 : desc->width, response->counter_id);
84 : 0 : break;
85 : 0 : case EFX_TABLE_FIELD_ID_NAT_DIR:
86 : 0 : sfc_tbls_field_set_u8(mcdi_resp, resp_size, desc->lbn,
87 : 0 : desc->width, response->nat.dir_is_dst);
88 : 0 : break;
89 : 0 : case EFX_TABLE_FIELD_ID_NAT_IP:
90 : 0 : sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn,
91 : 0 : desc->width, response->nat.ip_le);
92 : 0 : break;
93 : 0 : case EFX_TABLE_FIELD_ID_NAT_PORT:
94 : 0 : sfc_tbls_field_set_u16(mcdi_resp, resp_size, desc->lbn,
95 : 0 : desc->width, response->nat.port_le);
96 : 0 : break;
97 : :
98 : : default:
99 : : break;
100 : : }
101 : : }
102 : 0 : }
103 : :
104 : : int
105 : 0 : 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 : 0 : 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 [ # # ]: 0 : if (tables->status != SFC_TBLS_STATUS_SUPPORTED)
124 : : return -ENOTSUP;
125 : :
126 [ # # ]: 0 : if (!sfc_mae_conntrack_is_supported(sa))
127 : : return -ENOTSUP;
128 : :
129 : : meta = sfc_mae_conntrack_meta_lookup(sa);
130 [ # # ]: 0 : if (meta == NULL)
131 : : return -ENOENT;
132 : :
133 : 0 : key_width = meta->descriptor.key_width;
134 : 0 : resp_width = meta->descriptor.resp_width;
135 : :
136 : : start_data = (uint32_t *)data;
137 : : key_data = start_data;
138 : 0 : response_data = sfc_tbls_next_req_fields(key_data, key_width);
139 : 0 : end_data = sfc_tbls_next_req_fields(response_data, resp_width);
140 : :
141 : 0 : key_size = RTE_PTR_DIFF(response_data, key_data);
142 : 0 : response_size = RTE_PTR_DIFF(end_data, response_data);
143 : 0 : data_size = RTE_PTR_DIFF(end_data, start_data);
144 : : SFC_ASSERT(data_size <= sizeof(data));
145 : :
146 : 0 : sfc_mae_ct_key_to_mcdi_key(key, meta->keys,
147 : 0 : meta->descriptor.n_key_fields, key_data,
148 : : key_size);
149 : 0 : sfc_mae_ct_response_to_mcdi_response(response, meta->responses,
150 : 0 : meta->descriptor.n_resp_fields,
151 : : response_data, response_size);
152 : :
153 : 0 : rc = sfc_tbls_bcam_entry_insert(sa->nic, EFX_TABLE_ID_CONNTRACK,
154 : : key_width, resp_width, data,
155 : : data_size);
156 : :
157 : 0 : return rc;
158 : : }
159 : :
160 : : int
161 : 0 : 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 : 0 : 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 [ # # ]: 0 : if (tables->status != SFC_TBLS_STATUS_SUPPORTED)
175 : : return -ENOTSUP;
176 : :
177 [ # # ]: 0 : if (!sfc_mae_conntrack_is_supported(sa))
178 : : return -ENOTSUP;
179 : :
180 : : meta = sfc_mae_conntrack_meta_lookup(sa);
181 [ # # ]: 0 : if (meta == NULL)
182 : : return -ENOENT;
183 : :
184 : 0 : key_width = meta->descriptor.key_width;
185 : :
186 : : start_data = (uint32_t *)data;
187 : : key_data = start_data;
188 : 0 : 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 : 0 : sfc_mae_ct_key_to_mcdi_key(key, meta->keys,
194 : 0 : meta->descriptor.n_key_fields,
195 : : key_data, data_size);
196 : :
197 : 0 : rc = sfc_tbls_bcam_entry_delete(sa->nic, EFX_TABLE_ID_CONNTRACK,
198 : : key_width, data, data_size);
199 : :
200 : 0 : return rc;
201 : : }
|