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 : : #ifndef _SFC_TBLS_H
7 : : #define _SFC_TBLS_H
8 : :
9 : : #include "efx.h"
10 : :
11 : : #include "sfc_tbl_meta.h"
12 : :
13 : : #ifdef __cplusplus
14 : : extern "C" {
15 : : #endif
16 : :
17 : : /*
18 : : * Table types:
19 : : * CAM - Content addressable memory
20 : : * BCAM - Binary CAM
21 : : * TCAM - Ternary CAM
22 : : * STCAM - Semi-ternary CAM
23 : : *
24 : : * Short description:
25 : : * TCAM: Each entry has a key, mask, response and priority. An entry matches
26 : : * when (key & mask) == (request & mask). In the case of multiple
27 : : * matches, the entry with the highest priority wins; Each entry may
28 : : * have its own mask, but TCAM table definitions may place constraints
29 : : * on the possible masks allowed for each of the individual fields.
30 : : * STCAM: A limited form of TCAM in which only a limited number of masks and
31 : : * associated priorities), up to some maximum fixed by the definition
32 : : * of the table, may be in use at any one time.
33 : : * BCAM: Each entry has only a key and response, with the whole request
34 : : * matched against the key (like a typical hash table or "map").
35 : : * Direct (sometimes "DCAM", although it's not really content-addressable):
36 : : * Essentially just an array, where the key bits are used simply as an
37 : : * index.
38 : : */
39 : :
40 : : /* Priority is used only for TCAM or STCAM, use 0 in case of BCAM */
41 : : #define SFC_TBLS_BCAM_PRIORITY 0
42 : :
43 : : /* Mask ID is used only for STCAM with ALLOC_MASKS flag, use 0 for BCAM */
44 : : #define SFC_TBLS_BCAM_MASK_ID 0
45 : :
46 : : /* Mask is used only for STCAM */
47 : : #define SFC_TBLS_BCAM_MASK_WIDTH 0
48 : :
49 : : /** Options for HW tables support status */
50 : : enum sfc_tbls_status {
51 : : SFC_TBLS_STATUS_UNKNOWN = 0,
52 : : SFC_TBLS_STATUS_UNSUPPORTED,
53 : : SFC_TBLS_STATUS_SUPPORTED,
54 : : };
55 : :
56 : : /**
57 : : * Entry point to access HW tables
58 : : *
59 : : * SFC driver can access hardware (HW) tables.
60 : : * Interaction with HW tables is done through the MCDI table access API
61 : : * that is implemented in EFX.
62 : : *
63 : : * In order to manipulate data on HW tables it's necessary to
64 : : * - discover the list of supported tables;
65 : : * - read a table descriptor to get details of the structure
66 : : * of the table;
67 : : * - get named fields of the table;
68 : : * - insert/delete/update table entries based on given fields
69 : : * and information about the table
70 : : *
71 : : * All table layout data should be saved in a cache.
72 : : * The cache allows to avoid getting the table descriptor each time when you want
73 : : * to manipulate table entries. It just contains the table
74 : : * descriptors and all associated data. The cache is based on the RTE hash map and
75 : : * it uses a table ID as a key.
76 : : * The sfc_tbl_meta library serves as a wrapper over the cache and allows to user
77 : : * to get all information about the tables without worrying about the cache.
78 : : *
79 : : * +------------------------+
80 : : * | Cache is uninitialized |<----------------------------------+
81 : : * +------------------------+ |
82 : : * | |
83 : : * | sfc_attach() |
84 : : * | sfc_tbls_attach() -- (fail) -- sfc_tbls_detach()------+
85 : : * V ^
86 : : * +------------------------+ |
87 : : * | Cache is initialized | +-------+
88 : : * +------------------------+ |
89 : : * | sfc_start() |
90 : : * | sfc_tbls_start() -- (fail) -- sfc_tbls_stop()-+
91 : : * V |
92 : : * +------------------------+ |
93 : : * | Cache is initialized | |
94 : : * | and valid | |
95 : : * +------------------------+ |
96 : : * | |
97 : : * | sfc_restart() |
98 : : * V |
99 : : * +------------------------+ |
100 : : * | Cache is initialized | |
101 : : * | but can be invalid | |
102 : : * +------------------------+---------------------------+
103 : : */
104 : : struct sfc_tbls {
105 : : struct sfc_tbl_meta_cache meta;
106 : : enum sfc_tbls_status status;
107 : : };
108 : :
109 : : struct sfc_adapter;
110 : :
111 : : static inline bool
112 : : sfc_tbls_id_is_supported(struct sfc_adapter *sa,
113 : : efx_table_id_t table_id)
114 : : {
115 : 0 : return (sfc_tbl_meta_lookup(sa, table_id) == NULL ? false : true);
116 : : }
117 : :
118 : : int sfc_tbls_attach(struct sfc_adapter *sa);
119 : : void sfc_tbls_detach(struct sfc_adapter *sa);
120 : : int sfc_tbls_start(struct sfc_adapter *sa);
121 : :
122 : : static inline void
123 : : sfc_tbls_stop(struct sfc_adapter *sa)
124 : : {
125 : 0 : sfc_tbls_detach(sa);
126 : 0 : }
127 : :
128 : : static inline int
129 : : sfc_tbls_bcam_entry_insert(efx_nic_t *enp, efx_table_id_t table_id, uint16_t key_width,
130 : : uint16_t resp_width, uint8_t *data, unsigned int data_size)
131 : : {
132 : 0 : return efx_table_entry_insert(enp, table_id, SFC_TBLS_BCAM_PRIORITY,
133 : : SFC_TBLS_BCAM_MASK_ID, key_width,
134 : : SFC_TBLS_BCAM_MASK_WIDTH, resp_width,
135 : : data, data_size);
136 : : }
137 : :
138 : : static inline int
139 : : sfc_tbls_bcam_entry_delete(efx_nic_t *enp, efx_table_id_t table_id, uint16_t key_width,
140 : : uint8_t *data, unsigned int data_size)
141 : : {
142 : 0 : return efx_table_entry_delete(enp, table_id, SFC_TBLS_BCAM_MASK_ID,
143 : : key_width, SFC_TBLS_BCAM_MASK_WIDTH,
144 : : data, data_size);
145 : : }
146 : :
147 : : /**
148 : : * All manipulations with HW tables entries require forming
149 : : * a key and response.
150 : : * The key and response fields follow, consecutively, each
151 : : * packed as follows:
152 : : * - the key/response is logically treated as a single wide N-bit value;
153 : : * - fields have been placed in these logical values per the "lbn" and "width"
154 : : * information from the table field descriptors;
155 : : * - the wide N-bit value is padded at the MSB end up to a 32-bit boundary;
156 : : * - the values are put into the table op request with bits[31:0] of the wide
157 : : * value in the first 32-bit word, bits[63:32] in the second 32-bit word, etc.
158 : : *
159 : : * Below is an API that helps to form MCDI insertion/deletion request.
160 : : * Workflow:
161 : : * 1) Allocate an array of EFX_TABLE_ENTRY_LENGTH_MAX bytes.
162 : : * 2) Read a descriptor of the table that you want to use.
163 : : * 3) Fill the array using sfc_tbls_field_set_* functions to form a key.
164 : : * Each field of the key has LBN and width. This information can be
165 : : * found in a field's descriptor.
166 : : * 4) Use sfc_tbls_next_req_fields() to get a pointer where the response
167 : : * must start. It's required as the key and response need to be
168 : : * zero-padded at the MSB end to multiples of 32 bits.
169 : : * 5) Fill the response the same way.
170 : : * 6) Use sfc_tbls_next_req_fields() to get the end of the data request.
171 : : * It will help you to get the real size of the data request.
172 : : */
173 : :
174 : : /**
175 : : * Get a pointer to the beginning of the next 32-bit wide fields
176 : : * that go after a given width.
177 : : * It should be used to get a pointer to the response's start and the end
178 : : * of the data for an MCDI request.
179 : : *
180 : : * @param data Pointer to the data to make an offset from
181 : : * @param width Width of fields to offset
182 : : *
183 : : * @note @p width is expected to be a key's or response's size.
184 : : *
185 : : * @return Pointer to the beginning of the next field.
186 : : */
187 : : static inline uint32_t *
188 : : sfc_tbls_next_req_fields(uint32_t *data, uint16_t width)
189 : : {
190 : 0 : return data + EFX_DIV_ROUND_UP(width, sizeof(*data) * CHAR_BIT);
191 : : }
192 : :
193 : : /**
194 : : * Insert value into a field in the @p data buffer starting at
195 : : * bit offset @p lbn and containing @p width bits.
196 : : *
197 : : * @param data Data buffer
198 : : * @param data_size Size of the data buffer
199 : : * @param lbn Offset
200 : : * @param width Width of @p value in bits
201 : : * @param value uint32_t value to insert
202 : : *
203 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
204 : : */
205 : : void sfc_tbls_field_set_u32(uint32_t data[], unsigned int data_size,
206 : : uint16_t lbn, uint16_t width, uint32_t value);
207 : :
208 : : /**
209 : : * Insert value into a field in the @p data buffer starting at
210 : : * bit offset @p lbn and containing @p width bits.
211 : : *
212 : : * @param data Data buffer
213 : : * @param data_size Size of the data buffer
214 : : * @param lbn Offset
215 : : * @param width Width of @p value in bits
216 : : * @param value uint16_t value to insert
217 : : *
218 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
219 : : */
220 : : void sfc_tbls_field_set_u16(uint32_t data[], unsigned int data_size,
221 : : uint16_t lbn, uint16_t width, uint16_t value);
222 : :
223 : : /**
224 : : * Insert value into a field in the @p data buffer starting at
225 : : * bit offset @p lbn and containing @p width bits.
226 : : *
227 : : * @param data Data buffer
228 : : * @param data_size Size of the data buffer
229 : : * @param lbn Offset
230 : : * @param width Width of @p value in bits
231 : : * @param value uint8_t value to insert
232 : : *
233 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
234 : : */
235 : : void sfc_tbls_field_set_u8(uint32_t data[], unsigned int data_size,
236 : : uint16_t lbn, uint16_t width, uint8_t value);
237 : :
238 : : /**
239 : : * Insert IP address into a field in the @p data buffer starting at
240 : : * bit offset @p lbn and containing @p width bits.
241 : : *
242 : : * @param data Data buffer
243 : : * @param data_size Size of the data buffer
244 : : * @param lbn Offset
245 : : * @param width Width of @p value in bits
246 : : * @param ip IP address to insert
247 : : *
248 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
249 : : */
250 : : void sfc_tbls_field_set_ip(uint32_t data[], unsigned int data_size,
251 : : uint16_t lbn, uint16_t width, const uint32_t *ip);
252 : :
253 : : /**
254 : : * Insert value into a field in the data buffer starting at
255 : : * bit offset @p lbn and containing @p width bits.
256 : : *
257 : : * @param data Data buffer
258 : : * @param data_size Size of the data buffer
259 : : * @param lbn Offset
260 : : * @param width Width of @p value in bits
261 : : * @param value uint64_t value to insert
262 : : *
263 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
264 : : */
265 : : void sfc_tbls_field_set_u64(uint32_t data[], unsigned int data_size,
266 : : uint16_t lbn, uint16_t width, uint64_t value);
267 : :
268 : : /**
269 : : * Insert value into a field in the @p data buffer starting at
270 : : * bit offset @p lbn and containing @p width bits.
271 : : *
272 : : * @param data Data buffer
273 : : * @param data_size Size of the data buffer
274 : : * @param lbn Offset
275 : : * @param width Width of @p value in bits
276 : : * @param value Bit value to insert
277 : : *
278 : : * @note @p width and @p lbn must to be obtained from the field's descriptor.
279 : : */
280 : : void sfc_tbls_field_set_bit(uint32_t data[], unsigned int data_size,
281 : : uint16_t lbn, uint16_t width, bool value);
282 : :
283 : : #ifdef __cplusplus
284 : : }
285 : : #endif
286 : : #endif /* _SFC_TBLS_H */
|