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 *
bnxt_pmd_get_bp(uint16_t port)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
bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms * parms)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
glob_error_fn(const char * epath,int32_t eerrno)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
ulp_pmd_get_mac_by_pci(const char * pci_name,uint8_t * mac)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
bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms * parms,uint8_t * mac)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
bnxt_pmd_get_svif(uint16_t port_id,bool func_svif,enum bnxt_ulp_intf_type type)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
bnxt_pmd_get_iface_mac(uint16_t port,enum bnxt_ulp_intf_type type,uint8_t * mac,uint8_t * parent_mac)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
bnxt_pmd_get_parent_vnic_id(uint16_t port,enum bnxt_ulp_intf_type type)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
bnxt_pmd_get_vnic_id(uint16_t port,enum bnxt_ulp_intf_type type)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
bnxt_pmd_get_fw_func_id(uint16_t port,enum bnxt_ulp_intf_type type)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
bnxt_pmd_get_interface_type(uint16_t port)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
bnxt_pmd_get_phy_port_id(uint16_t port_id)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
bnxt_pmd_get_parif(uint16_t port_id,enum bnxt_ulp_intf_type type)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
bnxt_pmd_get_vport(uint16_t port_id)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
bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev * eth_dev)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 }
379