net/bnxt: support L2 context TCAM operations
[dpdk.git] / drivers / net / bnxt / tf_core / tf_device_p58.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_common.h>
7
8 #include "cfa_resource_types.h"
9 #include "tf_device.h"
10 #include "tf_identifier.h"
11 #include "tf_tbl.h"
12 #include "tf_tcam.h"
13 #include "tf_em.h"
14 #include "tf_if_tbl.h"
15 #include "tfp.h"
16 #include "tf_msg_common.h"
17
18 #define TF_DEV_P58_PARIF_MAX 16
19 #define TF_DEV_P58_PF_MASK 0xfUL
20
21 /* For print alignment, make all entries 8 chars in this table */
22 const char *tf_resource_str_p58[CFA_RESOURCE_TYPE_P58_LAST + 1] = {
23         [CFA_RESOURCE_TYPE_P58_METER]              = "meter   ",
24         [CFA_RESOURCE_TYPE_P58_SRAM_BANK_0]        = "sram_bk0",
25         [CFA_RESOURCE_TYPE_P58_SRAM_BANK_1]        = "sram_bk1",
26         [CFA_RESOURCE_TYPE_P58_SRAM_BANK_2]        = "sram_bk2",
27         [CFA_RESOURCE_TYPE_P58_SRAM_BANK_3]        = "sram_bk3",
28         [CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH]  = "l2ctx_hi",
29         [CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW]   = "l2ctx_lo",
30         [CFA_RESOURCE_TYPE_P58_L2_CTXT_REMAP_HIGH] = "l2ctr_hi",
31         [CFA_RESOURCE_TYPE_P58_L2_CTXT_REMAP_LOW]  = "l2ctr_lo",
32         [CFA_RESOURCE_TYPE_P58_PROF_FUNC]          = "prf_func",
33         [CFA_RESOURCE_TYPE_P58_PROF_TCAM]          = "prf_tcam",
34         [CFA_RESOURCE_TYPE_P58_EM_PROF_ID]         = "em_prof ",
35         [CFA_RESOURCE_TYPE_P58_WC_TCAM_PROF_ID]    = "wc_prof ",
36         [CFA_RESOURCE_TYPE_P58_EM_REC]             = "em_rec  ",
37         [CFA_RESOURCE_TYPE_P58_WC_TCAM]            = "wc_tcam ",
38         [CFA_RESOURCE_TYPE_P58_METER_PROF]         = "mtr_prof",
39         [CFA_RESOURCE_TYPE_P58_MIRROR]             = "mirror  ",
40         [CFA_RESOURCE_TYPE_P58_EM_FKB]             = "em_fkb  ",
41         [CFA_RESOURCE_TYPE_P58_WC_FKB]             = "wc_fkb  ",
42         [CFA_RESOURCE_TYPE_P58_VEB_TCAM]           = "veb     ",
43 };
44
45 /**
46  * Device specific function that retrieves the MAX number of HCAPI
47  * types the device supports.
48  *
49  * [in] tfp
50  *   Pointer to TF handle
51  *
52  * [out] max_types
53  *   Pointer to the MAX number of HCAPI types supported
54  *
55  * Returns
56  *   - (0) if successful.
57  *   - (-EINVAL) on failure.
58  */
59 static int
60 tf_dev_p58_get_max_types(struct tf *tfp,
61                         uint16_t *max_types)
62 {
63         struct tf_session *tfs;
64         struct tf_dev_info *dev;
65         int rc;
66
67         if (max_types == NULL || tfp == NULL)
68                 return -EINVAL;
69
70         /* Retrieve the session information */
71         rc = tf_session_get_session(tfp, &tfs);
72         if (rc)
73                 return rc;
74
75         /* Retrieve the device information */
76         rc = tf_session_get_device(tfs, &dev);
77         if (rc)
78                 return rc;
79
80         *max_types = CFA_RESOURCE_TYPE_P58_LAST + 1;
81
82         return 0;
83 }
84 /**
85  * Device specific function that retrieves a human readable
86  * string to identify a CFA resource type.
87  *
88  * [in] tfp
89  *   Pointer to TF handle
90  *
91  * [in] resource_id
92  *   HCAPI CFA resource id
93  *
94  * [out] resource_str
95  *   Resource string
96  *
97  * Returns
98  *   - (0) if successful.
99  *   - (-EINVAL) on failure.
100  */
101 static int
102 tf_dev_p58_get_resource_str(struct tf *tfp __rte_unused,
103                             uint16_t resource_id,
104                             const char **resource_str)
105 {
106         if (resource_str == NULL)
107                 return -EINVAL;
108
109         if (resource_id > CFA_RESOURCE_TYPE_P58_LAST)
110                 return -EINVAL;
111
112         *resource_str = tf_resource_str_p58[resource_id];
113
114         return 0;
115 }
116
117 /**
118  * Device specific function that retrieves the WC TCAM slices the
119  * device supports.
120  *
121  * [in] tfp
122  *   Pointer to TF handle
123  *
124  * [out] slice_size
125  *   Pointer to the WC TCAM slice size
126  *
127  * [out] num_slices_per_row
128  *   Pointer to the WC TCAM row slice configuration
129  *
130  * Returns
131  *   - (0) if successful.
132  *   - (-EINVAL) on failure.
133  */
134 static int
135 tf_dev_p58_get_tcam_slice_info(struct tf *tfp __rte_unused,
136                               enum tf_tcam_tbl_type type,
137                               uint16_t key_sz,
138                               uint16_t *num_slices_per_row)
139 {
140 #define CFA_P58_WC_TCAM_SLICES_PER_ROW 2
141 #define CFA_P58_WC_TCAM_SLICE_SIZE     12
142
143         if (type == TF_TCAM_TBL_TYPE_WC_TCAM) {
144                 *num_slices_per_row = CFA_P58_WC_TCAM_SLICES_PER_ROW;
145                 if (key_sz > *num_slices_per_row * CFA_P58_WC_TCAM_SLICE_SIZE)
146                         return -ENOTSUP;
147
148                 *num_slices_per_row = 1;
149         } else { /* for other type of tcam */
150                 *num_slices_per_row = 1;
151         }
152
153         return 0;
154 }
155
156 static int
157 tf_dev_p58_map_parif(struct tf *tfp __rte_unused,
158                     uint16_t parif_bitmask,
159                     uint16_t pf,
160                     uint8_t *data,
161                     uint8_t *mask,
162                     uint16_t sz_in_bytes)
163 {
164         uint32_t parif_pf[2] = { 0 };
165         uint32_t parif_pf_mask[2] = { 0 };
166         uint32_t parif;
167         uint32_t shift;
168
169         if (sz_in_bytes != sizeof(uint64_t))
170                 return -ENOTSUP;
171
172         for (parif = 0; parif < TF_DEV_P58_PARIF_MAX; parif++) {
173                 if (parif_bitmask & (1UL << parif)) {
174                         if (parif < 8) {
175                                 shift = 4 * parif;
176                                 parif_pf_mask[0] |= TF_DEV_P58_PF_MASK << shift;
177                                 parif_pf[0] |= pf << shift;
178                         } else {
179                                 shift = 4 * (parif - 8);
180                                 parif_pf_mask[1] |= TF_DEV_P58_PF_MASK << shift;
181                                 parif_pf[1] |= pf << shift;
182                         }
183                 }
184         }
185         tfp_memcpy(data, parif_pf, sz_in_bytes);
186         tfp_memcpy(mask, parif_pf_mask, sz_in_bytes);
187
188         return 0;
189 }
190
191 static int tf_dev_p58_get_mailbox(void)
192 {
193         return TF_CHIMP_MB;
194 }
195
196 static int tf_dev_p58_word_align(uint16_t size)
197 {
198         return ((((size) + 63) >> 6) * 8);
199 }
200
201 /**
202  * Truflow P58 device specific functions
203  */
204 const struct tf_dev_ops tf_dev_ops_p58_init = {
205         .tf_dev_get_max_types = tf_dev_p58_get_max_types,
206         .tf_dev_get_resource_str = tf_dev_p58_get_resource_str,
207         .tf_dev_get_tcam_slice_info = tf_dev_p58_get_tcam_slice_info,
208         .tf_dev_alloc_ident = NULL,
209         .tf_dev_free_ident = NULL,
210         .tf_dev_search_ident = NULL,
211         .tf_dev_alloc_ext_tbl = NULL,
212         .tf_dev_alloc_tbl = NULL,
213         .tf_dev_free_ext_tbl = NULL,
214         .tf_dev_free_tbl = NULL,
215         .tf_dev_alloc_search_tbl = NULL,
216         .tf_dev_set_tbl = NULL,
217         .tf_dev_set_ext_tbl = NULL,
218         .tf_dev_get_tbl = NULL,
219         .tf_dev_get_bulk_tbl = NULL,
220         .tf_dev_alloc_tcam = NULL,
221         .tf_dev_free_tcam = NULL,
222         .tf_dev_alloc_search_tcam = NULL,
223         .tf_dev_set_tcam = NULL,
224         .tf_dev_get_tcam = NULL,
225         .tf_dev_insert_int_em_entry = NULL,
226         .tf_dev_delete_int_em_entry = NULL,
227         .tf_dev_insert_ext_em_entry = NULL,
228         .tf_dev_delete_ext_em_entry = NULL,
229         .tf_dev_alloc_tbl_scope = NULL,
230         .tf_dev_map_tbl_scope = NULL,
231         .tf_dev_map_parif = NULL,
232         .tf_dev_free_tbl_scope = NULL,
233         .tf_dev_set_if_tbl = NULL,
234         .tf_dev_get_if_tbl = NULL,
235         .tf_dev_set_global_cfg = NULL,
236         .tf_dev_get_global_cfg = NULL,
237         .tf_dev_get_mailbox = tf_dev_p58_get_mailbox,
238         .tf_dev_word_align = NULL,
239 };
240
241 /**
242  * Truflow P58 device specific functions
243  */
244 const struct tf_dev_ops tf_dev_ops_p58 = {
245         .tf_dev_get_max_types = tf_dev_p58_get_max_types,
246         .tf_dev_get_resource_str = tf_dev_p58_get_resource_str,
247         .tf_dev_get_tcam_slice_info = tf_dev_p58_get_tcam_slice_info,
248         .tf_dev_alloc_ident = tf_ident_alloc,
249         .tf_dev_free_ident = tf_ident_free,
250         .tf_dev_search_ident = tf_ident_search,
251         .tf_dev_alloc_tbl = tf_tbl_alloc,
252         .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc,
253         .tf_dev_free_tbl = tf_tbl_free,
254         .tf_dev_free_ext_tbl = tf_tbl_ext_free,
255         .tf_dev_alloc_search_tbl = tf_tbl_alloc_search,
256         .tf_dev_set_tbl = tf_tbl_set,
257         .tf_dev_set_ext_tbl = tf_tbl_ext_common_set,
258         .tf_dev_get_tbl = tf_tbl_get,
259         .tf_dev_get_bulk_tbl = tf_tbl_bulk_get,
260         .tf_dev_alloc_tcam = tf_tcam_alloc,
261         .tf_dev_free_tcam = tf_tcam_free,
262         .tf_dev_alloc_search_tcam = tf_tcam_alloc_search,
263         .tf_dev_set_tcam = tf_tcam_set,
264         .tf_dev_get_tcam = tf_tcam_get,
265         .tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry,
266         .tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry,
267         .tf_dev_insert_ext_em_entry = NULL,
268         .tf_dev_delete_ext_em_entry = NULL,
269         .tf_dev_alloc_tbl_scope = NULL,
270         .tf_dev_map_tbl_scope = NULL,
271         .tf_dev_map_parif = tf_dev_p58_map_parif,
272         .tf_dev_free_tbl_scope = NULL,
273         .tf_dev_set_if_tbl = tf_if_tbl_set,
274         .tf_dev_get_if_tbl = tf_if_tbl_get,
275         .tf_dev_set_global_cfg = tf_global_cfg_set,
276         .tf_dev_get_global_cfg = tf_global_cfg_get,
277         .tf_dev_get_mailbox = tf_dev_p58_get_mailbox,
278         .tf_dev_word_align = tf_dev_p58_word_align,
279 };