Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2021-2023 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 : : int
21 : 0 : bnxt_tunnel_dst_port_free(struct bnxt *bp,
22 : : uint16_t port,
23 : : uint8_t type)
24 : : {
25 : 0 : return bnxt_hwrm_tunnel_dst_port_free(bp,
26 : : port,
27 : : type);
28 : : }
29 : :
30 : : int
31 : 0 : bnxt_tunnel_dst_port_alloc(struct bnxt *bp,
32 : : uint16_t port,
33 : : uint8_t type)
34 : : {
35 : 0 : return bnxt_hwrm_tunnel_dst_port_alloc(bp,
36 : : port,
37 : : type);
38 : : }
39 : :
40 : : int
41 : 0 : bnxt_tunnel_upar_id_get(struct bnxt *bp,
42 : : uint8_t type,
43 : : uint8_t *upar_id)
44 : : {
45 : 0 : return bnxt_hwrm_tunnel_upar_id_get(bp,
46 : : upar_id,
47 : : type);
48 : : }
49 : :
50 : : struct bnxt *
51 : 0 : bnxt_pmd_get_bp(uint16_t port)
52 : : {
53 : : struct bnxt *bp;
54 : : struct rte_eth_dev *dev;
55 : :
56 [ # # ]: 0 : if (!rte_eth_dev_is_valid_port(port)) {
57 : 0 : PMD_DRV_LOG(ERR, "Invalid port %d\n", port);
58 : 0 : return NULL;
59 : : }
60 : :
61 : 0 : dev = &rte_eth_devices[port];
62 [ # # ]: 0 : if (!is_bnxt_supported(dev)) {
63 : 0 : PMD_DRV_LOG(ERR, "Device %d not supported\n", port);
64 : 0 : return NULL;
65 : : }
66 : :
67 : 0 : bp = (struct bnxt *)dev->data->dev_private;
68 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp)) {
69 : 0 : PMD_DRV_LOG(ERR, "TRUFLOW not enabled\n");
70 : 0 : return NULL;
71 : : }
72 : :
73 : : return bp;
74 : : }
75 : :
76 : 0 : int32_t bnxt_rss_config_action_apply(struct bnxt_ulp_mapper_parms *parms)
77 : : {
78 : : struct bnxt_vnic_info *vnic = NULL;
79 : : struct bnxt *bp = NULL;
80 : : uint64_t rss_types;
81 : : uint16_t hwrm_type;
82 : : uint32_t rss_level, key_len;
83 : : uint8_t *rss_key;
84 : 0 : struct ulp_rte_act_prop *ap = parms->act_prop;
85 : : int32_t rc = -EINVAL;
86 : :
87 : 0 : bp = bnxt_pmd_get_bp(parms->port_id);
88 [ # # ]: 0 : if (bp == NULL) {
89 : 0 : BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
90 : 0 : return rc;
91 : : }
92 : 0 : vnic = bnxt_get_default_vnic(bp);
93 [ # # ]: 0 : if (vnic == NULL) {
94 : 0 : BNXT_TF_DBG(ERR, "default vnic not available for %u\n",
95 : : parms->port_id);
96 : 0 : return rc;
97 : : }
98 : :
99 : : /* get the details */
100 : : memcpy(&rss_types, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES],
101 : : BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);
102 : : memcpy(&rss_level, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL],
103 : : BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);
104 : : memcpy(&key_len, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],
105 : : BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);
106 : 0 : rss_key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY];
107 : :
108 : 0 : hwrm_type = bnxt_rte_to_hwrm_hash_types(rss_types);
109 [ # # ]: 0 : if (!hwrm_type) {
110 : 0 : BNXT_TF_DBG(ERR, "Error unsupported rss config type\n");
111 : 0 : return rc;
112 : : }
113 : : /* Configure RSS only if the queue count is > 1 */
114 [ # # ]: 0 : if (vnic->rx_queue_cnt > 1) {
115 : 0 : vnic->hash_type = hwrm_type;
116 : 0 : vnic->hash_mode =
117 : 0 : bnxt_rte_to_hwrm_hash_level(bp, rss_types, rss_level);
118 : 0 : memcpy(vnic->rss_hash_key, rss_key,
119 : : BNXT_ULP_ACT_PROP_SZ_RSS_KEY);
120 : 0 : rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
121 [ # # ]: 0 : if (rc) {
122 : 0 : BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n");
123 : 0 : return rc;
124 : : }
125 : 0 : BNXT_TF_DBG(INFO, "Rss config successfully applied\n");
126 : : }
127 : : return 0;
128 : : }
129 : :
130 : : #define PARENT_PHY_INTF_PATH "/sys/bus/pci/devices/%s/physfn/net/*"
131 : : #define ULP_PRT_MAC_PATH "/sys/bus/pci/devices/%s/physfn/net/%s/address"
132 : :
133 : : #define ULP_FILE_PATH_SIZE 256
134 : :
135 : 0 : static int32_t glob_error_fn(const char *epath, int32_t eerrno)
136 : : {
137 : 0 : BNXT_TF_DBG(ERR, "path %s error %d\n", epath, eerrno);
138 : 0 : return 0;
139 : : }
140 : :
141 : 0 : static int32_t ulp_pmd_get_mac_by_pci(const char *pci_name, uint8_t *mac)
142 : : {
143 : : char path[ULP_FILE_PATH_SIZE], dev_str[ULP_FILE_PATH_SIZE];
144 : : char *intf_name;
145 : : glob_t gres;
146 : : FILE *fp;
147 : : int32_t rc = -EINVAL;
148 : :
149 : : memset(path, 0, sizeof(path));
150 : : sprintf(path, PARENT_PHY_INTF_PATH, pci_name);
151 : :
152 : : /* There can be only one, no more, no less */
153 [ # # ]: 0 : if (glob(path, 0, glob_error_fn, &gres) == 0) {
154 [ # # ]: 0 : if (gres.gl_pathc != 1)
155 : : return rc;
156 : :
157 : : /* Replace the PCI address with interface name and get index */
158 : 0 : intf_name = basename(gres.gl_pathv[0]);
159 : : sprintf(path, ULP_PRT_MAC_PATH, pci_name, intf_name);
160 : :
161 : 0 : fp = fopen(path, "r");
162 [ # # ]: 0 : if (!fp) {
163 : 0 : BNXT_TF_DBG(ERR, "Error in getting bond mac address\n");
164 : 0 : return rc;
165 : : }
166 : :
167 : : memset(dev_str, 0, sizeof(dev_str));
168 [ # # ]: 0 : if (fgets(dev_str, sizeof(dev_str), fp) == NULL) {
169 : 0 : BNXT_TF_DBG(ERR, "Error in reading %s\n", path);
170 : 0 : fclose(fp);
171 : 0 : return rc;
172 : : }
173 : :
174 [ # # ]: 0 : if (sscanf(dev_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
175 : : &mac[0], &mac[1], &mac[2],
176 : : &mac[3], &mac[4], &mac[5]) == 6)
177 : : rc = 0;
178 : 0 : fclose(fp);
179 : : }
180 : : return rc;
181 : : }
182 : :
183 : 0 : int32_t bnxt_pmd_get_parent_mac_addr(struct bnxt_ulp_mapper_parms *parms,
184 : : uint8_t *mac)
185 : : {
186 : : struct bnxt *bp = NULL;
187 : : int32_t rc = -EINVAL;
188 : :
189 : 0 : bp = bnxt_pmd_get_bp(parms->port_id);
190 [ # # ]: 0 : if (bp == NULL) {
191 : 0 : BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
192 : 0 : return rc;
193 : : }
194 : 0 : return ulp_pmd_get_mac_by_pci(bp->pdev->name, &mac[2]);
195 : : }
196 : :
197 : : uint16_t
198 : 0 : bnxt_pmd_get_svif(uint16_t port_id, bool func_svif,
199 : : enum bnxt_ulp_intf_type type)
200 : : {
201 : : struct rte_eth_dev *eth_dev;
202 : : struct bnxt *bp;
203 : :
204 : 0 : eth_dev = &rte_eth_devices[port_id];
205 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
206 : 0 : struct bnxt_representor *vfr = eth_dev->data->dev_private;
207 [ # # ]: 0 : if (!vfr)
208 : : return 0;
209 : :
210 [ # # ]: 0 : if (type == BNXT_ULP_INTF_TYPE_VF_REP)
211 : 0 : return vfr->svif;
212 : :
213 : 0 : eth_dev = vfr->parent_dev;
214 : : }
215 : :
216 : 0 : bp = eth_dev->data->dev_private;
217 : :
218 [ # # ]: 0 : return func_svif ? bp->func_svif : bp->port_svif;
219 : : }
220 : :
221 : : void
222 : 0 : bnxt_pmd_get_iface_mac(uint16_t port, enum bnxt_ulp_intf_type type,
223 : : uint8_t *mac, uint8_t *parent_mac)
224 : : {
225 : : struct rte_eth_dev *eth_dev;
226 : : struct bnxt *bp;
227 : :
228 [ # # ]: 0 : if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF &&
229 : : type != BNXT_ULP_INTF_TYPE_PF)
230 : : return;
231 : :
232 : 0 : eth_dev = &rte_eth_devices[port];
233 : 0 : bp = eth_dev->data->dev_private;
234 [ # # ]: 0 : memcpy(mac, bp->mac_addr, RTE_ETHER_ADDR_LEN);
235 : :
236 [ # # ]: 0 : if (type == BNXT_ULP_INTF_TYPE_TRUSTED_VF)
237 : 0 : memcpy(parent_mac, bp->parent->mac_addr, RTE_ETHER_ADDR_LEN);
238 : : }
239 : :
240 : : uint16_t
241 : 0 : bnxt_pmd_get_parent_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
242 : : {
243 : : struct rte_eth_dev *eth_dev;
244 : : struct bnxt *bp;
245 : :
246 [ # # ]: 0 : if (type != BNXT_ULP_INTF_TYPE_TRUSTED_VF)
247 : : return 0;
248 : :
249 : 0 : eth_dev = &rte_eth_devices[port];
250 : 0 : bp = eth_dev->data->dev_private;
251 : :
252 : 0 : return bp->parent->vnic;
253 : : }
254 : :
255 : : uint16_t
256 : 0 : bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
257 : : {
258 : : struct rte_eth_dev *eth_dev;
259 : : struct bnxt_vnic_info *vnic;
260 : : struct bnxt *bp;
261 : :
262 : 0 : eth_dev = &rte_eth_devices[port];
263 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
264 : 0 : struct bnxt_representor *vfr = eth_dev->data->dev_private;
265 [ # # ]: 0 : if (!vfr)
266 : : return 0;
267 : :
268 [ # # ]: 0 : if (type == BNXT_ULP_INTF_TYPE_VF_REP)
269 : 0 : return vfr->dflt_vnic_id;
270 : :
271 : 0 : eth_dev = vfr->parent_dev;
272 : : }
273 : :
274 : 0 : bp = eth_dev->data->dev_private;
275 : :
276 : 0 : vnic = bnxt_get_default_vnic(bp);
277 : :
278 : 0 : return vnic->fw_vnic_id;
279 : : }
280 : :
281 : : uint16_t
282 : 0 : bnxt_pmd_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type)
283 : : {
284 : : struct rte_eth_dev *eth_dev;
285 : : struct bnxt *bp;
286 : :
287 : 0 : eth_dev = &rte_eth_devices[port];
288 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
289 : 0 : struct bnxt_representor *vfr = eth_dev->data->dev_private;
290 [ # # ]: 0 : if (!vfr)
291 : : return 0;
292 : :
293 [ # # ]: 0 : if (type == BNXT_ULP_INTF_TYPE_VF_REP)
294 : 0 : return vfr->fw_fid;
295 : :
296 : 0 : eth_dev = vfr->parent_dev;
297 : : }
298 : :
299 : 0 : bp = eth_dev->data->dev_private;
300 : :
301 : 0 : return bp->fw_fid;
302 : : }
303 : :
304 : : enum bnxt_ulp_intf_type
305 : 0 : bnxt_pmd_get_interface_type(uint16_t port)
306 : : {
307 : : struct rte_eth_dev *eth_dev;
308 : : struct bnxt *bp;
309 : :
310 : 0 : eth_dev = &rte_eth_devices[port];
311 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev))
312 : : return BNXT_ULP_INTF_TYPE_VF_REP;
313 : :
314 : 0 : bp = eth_dev->data->dev_private;
315 [ # # ]: 0 : if (BNXT_PF(bp))
316 : : return BNXT_ULP_INTF_TYPE_PF;
317 [ # # ]: 0 : else if (BNXT_VF_IS_TRUSTED(bp))
318 : : return BNXT_ULP_INTF_TYPE_TRUSTED_VF;
319 : : else if (BNXT_VF(bp))
320 : 0 : return BNXT_ULP_INTF_TYPE_VF;
321 : :
322 : : return BNXT_ULP_INTF_TYPE_INVALID;
323 : : }
324 : :
325 : : uint16_t
326 : 0 : bnxt_pmd_get_phy_port_id(uint16_t port_id)
327 : : {
328 : : struct bnxt_representor *vfr;
329 : : struct rte_eth_dev *eth_dev;
330 : : struct bnxt *bp;
331 : :
332 : 0 : eth_dev = &rte_eth_devices[port_id];
333 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
334 : 0 : vfr = eth_dev->data->dev_private;
335 [ # # ]: 0 : if (!vfr)
336 : : return 0;
337 : :
338 : 0 : eth_dev = vfr->parent_dev;
339 : : }
340 : :
341 : 0 : bp = eth_dev->data->dev_private;
342 : :
343 [ # # ]: 0 : return BNXT_PF(bp) ? bp->pf->port_id : bp->parent->port_id;
344 : : }
345 : :
346 : : uint16_t
347 : 0 : bnxt_pmd_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type)
348 : : {
349 : : struct rte_eth_dev *eth_dev;
350 : : struct bnxt *bp;
351 : :
352 : 0 : eth_dev = &rte_eth_devices[port_id];
353 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
354 : 0 : struct bnxt_representor *vfr = eth_dev->data->dev_private;
355 [ # # ]: 0 : if (!vfr)
356 : : return 0;
357 : :
358 [ # # ]: 0 : if (type == BNXT_ULP_INTF_TYPE_VF_REP)
359 : 0 : return vfr->fw_fid - 1;
360 : :
361 : 0 : eth_dev = vfr->parent_dev;
362 : : }
363 : :
364 : 0 : bp = eth_dev->data->dev_private;
365 : :
366 [ # # ]: 0 : return BNXT_PF(bp) ? bp->fw_fid - 1 : bp->parent->fid - 1;
367 : : }
368 : :
369 : : uint16_t
370 : 0 : bnxt_pmd_get_vport(uint16_t port_id)
371 : : {
372 : 0 : return (1 << bnxt_pmd_get_phy_port_id(port_id));
373 : : }
374 : :
375 : : int32_t
376 : 0 : bnxt_pmd_set_unicast_rxmask(struct rte_eth_dev *eth_dev)
377 : : {
378 : 0 : struct bnxt *bp = eth_dev->data->dev_private;
379 : : struct bnxt_vnic_info *vnic;
380 : : uint32_t old_flags;
381 : : int32_t rc;
382 : :
383 : 0 : rc = is_bnxt_in_error(bp);
384 [ # # ]: 0 : if (rc)
385 : : return rc;
386 : :
387 : : /* Filter settings will get applied when port is started */
388 [ # # ]: 0 : if (!eth_dev->data->dev_started)
389 : : return 0;
390 : :
391 [ # # ]: 0 : if (bp->vnic_info == NULL)
392 : : return 0;
393 : :
394 : 0 : vnic = bnxt_get_default_vnic(bp);
395 : :
396 : 0 : old_flags = vnic->flags;
397 : 0 : vnic->flags |= BNXT_VNIC_INFO_UCAST;
398 : 0 : vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
399 : 0 : vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
400 : 0 : vnic->flags &= ~BNXT_VNIC_INFO_BCAST;
401 : 0 : rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
402 [ # # ]: 0 : if (rc != 0)
403 : 0 : vnic->flags = old_flags;
404 : :
405 : : return rc;
406 : : }
407 : :
408 : 0 : int32_t bnxt_pmd_queue_action_create(struct bnxt_ulp_mapper_parms *parms,
409 : : uint16_t *vnic_idx, uint16_t *vnic_id)
410 : : {
411 : : struct bnxt *bp = NULL;
412 : : uint16_t q_index;
413 : 0 : struct ulp_rte_act_prop *ap = parms->act_prop;
414 : :
415 : 0 : bp = bnxt_pmd_get_bp(parms->port_id);
416 [ # # ]: 0 : if (bp == NULL) {
417 : 0 : BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
418 : 0 : return -EINVAL;
419 : : }
420 : :
421 : : memcpy(&q_index, &ap->act_details[BNXT_ULP_ACT_PROP_IDX_QUEUE_INDEX],
422 : : BNXT_ULP_ACT_PROP_SZ_QUEUE_INDEX);
423 : :
424 : 0 : return bnxt_vnic_queue_action_alloc(bp, q_index, vnic_idx, vnic_id);
425 : : }
426 : :
427 : 0 : int32_t bnxt_pmd_queue_action_delete(struct tf *tfp, uint16_t vnic_idx)
428 : : {
429 : : struct bnxt *bp = NULL;
430 : :
431 : 0 : bp = tfp->bp;
432 [ # # ]: 0 : if (bp == NULL) {
433 : 0 : BNXT_TF_DBG(ERR, "Invalid bp\n");
434 : 0 : return -EINVAL;
435 : : }
436 : 0 : return bnxt_vnic_queue_action_free(bp, vnic_idx);
437 : : }
438 : :
439 : 0 : int32_t bnxt_pmd_rss_action_create(struct bnxt_ulp_mapper_parms *parms,
440 : : uint16_t *vnic_idx, uint16_t *vnic_id)
441 : : {
442 : : struct bnxt *bp = NULL;
443 : 0 : struct bnxt_vnic_rss_info rss_info = {0};
444 : 0 : struct ulp_rte_act_prop *ap = parms->act_prop;
445 : :
446 : 0 : bp = bnxt_pmd_get_bp(parms->port_id);
447 [ # # ]: 0 : if (bp == NULL) {
448 : 0 : BNXT_TF_DBG(ERR, "Invalid bp for port_id %u\n", parms->port_id);
449 : 0 : return -EINVAL;
450 : : }
451 : :
452 : : /* get the details */
453 : : memset(&rss_info, 0, sizeof(rss_info));
454 : : memcpy(&rss_info.rss_types,
455 : : &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES],
456 : : BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);
457 : : memcpy(&rss_info.rss_level,
458 : : &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL],
459 : : BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);
460 : : memcpy(&rss_info.key_len,
461 : : &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],
462 : : BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);
463 [ # # ]: 0 : if (rss_info.key_len)
464 : 0 : rss_info.key = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY];
465 : : memcpy(&rss_info.queue_num,
466 : : &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE_NUM],
467 : : BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE_NUM);
468 : :
469 : : /* Validate the size of the queue list */
470 : : if (sizeof(rss_info.queue_list) < BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE) {
471 : : BNXT_TF_DBG(ERR, "Mismatch of RSS queue size in template\n");
472 : : return -EINVAL;
473 : : }
474 : : memcpy(rss_info.queue_list,
475 : 0 : &ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_QUEUE],
476 : : BNXT_ULP_ACT_PROP_SZ_RSS_QUEUE);
477 : :
478 : 0 : return bnxt_vnic_rss_action_alloc(bp, &rss_info, vnic_idx, vnic_id);
479 : : }
480 : :
481 : 0 : int32_t bnxt_pmd_rss_action_delete(struct tf *tfp, uint16_t vnic_idx)
482 : : {
483 : 0 : struct bnxt *bp = tfp->bp;
484 : :
485 [ # # ]: 0 : if (bp == NULL) {
486 : 0 : BNXT_TF_DBG(ERR, "Invalid bp\n");
487 : 0 : return -EINVAL;
488 : : }
489 : 0 : return bnxt_vnic_rss_action_free(bp, vnic_idx);
490 : : }
491 : :
492 : : #define ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT 16
493 : : #define ULP_GLOBAL_TUNNEL_PORT_ID_MASK ((uint16_t)0xffff)
494 : : #define ULP_GLOBAL_TUNNEL_UPARID_SHIFT 8
495 : : #define ULP_GLOBAL_TUNNEL_UPARID_MASK ((uint16_t)0xff)
496 : : #define ULP_GLOBAL_TUNNEL_TYPE_SHIFT 0
497 : : #define ULP_GLOBAL_TUNNEL_TYPE_MASK ((uint16_t)0xffff)
498 : :
499 : : /* Extracts the dpdk port id and tunnel type from the handle */
500 : : static void
501 : : bnxt_pmd_global_reg_hndl_to_data(uint32_t handle, uint16_t *port,
502 : : uint8_t *upar_id, uint8_t *type)
503 : : {
504 : : *type = (handle >> ULP_GLOBAL_TUNNEL_TYPE_SHIFT) &
505 : : ULP_GLOBAL_TUNNEL_TYPE_MASK;
506 : : *upar_id = (handle >> ULP_GLOBAL_TUNNEL_UPARID_SHIFT) &
507 : : ULP_GLOBAL_TUNNEL_UPARID_MASK;
508 : 0 : *port = (handle >> ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT) &
509 : : ULP_GLOBAL_TUNNEL_PORT_ID_MASK;
510 : : }
511 : :
512 : : /* Packs the dpdk port id and tunnel type in the handle */
513 : : static void
514 : : bnxt_pmd_global_reg_data_to_hndl(uint16_t port_id, uint8_t upar_id,
515 : : uint8_t type, uint32_t *handle)
516 : : {
517 : 0 : *handle = (port_id & ULP_GLOBAL_TUNNEL_PORT_ID_MASK) <<
518 : : ULP_GLOBAL_TUNNEL_PORT_ID_SHIFT;
519 : 0 : *handle |= (upar_id & ULP_GLOBAL_TUNNEL_UPARID_MASK) <<
520 : : ULP_GLOBAL_TUNNEL_UPARID_SHIFT;
521 : 0 : *handle |= (type & ULP_GLOBAL_TUNNEL_TYPE_MASK) <<
522 : : ULP_GLOBAL_TUNNEL_TYPE_SHIFT;
523 : 0 : }
524 : :
525 : : static struct bnxt_global_tunnel_info
526 : : ulp_global_tunnel_db[BNXT_GLOBAL_REGISTER_TUNNEL_MAX] = {{0}};
527 : : /* Sets or resets the tunnel ports.
528 : : * If dport == 0, then the port_id and type are retrieved from the handle.
529 : : * otherwise, the incoming port_id, type, and dport are used.
530 : : * The type is enum ulp_mapper_ulp_global_tunnel_type
531 : : */
532 : : int32_t
533 : 0 : bnxt_pmd_global_tunnel_set(uint16_t port_id, uint8_t type,
534 : : uint16_t udp_port, uint32_t *handle)
535 : : {
536 : : uint16_t lport_id, ldport;
537 : : uint8_t hwtype, ltype, lupar_id;
538 : : struct bnxt *bp;
539 : : int32_t rc = 0;
540 : :
541 : : /* convert to HWRM type */
542 [ # # # ]: 0 : switch (type) {
543 : : case BNXT_GLOBAL_REGISTER_TUNNEL_VXLAN:
544 : : hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
545 : : break;
546 : 0 : case BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI:
547 : : hwtype = HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI;
548 : 0 : break;
549 : 0 : default:
550 : 0 : BNXT_TF_DBG(ERR, "Tunnel Type (%d) invalid\n", type);
551 : 0 : return -EINVAL;
552 : : }
553 : :
554 [ # # ]: 0 : if (!udp_port && type != BNXT_GLOBAL_REGISTER_TUNNEL_ECPRI) {
555 : : /* Free based on the handle */
556 [ # # ]: 0 : if (!handle) {
557 : 0 : BNXT_TF_DBG(ERR, "Free with invalid handle\n");
558 : 0 : return -EINVAL;
559 : : }
560 : 0 : bnxt_pmd_global_reg_hndl_to_data(*handle, &lport_id,
561 : : &lupar_id, <ype);
562 : :
563 : 0 : bp = bnxt_pmd_get_bp(lport_id);
564 [ # # ]: 0 : if (!bp) {
565 : 0 : BNXT_TF_DBG(ERR, "Unable to get dev by port %d\n",
566 : : lport_id);
567 : 0 : return -EINVAL;
568 : : }
569 : :
570 [ # # ]: 0 : if (!ulp_global_tunnel_db[ltype].ref_cnt)
571 : : return 0;
572 : 0 : ldport = ulp_global_tunnel_db[ltype].dport;
573 : 0 : rc = bnxt_hwrm_tunnel_dst_port_free(bp, ldport, hwtype);
574 [ # # ]: 0 : if (rc) {
575 : 0 : BNXT_TF_DBG(ERR,
576 : : "Unable to free tunnel dst port (%d)\n",
577 : : ldport);
578 : 0 : return rc;
579 : : }
580 : 0 : ulp_global_tunnel_db[ltype].ref_cnt--;
581 [ # # ]: 0 : if (ulp_global_tunnel_db[ltype].ref_cnt == 0)
582 : 0 : ulp_global_tunnel_db[ltype].dport = 0;
583 : : } else {
584 : 0 : bp = bnxt_pmd_get_bp(port_id);
585 [ # # ]: 0 : if (!bp) {
586 : 0 : BNXT_TF_DBG(ERR, "Unable to get dev by port %d\n",
587 : : port_id);
588 : 0 : return -EINVAL;
589 : : }
590 : :
591 : 0 : rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_port, hwtype);
592 [ # # ]: 0 : if (!rc) {
593 : 0 : ulp_global_tunnel_db[type].ref_cnt++;
594 : 0 : ulp_global_tunnel_db[type].dport = udp_port;
595 : 0 : bnxt_pmd_global_reg_data_to_hndl(port_id, bp->ecpri_upar_in_use,
596 : : type, handle);
597 : : }
598 : : }
599 : : return rc;
600 : : }
601 : :
602 : : #define BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR "BNXT_ULP_T_HA_SUPPORT"
603 : : /* This function queries the linux shell variable to determine
604 : : * whether Hot upgrade should be disabled or not.
605 : : * If BNXT_ULP_T_HA_SUPPORT is set to zero explicitly then
606 : : * hotupgrade is disabled.
607 : : */
608 : 0 : int32_t bnxt_pmd_get_hot_upgrade_env(void)
609 : : {
610 : : char *env;
611 : : int32_t hot_up = 1;
612 : :
613 : 0 : env = getenv(BNXT_ULP_HOT_UP_DYNAMIC_ENV_VAR);
614 [ # # # # ]: 0 : if (env && strcmp(env, "0") == 0)
615 : : hot_up = 0;
616 : 0 : return hot_up;
617 : : }
|