net/virtio: fix incorrect cast of void *
[dpdk.git] / sfc / sfc_vdpa_filter.c
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 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         if (value == NULL || extra_args == NULL)
20                 return -EINVAL;
21
22         /* Convert string with Ethernet address to an ether_addr */
23         rte_ether_unformat_addr(value, mac_addr);
24
25         return 0;
26 }
27
28 static int
29 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         if (nic == NULL || spec == NULL)
35                 return -1;
36
37         spec->efs_priority = EFX_FILTER_PRI_MANUAL;
38         spec->efs_flags = EFX_FILTER_FLAG_RX;
39         spec->efs_dmaq_id = qid;
40
41         if (eth_addr == NULL)
42                 rc = efx_filter_spec_set_mc_def(spec);
43         else
44                 rc = efx_filter_spec_set_eth_local(spec,
45                                                    EFX_FILTER_SPEC_VID_UNSPEC,
46                                                    eth_addr);
47         if (rc != 0)
48                 return rc;
49
50         rc = efx_filter_insert(nic, spec);
51         if (rc != 0)
52                 return rc;
53
54         return rc;
55 }
56
57 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         struct sfc_vdpa_adapter *sva = ops_data->dev_handle;
65         efx_filter_spec_t *spec;
66
67         sfc_vdpa_log_init(sva, "entry");
68
69         nic = sva->nic;
70
71         sfc_vdpa_log_init(sva, "process kvarg");
72
73         /* skip MAC filter configuration if mac address is not provided */
74         if (rte_kvargs_count(sva->kvargs, SFC_VDPA_MAC_ADDR) == 0) {
75                 sfc_vdpa_warn(sva,
76                               "MAC address is not provided, skipping MAC Filter Config");
77                 return -1;
78         }
79
80         rc = rte_kvargs_process(sva->kvargs, SFC_VDPA_MAC_ADDR,
81                                 &sfc_vdpa_get_eth_addr,
82                                 &ucast_eth_addr);
83         if (rc < 0)
84                 return -1;
85
86         /* create filters on the base queue */
87         qid = SFC_VDPA_GET_VI_INDEX(0);
88
89         sfc_vdpa_log_init(sva, "insert broadcast mac filter");
90
91         EFX_MAC_BROADCAST_ADDR_SET(bcast_eth_addr.addr_bytes);
92         spec = &sva->filters.spec[SFC_VDPA_BCAST_MAC_FILTER];
93
94         rc = sfc_vdpa_set_mac_filter(nic, spec, qid,
95                                      bcast_eth_addr.addr_bytes);
96         if (rc != 0)
97                 sfc_vdpa_err(ops_data->dev_handle,
98                              "broadcast MAC filter insertion failed: %s",
99                              rte_strerror(rc));
100         else
101                 sva->filters.filter_cnt++;
102
103         sfc_vdpa_log_init(sva, "insert unicast mac filter");
104         spec = &sva->filters.spec[SFC_VDPA_UCAST_MAC_FILTER];
105
106         rc = sfc_vdpa_set_mac_filter(nic, spec, qid,
107                                      ucast_eth_addr.addr_bytes);
108         if (rc != 0)
109                 sfc_vdpa_err(sva, "unicast MAC filter insertion failed: %s",
110                              rte_strerror(rc));
111         else
112                 sva->filters.filter_cnt++;
113
114         sfc_vdpa_log_init(sva, "insert unknown mcast filter");
115         spec = &sva->filters.spec[SFC_VDPA_MCAST_DST_FILTER];
116
117         rc = sfc_vdpa_set_mac_filter(nic, spec, qid, NULL);
118         if (rc != 0)
119                 sfc_vdpa_err(sva,
120                              "mcast filter insertion failed: %s",
121                              rte_strerror(rc));
122         else
123                 sva->filters.filter_cnt++;
124
125         sfc_vdpa_log_init(sva, "done");
126
127         return rc;
128 }
129
130 int sfc_vdpa_filter_remove(struct sfc_vdpa_ops_data *ops_data)
131 {
132         int i, rc = 0;
133         struct sfc_vdpa_adapter *sva = ops_data->dev_handle;
134         efx_nic_t *nic;
135
136         nic = sva->nic;
137
138         for (i = 0; i < sva->filters.filter_cnt; i++) {
139                 rc = efx_filter_remove(nic, &(sva->filters.spec[i]));
140                 if (rc != 0)
141                         sfc_vdpa_err(sva,
142                                      "remove HW filter failed for entry %d: %s",
143                                      i, rte_strerror(rc));
144         }
145
146         sva->filters.filter_cnt = 0;
147
148         return rc;
149 }