Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020-2021 Xilinx, Inc.
3 : : */
4 : :
5 : : #include <rte_errno.h>
6 : : #include <rte_ether.h>
7 : : #include <rte_kvargs.h>
8 : :
9 : : #include "efx.h"
10 : : #include "efx_impl.h"
11 : : #include "sfc_vdpa.h"
12 : :
13 : : static inline int
14 : 0 : sfc_vdpa_get_eth_addr(const char *key __rte_unused,
15 : : const char *value, void *extra_args)
16 : : {
17 : : struct rte_ether_addr *mac_addr = extra_args;
18 : :
19 [ # # ]: 0 : if (value == NULL || extra_args == NULL)
20 : : return -EINVAL;
21 : :
22 : : /* Convert string with Ethernet address to an ether_addr */
23 : 0 : rte_ether_unformat_addr(value, mac_addr);
24 : :
25 : 0 : return 0;
26 : : }
27 : :
28 : : static int
29 : 0 : sfc_vdpa_set_mac_filter(efx_nic_t *nic, efx_filter_spec_t *spec,
30 : : int qid, uint8_t *eth_addr)
31 : : {
32 : : int rc;
33 : :
34 [ # # ]: 0 : if (nic == NULL || spec == NULL)
35 : : return -1;
36 : :
37 : 0 : spec->efs_priority = EFX_FILTER_PRI_MANUAL;
38 : 0 : spec->efs_flags = EFX_FILTER_FLAG_RX;
39 : 0 : spec->efs_dmaq_id = qid;
40 : :
41 [ # # ]: 0 : if (eth_addr == NULL)
42 : 0 : rc = efx_filter_spec_set_mc_def(spec);
43 : : else
44 : 0 : rc = efx_filter_spec_set_eth_local(spec,
45 : : EFX_FILTER_SPEC_VID_UNSPEC,
46 : : eth_addr);
47 [ # # ]: 0 : if (rc != 0)
48 : : return rc;
49 : :
50 : 0 : rc = efx_filter_insert(nic, spec);
51 [ # # ]: 0 : if (rc != 0)
52 : 0 : return rc;
53 : :
54 : : return rc;
55 : : }
56 : :
57 : 0 : int sfc_vdpa_filter_config(struct sfc_vdpa_ops_data *ops_data)
58 : : {
59 : : int rc;
60 : : int qid;
61 : : efx_nic_t *nic;
62 : : struct rte_ether_addr bcast_eth_addr;
63 : : struct rte_ether_addr ucast_eth_addr;
64 : 0 : struct sfc_vdpa_adapter *sva = ops_data->dev_handle;
65 : : efx_filter_spec_t *spec;
66 : :
67 : 0 : sfc_vdpa_log_init(sva, "entry");
68 : :
69 : 0 : nic = sva->nic;
70 : :
71 : 0 : sfc_vdpa_log_init(sva, "process kvarg");
72 : :
73 : : /* skip MAC filter configuration if mac address is not provided */
74 [ # # ]: 0 : if (rte_kvargs_count(sva->kvargs, SFC_VDPA_MAC_ADDR) == 0) {
75 : 0 : sfc_vdpa_warn(sva,
76 : : "MAC address is not provided, skipping MAC Filter Config");
77 : 0 : return -1;
78 : : }
79 : :
80 : 0 : rc = rte_kvargs_process(sva->kvargs, SFC_VDPA_MAC_ADDR,
81 : : &sfc_vdpa_get_eth_addr,
82 : : &ucast_eth_addr);
83 [ # # ]: 0 : if (rc < 0)
84 : : return -1;
85 : :
86 : : /* create filters on the base queue */
87 : : qid = SFC_VDPA_GET_VI_INDEX(0);
88 : :
89 : 0 : sfc_vdpa_log_init(sva, "insert broadcast mac filter");
90 : :
91 : 0 : EFX_MAC_BROADCAST_ADDR_SET(bcast_eth_addr.addr_bytes);
92 : 0 : spec = &sva->filters.spec[SFC_VDPA_BCAST_MAC_FILTER];
93 : :
94 : 0 : rc = sfc_vdpa_set_mac_filter(nic, spec, qid,
95 : : bcast_eth_addr.addr_bytes);
96 [ # # ]: 0 : if (rc != 0)
97 : 0 : sfc_vdpa_err(ops_data->dev_handle,
98 : : "broadcast MAC filter insertion failed: %s",
99 : : rte_strerror(rc));
100 : : else
101 : 0 : sva->filters.filter_cnt++;
102 : :
103 : 0 : sfc_vdpa_log_init(sva, "insert unicast mac filter");
104 : 0 : spec = &sva->filters.spec[SFC_VDPA_UCAST_MAC_FILTER];
105 : :
106 : 0 : rc = sfc_vdpa_set_mac_filter(nic, spec, qid,
107 : : ucast_eth_addr.addr_bytes);
108 [ # # ]: 0 : if (rc != 0)
109 : 0 : sfc_vdpa_err(sva, "unicast MAC filter insertion failed: %s",
110 : : rte_strerror(rc));
111 : : else
112 : 0 : sva->filters.filter_cnt++;
113 : :
114 : 0 : sfc_vdpa_log_init(sva, "insert unknown mcast filter");
115 : 0 : spec = &sva->filters.spec[SFC_VDPA_MCAST_DST_FILTER];
116 : :
117 : 0 : rc = sfc_vdpa_set_mac_filter(nic, spec, qid, NULL);
118 [ # # ]: 0 : if (rc != 0)
119 : 0 : sfc_vdpa_err(sva,
120 : : "mcast filter insertion failed: %s",
121 : : rte_strerror(rc));
122 : : else
123 : 0 : sva->filters.filter_cnt++;
124 : :
125 : 0 : sfc_vdpa_log_init(sva, "done");
126 : :
127 : 0 : return rc;
128 : : }
129 : :
130 : 0 : int sfc_vdpa_filter_remove(struct sfc_vdpa_ops_data *ops_data)
131 : : {
132 : : int i, rc = 0;
133 : 0 : struct sfc_vdpa_adapter *sva = ops_data->dev_handle;
134 : : efx_nic_t *nic;
135 : :
136 : 0 : nic = sva->nic;
137 : :
138 [ # # ]: 0 : for (i = 0; i < sva->filters.filter_cnt; i++) {
139 : 0 : rc = efx_filter_remove(nic, &(sva->filters.spec[i]));
140 [ # # ]: 0 : if (rc != 0)
141 : 0 : sfc_vdpa_err(sva,
142 : : "remove HW filter failed for entry %d: %s",
143 : : i, rte_strerror(rc));
144 : : }
145 : :
146 : 0 : sva->filters.filter_cnt = 0;
147 : :
148 : 0 : return rc;
149 : : }
|