net/ice/base: init flag redirect table for parser
[dpdk.git] / drivers / net / bnxt / tf_ulp / bnxt_tf_pmd_shim.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <glob.h>
7 #include <libgen.h>
8 #include <stdio.h>
9 #include <net/if.h>
10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 #include <unistd.h>
13
14 #include "bnxt.h"
15 #include "bnxt_vnic.h"
16 #include "bnxt_hwrm.h"
17 #include "bnxt_tf_common.h"
18 #include "bnxt_tf_pmd_shim.h"
19
20 struct bnxt *
21 bnxt_pmd_get_bp(uint16_t port)
22 {
23         struct bnxt *bp;
24         struct rte_eth_dev *dev;
25
26         if (!rte_eth_dev_is_valid_port(port)) {
27                 PMD_DRV_LOG(ERR, "Invalid port %d\n", port);
28                 return NULL;
29         }
30
31         dev = &rte_eth_devices[port];
32         if (!is_bnxt_supported(dev)) {
33                 PMD_DRV_LOG(ERR, "Device %d not supported\n", port);
34                 return NULL;
35         }
36
37         bp = (struct bnxt *)dev->data->dev_private;
38         if (!BNXT_TRUFLOW_EN(bp)) {
39                 PMD_DRV_LOG(ERR, "TRUFLOW not enabled\n");
40                 return NULL;
41         }
42
43         return bp;
44 }
45
46 int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms)
47 {
48         struct bnxt_vnic_info *vnic = NULL;
49         struct bnxt *bp = NULL;
50         uint64_t rss_types;
51         uint16_t hwrm_type;
52         uint32_t rss_level, key_len;
53         uint8_t *rss_key;
54         struct ulp_rte_act_prop *ap = parms->act_prop;
55         int32_t rc = -EINVAL;
56
57         bp = bnxt_pmd_get_bp(parms->port_id);
58         if (bp == NULL) {
59                 BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
60                 return rc;
61         }
62         vnic = BNXT_GET_DEFAULT_VNIC(bp);
63         if (vnic == NULL) {
64                 BNXT_TF_DBG(ERR, "default vnic not available for %u\n",
65                             parms->port_id);
66                 return rc;
67         }
68
69         /* get the details */
70         memcpy(&rss_types, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES],
71                BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);
72         memcpy(&rss_level, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL],
73                BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);
74         memcpy(&key_len, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],
75                BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);
76         rss_key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY];
77
78         hwrm_type = bnxt_rte_to_hwrm_hash_types(rss_types);
79         if (!hwrm_type) {
80                 BNXT_TF_DBG(ERR, "Error unsupported rss config type\n");
81                 return rc;
82         }
83         /* Configure RSS only if the queue count is > 1 */
84         if (vnic->rx_queue_cnt > 1) {
85                 vnic->hash_type = hwrm_type;
86                 vnic->hash_mode =
87                         bnxt_rte_to_hwrm_hash_level(bp, rss_types, rss_level);
88                 memcpy(vnic->rss_hash_key, rss_key,
89                        BNXT_ULP_ACT_PROP_SZ_RSS_KEY);
90                 rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
91                 if (rc) {
92                         BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n");
93                         return rc;
94                 }
95                 BNXT_TF_DBG(INFO, "Rss config successfully applied\n");
96         }
97         return 0;
98 }
99
100 #define PARENT_PHY_INTF_PATH "/sys/bus/pci/devices/%s/physfn/net/*"
101 #define ULP_PRT_MAC_PATH "/sys/bus/pci/devices/%s/physfn/net/%s/address"
102
103 #define ULP_FILE_PATH_SIZE 256
104
105 static int32_t glob_error_fn(const char *epath, int32_t eerrno)
106 {
107         BNXT_TF_DBG(ERR, "path %s error %d\n", epath, eerrno);
108         return 0;
109 }
110
111
112 static int32_t ulp_pmd_get_mac_by_pci(const char *pci_name, uint8_t *mac)
113 {
114         char path[ULP_FILE_PATH_SIZE], dev_str[ULP_FILE_PATH_SIZE];
115         char *intf_name;
116         glob_t gres;
117         FILE *fp;
118         int32_t rc = -EINVAL;
119
120         memset(path, 0, sizeof(path));
121         sprintf(path, PARENT_PHY_INTF_PATH, pci_name);
122
123         /* There can be only one, no more, no less */
124         if (glob(path, 0, glob_error_fn, &gres) == 0) {
125                 if (gres.gl_pathc != 1)
126                         return rc;
127
128                 /* Replace the PCI address with interface name and get index */
129                 intf_name = basename(gres.gl_pathv[0]);
130                 sprintf(path, ULP_PRT_MAC_PATH, pci_name, intf_name);
131
132                 fp = fopen(path, "r");
133                 if (!fp) {
134                         BNXT_TF_DBG(ERR, "Error in getting bond mac address\n");
135                         return rc;
136                 }
137
138                 memset(dev_str, 0, sizeof(dev_str));
139                 if (fgets(dev_str, sizeof(dev_str), fp) == NULL) {
140                         BNXT_TF_DBG(ERR, "Error in reading %s\n", path);
141                         fclose(fp);
142                         return rc;
143                 }
144
145                 if (sscanf(dev_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
146                            &mac[0], &mac[1], &mac[2],
147                            &mac[3], &mac[4], &mac[5]) == 6)
148                         rc = 0;
149                 fclose(fp);
150         }
151         return rc;
152 }
153
154 int32_t bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms *parms,
155                                      uint8_t *mac)
156 {
157         struct bnxt *bp = NULL;
158         int32_t rc = -EINVAL;
159
160         bp = bnxt_pmd_get_bp(parms->port_id);
161         if (bp == NULL) {
162                 BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
163                 return rc;
164         }
165         return ulp_pmd_get_mac_by_pci(bp->pdev->name, &mac[2]);
166 }
167
168 uint16_t
169 bnxt_pmd_get_svif(uint16_t port_id, bool func_svif,
170               enum bnxt_ulp_intf_type type)
171 {
172         struct rte_eth_dev *eth_dev;
173         struct bnxt *bp;
174
175         eth_dev = &rte_eth_devices[port_id];
176         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
177                 struct bnxt_representor *vfr = eth_dev->data->dev_private;
178                 if (!vfr)
179                         return 0;
180
181                 if (type == BNXT_ULP_INTF_TYPE_VF_REP)
182                         return vfr->svif;
183
184                 eth_dev = vfr->parent_dev;
185         }
186
187         bp = eth_dev->data->dev_private;
188
189         return func_svif ? bp->func_svif : bp->port_svif;
190 }
191
192 void
193 bnxt_pmd_get_iface_mac(uint16_t port, enum bnxt_ulp_intf_type type,
194                        uint8_t *mac, uint8_t *parent_mac)
195 {
196         struct rte_eth_dev *eth_dev;
197         struct bnxt *bp;
198
199         if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF &&
200             type != BNXT_ULP_INTF_TYPE_PF)
201                 return;
202
203         eth_dev = &rte_eth_devices[port];
204         bp = eth_dev->data->dev_private;
205         memcpy(mac, bp->mac_addr, RTE_ETHER_ADDR_LEN);
206
207         if (type == BNXT_ULP_INTF_TYPE_TRUSTED_VF)
208                 memcpy(parent_mac, bp->parent->mac_addr, RTE_ETHER_ADDR_LEN);
209 }
210
211 uint16_t
212 bnxt_pmd_get_parent_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
213 {
214         struct rte_eth_dev *eth_dev;
215         struct bnxt *bp;
216
217         if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF)
218                 return 0;
219
220         eth_dev = &rte_eth_devices[port];
221         bp = eth_dev->data->dev_private;
222
223         return bp->parent->vnic;
224 }
225
226 uint16_t
227 bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
228 {
229         struct rte_eth_dev *eth_dev;
230         struct bnxt_vnic_info *vnic;
231         struct bnxt *bp;
232
233         eth_dev = &rte_eth_devices[port];
234         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
235                 struct bnxt_representor *vfr = eth_dev->data->dev_private;
236                 if (!vfr)
237                         return 0;
238
239                 if (type == BNXT_ULP_INTF_TYPE_VF_REP)
240                         return vfr->dflt_vnic_id;
241
242                 eth_dev = vfr->parent_dev;
243         }
244
245         bp = eth_dev->data->dev_private;
246
247         vnic = BNXT_GET_DEFAULT_VNIC(bp);
248
249         return vnic->fw_vnic_id;
250 }
251
252 uint16_t
253 bnxt_pmd_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type)
254 {
255         struct rte_eth_dev *eth_dev;
256         struct bnxt *bp;
257
258         eth_dev = &rte_eth_devices[port];
259         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
260                 struct bnxt_representor *vfr = eth_dev->data->dev_private;
261                 if (!vfr)
262                         return 0;
263
264                 if (type == BNXT_ULP_INTF_TYPE_VF_REP)
265                         return vfr->fw_fid;
266
267                 eth_dev = vfr->parent_dev;
268         }
269
270         bp = eth_dev->data->dev_private;
271
272         return bp->fw_fid;
273 }
274
275 enum bnxt_ulp_intf_type
276 bnxt_pmd_get_interface_type(uint16_t port)
277 {
278         struct rte_eth_dev *eth_dev;
279         struct bnxt *bp;
280
281         eth_dev = &rte_eth_devices[port];
282         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev))
283                 return BNXT_ULP_INTF_TYPE_VF_REP;
284
285         bp = eth_dev->data->dev_private;
286         if (BNXT_PF(bp))
287                 return BNXT_ULP_INTF_TYPE_PF;
288         else if (BNXT_VF_IS_TRUSTED(bp))
289                 return BNXT_ULP_INTF_TYPE_TRUSTED_VF;
290         else if (BNXT_VF(bp))
291                 return BNXT_ULP_INTF_TYPE_VF;
292
293         return BNXT_ULP_INTF_TYPE_INVALID;
294 }
295
296 uint16_t
297 bnxt_pmd_get_phy_port_id(uint16_t port_id)
298 {
299         struct bnxt_representor *vfr;
300         struct rte_eth_dev *eth_dev;
301         struct bnxt *bp;
302
303         eth_dev = &rte_eth_devices[port_id];
304         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
305                 vfr = eth_dev->data->dev_private;
306                 if (!vfr)
307                         return 0;
308
309                 eth_dev = vfr->parent_dev;
310         }
311
312         bp = eth_dev->data->dev_private;
313
314         return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id;
315 }
316
317 uint16_t
318 bnxt_pmd_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type)
319 {
320         struct rte_eth_dev *eth_dev;
321         struct bnxt *bp;
322
323         eth_dev = &rte_eth_devices[port_id];
324         if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
325                 struct bnxt_representor *vfr = eth_dev->data->dev_private;
326                 if (!vfr)
327                         return 0;
328
329                 if (type == BNXT_ULP_INTF_TYPE_VF_REP)
330                         return vfr->fw_fid - 1;
331
332                 eth_dev = vfr->parent_dev;
333         }
334
335         bp = eth_dev->data->dev_private;
336
337         return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1;
338 }
339
340 uint16_t
341 bnxt_pmd_get_vport(uint16_t port_id)
342 {
343         return (1 << bnxt_pmd_get_phy_port_id(port_id));
344 }
345
346
347 int32_t
348 bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)
349 {
350         struct bnxt *bp = eth_dev->data->dev_private;
351         struct bnxt_vnic_info *vnic;
352         uint32_t old_flags;
353         int32_t rc;
354
355         rc = is_bnxt_in_error(bp);
356         if (rc)
357                 return rc;
358
359         /* Filter settings will get applied when port is started */
360         if (!eth_dev->data->dev_started)
361                 return 0;
362
363         if (bp->vnic_info == NULL)
364                 return 0;
365
366         vnic = BNXT_GET_DEFAULT_VNIC(bp);
367
368         old_flags = vnic->flags;
369         vnic->flags |= BNXT_VNIC_INFO_UCAST;
370         vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
371         vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
372         vnic->flags &= ~BNXT_VNIC_INFO_BCAST;
373         rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
374         if (rc != 0)
375                 vnic->flags = old_flags;
376
377         return rc;
378 }