Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_os.h>
6 : : #include <rte_tailq.h>
7 : : #include "sxe2_osal.h"
8 : : #include "sxe2_mac.h"
9 : : #include "sxe2_common_log.h"
10 : : #include "sxe2_ethdev.h"
11 : : #include "sxe2_switchdev.h"
12 : : #include "sxe2_cmd_chnl.h"
13 : : #include "sxe2_host_regs.h"
14 : :
15 : 0 : int32_t sxe2_uplink_clear(struct sxe2_adapter *adapter)
16 : : {
17 : 0 : int32_t ret = 0;
18 : :
19 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
20 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode is not switchdev");
21 : 0 : goto l_end;
22 : : }
23 : :
24 : 0 : ret = sxe2_drv_switchdev_uplink_config(adapter, false);
25 : 0 : l_end:
26 : 0 : return ret;
27 : : }
28 : :
29 : 0 : int32_t sxe2_uplink_set(struct sxe2_adapter *adapter)
30 : : {
31 : 0 : int32_t ret = 0;
32 : :
33 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
34 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode is not switchdev");
35 : 0 : goto l_end;
36 : : }
37 : :
38 : 0 : ret = sxe2_drv_switchdev_uplink_config(adapter, true);
39 : 0 : l_end:
40 : 0 : return ret;
41 : : }
42 : :
43 : 0 : int32_t sxe2_repr_clear(struct sxe2_adapter *adapter)
44 : : {
45 : 0 : int32_t ret = 0;
46 : 0 : uint16_t repr_id = 0;
47 : 0 : struct rte_eth_dev *repr_dev;
48 : 0 : struct sxe2_adapter *repr_adapter;
49 : 0 : struct sxe2_switchdev_repr_info repr_vf;
50 : :
51 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
52 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode is not switchdev");
53 : 0 : goto l_end;
54 : : }
55 : :
56 [ # # ]: 0 : for (repr_id = 0; repr_id < adapter->repr_ctxt.nb_repr_vf; repr_id++) {
57 : 0 : repr_dev = adapter->repr_ctxt.vf_rep_eth_dev[repr_id];
58 [ # # ]: 0 : if (!repr_dev)
59 : 0 : continue;
60 : 0 : repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_dev);
61 [ # # ]: 0 : if (repr_adapter &&
62 [ # # ]: 0 : repr_adapter->repr_priv_data &&
63 [ # # ]: 0 : repr_adapter->repr_priv_data->cp_vsi) {
64 : 0 : memset(&repr_vf, 0, sizeof(struct sxe2_switchdev_repr_info));
65 : :
66 : 0 : repr_vf.repr_pf_id = repr_adapter->repr_priv_data->repr_pf_id;
67 : 0 : repr_vf.repr_vf_id = repr_adapter->repr_priv_data->repr_vf_id;
68 : 0 : repr_vf.cp_vsi_id = repr_adapter->repr_priv_data->cp_vsi->vsi_id;
69 : 0 : repr_vf.repr_q_id = repr_adapter->repr_priv_data->repr_q_id;
70 : 0 : ret = sxe2_drv_switchdev_repr_vf_config(adapter, &repr_vf,
71 : : false);
72 : : }
73 : : }
74 : 0 : l_end:
75 : 0 : return ret;
76 : : }
77 : :
78 : 0 : int32_t sxe2_repr_set(struct sxe2_adapter *adapter)
79 : : {
80 : 0 : int32_t ret = 0;
81 : 0 : uint16_t repr_id = 0;
82 : 0 : struct rte_eth_dev *repr_dev;
83 : 0 : struct sxe2_adapter *repr_adapter;
84 : 0 : struct sxe2_switchdev_repr_info repr_vf;
85 : :
86 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
87 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode is not switchdev");
88 : 0 : goto l_end;
89 : : }
90 : :
91 [ # # ]: 0 : for (repr_id = 0; repr_id < adapter->repr_ctxt.nb_repr_vf; repr_id++) {
92 : 0 : repr_dev = adapter->repr_ctxt.vf_rep_eth_dev[repr_id];
93 [ # # ]: 0 : if (!repr_dev)
94 : 0 : continue;
95 : 0 : repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_dev);
96 [ # # ]: 0 : if (repr_adapter &&
97 [ # # ]: 0 : repr_adapter->repr_priv_data &&
98 [ # # ]: 0 : repr_adapter->repr_priv_data->cp_vsi) {
99 : 0 : memset(&repr_vf, 0, sizeof(struct sxe2_switchdev_repr_info));
100 : :
101 : 0 : repr_vf.repr_pf_id = repr_adapter->repr_priv_data->repr_pf_id;
102 : 0 : repr_vf.repr_vf_id = repr_adapter->repr_priv_data->repr_vf_id;
103 : 0 : repr_vf.cp_vsi_id = repr_adapter->repr_priv_data->cp_vsi->vsi_id;
104 : 0 : repr_vf.repr_q_id = repr_adapter->repr_priv_data->repr_q_id;
105 : 0 : ret = sxe2_drv_switchdev_repr_vf_config(adapter, &repr_vf, true);
106 : : }
107 : : }
108 : :
109 : 0 : l_end:
110 : 0 : return ret;
111 : : }
112 : :
113 : 0 : void sxe2_free_repr_info(struct rte_eth_dev *dev)
114 : : {
115 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
116 : :
117 [ # # ]: 0 : if (adapter->repr_ctxt.vf_rep_eth_dev) {
118 : 0 : rte_free(adapter->repr_ctxt.vf_rep_eth_dev);
119 : 0 : adapter->repr_ctxt.vf_rep_eth_dev = NULL;
120 : : }
121 : :
122 : 0 : adapter->repr_ctxt.nb_repr_vf = 0;
123 : 0 : }
124 : :
125 : 0 : static int32_t sxe2_switchdev_clear(struct sxe2_adapter *adapter)
126 : : {
127 : 0 : int32_t ret = 0;
128 : :
129 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
130 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode is not switchdev");
131 : 0 : goto l_end;
132 : : }
133 : :
134 : 0 : adapter->switchdev_info.is_switchdev = false;
135 : :
136 [ # # # # ]: 0 : if (!adapter->flow_isolate_cfg && adapter->flow_isolated)
137 : 0 : adapter->flow_isolated = false;
138 : :
139 : 0 : ret = sxe2_l2_rule_update(adapter);
140 [ # # ]: 0 : if (ret != 0)
141 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update l2 rule");
142 : :
143 : 0 : ret = sxe2_switchdev_rule_update(adapter);
144 [ # # ]: 0 : if (ret != 0)
145 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update switchdev rule");
146 : :
147 : 0 : l_end:
148 : 0 : return ret;
149 : : }
150 : :
151 : 0 : static int32_t sxe2_switchdev_set(struct sxe2_adapter *adapter)
152 : : {
153 : 0 : int32_t ret = 0;
154 : :
155 [ # # ]: 0 : if (adapter->switchdev_info.is_switchdev) {
156 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "Current mode switch dev");
157 : 0 : goto l_end;
158 : : }
159 : :
160 : 0 : adapter->switchdev_info.is_switchdev = true;
161 : :
162 [ # # # # ]: 0 : if (adapter->flow_isolate_cfg && !adapter->flow_isolated)
163 : 0 : adapter->flow_isolated = true;
164 : :
165 : 0 : ret = sxe2_l2_rule_update(adapter);
166 [ # # ]: 0 : if (ret != 0)
167 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update l2 rule");
168 : :
169 : 0 : ret = sxe2_switchdev_rule_update(adapter);
170 [ # # ]: 0 : if (ret != 0)
171 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to update switchdev rule");
172 : :
173 : 0 : l_end:
174 : 0 : return ret;
175 : : }
176 : :
177 : 0 : int32_t sxe2_switchdev_notify_callback(struct sxe2_adapter *adapter, bool set)
178 : : {
179 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
180 : 0 : int32_t ret = 0;
181 : 0 : bool cur_switchdev_set = false;
182 : :
183 [ # # ]: 0 : if (adapter->repr_ctxt.nb_repr_vf) {
184 : 0 : PMD_DEV_LOG_WARN(adapter, DRV, "switch dev notify remove dev");
185 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RMV, NULL);
186 : 0 : goto l_end;
187 : : }
188 : :
189 : 0 : ret = sxe2_drv_switchdev_mode_get(adapter, &cur_switchdev_set);
190 [ # # ]: 0 : if (ret) {
191 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get switchdev mode");
192 : 0 : ret = -EINVAL;
193 : 0 : goto l_end;
194 : : }
195 : :
196 [ # # ]: 0 : if (set != cur_switchdev_set) {
197 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "current switchdev mode miss macth");
198 : 0 : goto l_end;
199 : : }
200 : :
201 [ # # ]: 0 : if (set) {
202 : 0 : ret = sxe2_switchdev_set(adapter);
203 [ # # ]: 0 : if (ret != 0) {
204 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to set switchdev");
205 : 0 : goto l_end;
206 : : }
207 : : } else {
208 : 0 : ret = sxe2_switchdev_clear(adapter);
209 [ # # ]: 0 : if (ret != 0) {
210 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "Failed to clear switchdev");
211 : 0 : goto l_end;
212 : : }
213 : : }
214 : 0 : l_end:
215 : 0 : return ret;
216 : : }
217 : :
218 : 0 : int32_t sxe2_switchdev_init(struct rte_eth_dev *dev)
219 : : {
220 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
221 : :
222 : 0 : PMD_DEV_LOG_INFO(adapter, INIT, "switchdev init");
223 : :
224 [ # # ]: 0 : if (adapter->switchdev_info.is_switchdev)
225 : 0 : adapter->flow_isolated = true;
226 : :
227 : 0 : adapter->repr_priv_data = NULL;
228 : 0 : adapter->repr_ctxt.nb_repr_vf = 0;
229 : :
230 : 0 : return 0;
231 : : }
232 : :
233 : 0 : int32_t sxe2_switchdev_uninit(struct rte_eth_dev *dev)
234 : : {
235 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
236 : :
237 : 0 : PMD_DEV_LOG_INFO(adapter, INIT, "switchdev uinit");
238 : :
239 [ # # ]: 0 : if (adapter->repr_priv_data) {
240 : 0 : rte_free(adapter->repr_priv_data);
241 : 0 : adapter->repr_priv_data = NULL;
242 : : }
243 : :
244 : 0 : return 0;
245 : : }
246 : :
247 : 0 : int32_t sxe2_switchdev_dev_info_init(struct rte_eth_dev *dev,
248 : : struct sxe2_adapter *parent_adapter)
249 : : {
250 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
251 : 0 : struct sxe2_dev_info *dev_info = &adapter->dev_info;
252 : 0 : struct sxe2_dev_info *parent_dev_info = &parent_adapter->dev_info;
253 : 0 : struct sxe2_drv_dev_info_resp dev_info_resp = {0};
254 : 0 : struct sxe2_drv_dev_fw_info_resp dev_fw_info_resp = {0};
255 : 0 : int32_t ret = 0;
256 : :
257 : 0 : PMD_INIT_FUNC_TRACE();
258 : :
259 : 0 : dev_info->pci = parent_dev_info->pci;
260 : 0 : dev_info->pci.max_vfs = 0;
261 : :
262 : 0 : ret = sxe2_drv_dev_info_get(adapter, &dev_info_resp);
263 [ # # ]: 0 : if (ret) {
264 : 0 : PMD_LOG_ERR(INIT, "Failed to get device info, ret=[%d]", ret);
265 : 0 : goto l_end;
266 : : }
267 : :
268 : 0 : ret = sxe2_drv_dev_fw_info_get(adapter, &dev_fw_info_resp);
269 [ # # ]: 0 : if (ret) {
270 : 0 : PMD_LOG_ERR(INIT, "Failed to get device fw info, ret=[%d]", ret);
271 : 0 : goto l_end;
272 : : }
273 : 0 : dev_info->fw.build_id = dev_fw_info_resp.build_id;
274 : 0 : dev_info->fw.fix_version_id = dev_fw_info_resp.fix_version_id;
275 : 0 : dev_info->fw.sub_version_id = dev_fw_info_resp.sub_version_id;
276 : 0 : dev_info->fw.main_version_id = dev_fw_info_resp.main_version_id;
277 : :
278 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)dev_info_resp.mac_addr,
279 : 0 : (struct rte_ether_addr *)dev_info->mac.perm_addr);
280 : :
281 : 0 : l_end:
282 : 0 : return ret;
283 : : }
284 : :
285 : 0 : int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
286 : : struct sxe2_adapter *parent_adapter, uint16_t repr_id)
287 : : {
288 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
289 : 0 : struct sxe2_repr_private_data *repr_priv_data = adapter->repr_priv_data;
290 : 0 : int32_t ret = 0;
291 : :
292 [ # # ]: 0 : if (repr_priv_data != NULL)
293 : 0 : goto l_end;
294 : :
295 : 0 : repr_priv_data = rte_zmalloc("sxe2_repr_priv_data",
296 : : sizeof(struct sxe2_repr_private_data), 0);
297 [ # # ]: 0 : if (repr_priv_data == NULL) {
298 : 0 : PMD_LOG_ERR(INIT, "Failed to malloc representor private data.");
299 : 0 : ret = -EINVAL;
300 : 0 : goto l_end;
301 : : }
302 : :
303 : 0 : repr_priv_data->parent_adapter = parent_adapter;
304 : 0 : repr_priv_data->repr_id = repr_id;
305 : 0 : repr_priv_data->cp_vsi =
306 : 0 : TAILQ_FIRST(&parent_adapter->vsi_ctxt.other_vsi_list);
307 [ # # ]: 0 : if (repr_priv_data->cp_vsi == NULL) {
308 : 0 : PMD_LOG_ERR(INIT, "Failed to get cp vsi.");
309 : 0 : ret = -EINVAL;
310 : 0 : goto l_free;
311 : : }
312 : 0 : repr_priv_data->repr_q_id = repr_id;
313 : 0 : repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
314 : 0 : repr_priv_data->repr_vf_id = repr_id;
315 : 0 : repr_priv_data->repr_vf_k_vsi_id =
316 : 0 : parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
317 : 0 : repr_priv_data->repr_vf_u_vsi_id =
318 : 0 : parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
319 : :
320 [ # # ]: 0 : repr_priv_data->repr_vf_vsi_id =
321 : : parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
322 : : SXE2_INVALID_VSI_ID ?
323 : : parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
324 : : parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
325 : :
326 : 0 : adapter->repr_priv_data = repr_priv_data;
327 : 0 : goto l_end;
328 : 0 : l_free:
329 : 0 : rte_free(repr_priv_data);
330 : 0 : l_end:
331 : 0 : return ret;
332 : : }
|