Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2025 Yunsilicon Technology Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_dev_info.h>
6 : : #include <ethdev_pci.h>
7 : : #include <rte_interrupts.h>
8 : :
9 : : #include "xsc_log.h"
10 : : #include "xsc_defs.h"
11 : : #include "xsc_ethdev.h"
12 : : #include "xsc_rx.h"
13 : : #include "xsc_tx.h"
14 : : #include "xsc_dev.h"
15 : : #include "xsc_cmd.h"
16 : :
17 : : static int
18 : 0 : xsc_ethdev_rss_hash_conf_get(struct rte_eth_dev *dev,
19 : : struct rte_eth_rss_conf *rss_conf)
20 : : {
21 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
22 : :
23 [ # # # # ]: 0 : if (rss_conf->rss_key != NULL && rss_conf->rss_key_len >= priv->rss_conf.rss_key_len)
24 : 0 : memcpy(rss_conf->rss_key, priv->rss_conf.rss_key, priv->rss_conf.rss_key_len);
25 : :
26 : 0 : rss_conf->rss_key_len = priv->rss_conf.rss_key_len;
27 : 0 : rss_conf->rss_hf = priv->rss_conf.rss_hf;
28 : 0 : return 0;
29 : : }
30 : :
31 : : static int
32 : 0 : xsc_ethdev_rss_hash_update(struct rte_eth_dev *dev,
33 : : struct rte_eth_rss_conf *rss_conf)
34 : : {
35 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
36 : : int ret = 0;
37 : :
38 : 0 : ret = xsc_dev_rss_key_modify(priv->xdev, rss_conf->rss_key, rss_conf->rss_key_len);
39 [ # # ]: 0 : if (ret == 0) {
40 : 0 : memcpy(priv->rss_conf.rss_key, rss_conf->rss_key,
41 : 0 : priv->rss_conf.rss_key_len);
42 : 0 : priv->rss_conf.rss_key_len = rss_conf->rss_key_len;
43 : 0 : priv->rss_conf.rss_hf = rss_conf->rss_hf;
44 : : }
45 : :
46 : 0 : return ret;
47 : : }
48 : :
49 : : static int
50 : 0 : xsc_ethdev_configure(struct rte_eth_dev *dev)
51 : : {
52 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
53 : : int ret;
54 : : struct rte_eth_rss_conf *rss_conf;
55 : :
56 : 0 : priv->num_sq = dev->data->nb_tx_queues;
57 : 0 : priv->num_rq = dev->data->nb_rx_queues;
58 : :
59 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
60 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
61 : :
62 [ # # ]: 0 : if (priv->rss_conf.rss_key == NULL) {
63 : 0 : priv->rss_conf.rss_key = rte_zmalloc(NULL, XSC_RSS_HASH_KEY_LEN,
64 : : RTE_CACHE_LINE_SIZE);
65 [ # # ]: 0 : if (priv->rss_conf.rss_key == NULL) {
66 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc rss key");
67 : 0 : rte_errno = ENOMEM;
68 : : ret = -rte_errno;
69 : 0 : goto error;
70 : : }
71 : 0 : priv->rss_conf.rss_key_len = XSC_RSS_HASH_KEY_LEN;
72 : : }
73 : :
74 [ # # ]: 0 : if (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key != NULL) {
75 : 0 : rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
76 : 0 : ret = xsc_ethdev_rss_hash_update(dev, rss_conf);
77 [ # # ]: 0 : if (ret != 0) {
78 : 0 : PMD_DRV_LOG(ERR, "Xsc pmd set rss key error!");
79 : 0 : rte_errno = -ENOEXEC;
80 : 0 : goto error;
81 : : }
82 : : }
83 : :
84 : 0 : priv->txqs = (void *)dev->data->tx_queues;
85 : 0 : priv->rxqs = (void *)dev->data->rx_queues;
86 : 0 : return 0;
87 : :
88 : 0 : error:
89 : 0 : return -rte_errno;
90 : : }
91 : :
92 : : static void
93 : 0 : xsc_ethdev_txq_release(struct rte_eth_dev *dev, uint16_t idx)
94 : : {
95 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
96 [ # # ]: 0 : struct xsc_txq_data *txq_data = xsc_txq_get(priv, idx);
97 : 0 : uint8_t txq_state = dev->data->tx_queue_state[idx];
98 : :
99 [ # # ]: 0 : if (txq_data == NULL || txq_state == RTE_ETH_QUEUE_STATE_STOPPED)
100 : : return;
101 : :
102 : 0 : xsc_dev_set_qpsetid(priv->xdev, txq_data->qpn, 0);
103 : 0 : xsc_txq_obj_release(priv->xdev, txq_data);
104 : 0 : rte_free(txq_data->fcqs);
105 : 0 : txq_data->fcqs = NULL;
106 : 0 : xsc_txq_elts_free(txq_data);
107 : :
108 : 0 : dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
109 : : }
110 : :
111 : : static void
112 : 0 : xsc_ethdev_rxq_release(struct rte_eth_dev *dev, uint16_t idx)
113 : : {
114 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
115 [ # # ]: 0 : struct xsc_rxq_data *rxq_data = xsc_rxq_get(priv, idx);
116 : 0 : uint8_t rxq_state = dev->data->rx_queue_state[idx];
117 : :
118 [ # # ]: 0 : if (rxq_data == NULL || rxq_state == RTE_ETH_QUEUE_STATE_STOPPED)
119 : : return;
120 : :
121 : 0 : xsc_rxq_rss_obj_release(priv->xdev, rxq_data);
122 : 0 : xsc_rxq_elts_free(rxq_data);
123 : :
124 : 0 : dev->data->rx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
125 : : }
126 : :
127 : : static int
128 : 0 : xsc_ethdev_enable(struct rte_eth_dev *dev)
129 : : {
130 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
131 : : struct xsc_hwinfo *hwinfo;
132 : : int peer_dstinfo = 0;
133 : : int peer_logicalport = 0;
134 : : int logical_port = 0;
135 : : int local_dstinfo = 0;
136 : : int pcie_logic_port = 0;
137 : : int qp_set_id;
138 : : int repr_id;
139 : : struct xsc_rxq_data *rxq;
140 : : uint16_t rx_qpn;
141 : : int i, vld;
142 : : struct xsc_txq_data *txq;
143 : : struct xsc_repr_port *repr;
144 : : struct xsc_repr_info *repr_info;
145 : 0 : uint8_t mac_filter_en = !dev->data->promiscuous;
146 : :
147 [ # # ]: 0 : if (priv->funcid_type != XSC_PHYPORT_MAC_FUNCID)
148 : : return -ENODEV;
149 : :
150 : : rxq = xsc_rxq_get(priv, 0);
151 : : if (rxq == NULL)
152 : : return -EINVAL;
153 : :
154 : 0 : rx_qpn = (uint16_t)rxq->qpn;
155 : 0 : hwinfo = &priv->xdev->hwinfo;
156 : 0 : repr_id = priv->representor_id;
157 : 0 : repr = &priv->xdev->repr_ports[repr_id];
158 : : repr_info = &repr->info;
159 : :
160 : 0 : qp_set_id = xsc_dev_qp_set_id_get(priv->xdev, repr_id);
161 : 0 : logical_port = repr_info->logical_port;
162 : 0 : local_dstinfo = repr_info->local_dstinfo;
163 : 0 : peer_logicalport = repr_info->peer_logical_port;
164 : 0 : peer_dstinfo = repr_info->peer_dstinfo;
165 : :
166 : 0 : pcie_logic_port = hwinfo->pcie_no + 8;
167 : :
168 [ # # ]: 0 : for (i = 0; i < priv->num_sq; i++) {
169 : : txq = xsc_txq_get(priv, i);
170 : : if (txq == NULL)
171 : : return -EINVAL;
172 : 0 : xsc_dev_modify_qp_status(priv->xdev, txq->qpn, 1, XSC_CMD_OP_RTR2RTS_QP);
173 : 0 : xsc_dev_modify_qp_qostree(priv->xdev, txq->qpn);
174 : 0 : xsc_dev_set_qpsetid(priv->xdev, txq->qpn, qp_set_id);
175 : : }
176 : :
177 [ # # ]: 0 : if (!xsc_dev_is_vf(priv->xdev)) {
178 : 0 : xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo);
179 : 0 : xsc_dev_create_vfos_baselp(priv->xdev);
180 : 0 : xsc_dev_create_epat(priv->xdev, local_dstinfo, pcie_logic_port,
181 : 0 : rx_qpn - hwinfo->raw_rss_qp_id_base,
182 : 0 : priv->num_rq, &priv->rss_conf,
183 : 0 : mac_filter_en, priv->mac[0].addr_bytes);
184 : 0 : xsc_dev_create_pct(priv->xdev, repr_id, logical_port, peer_dstinfo);
185 : 0 : xsc_dev_create_pct(priv->xdev, repr_id, peer_logicalport, local_dstinfo);
186 : : } else {
187 : 0 : vld = xsc_dev_get_ipat_vld(priv->xdev, logical_port);
188 [ # # ]: 0 : if (vld == 0)
189 : 0 : xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo);
190 : 0 : xsc_dev_vf_modify_epat(priv->xdev, local_dstinfo,
191 : 0 : rx_qpn - hwinfo->raw_rss_qp_id_base,
192 : 0 : priv->num_rq, &priv->rss_conf,
193 : 0 : mac_filter_en, priv->mac[0].addr_bytes);
194 : : }
195 : :
196 : : return 0;
197 : : }
198 : :
199 : : static void
200 : : xsc_rxq_stop(struct rte_eth_dev *dev)
201 : : {
202 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
203 : : uint16_t i;
204 : :
205 [ # # # # : 0 : for (i = 0; i != priv->num_rq; ++i)
# # ]
206 : 0 : xsc_ethdev_rxq_release(dev, i);
207 : : }
208 : :
209 : : static void
210 : : xsc_txq_stop(struct rte_eth_dev *dev)
211 : : {
212 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
213 : : uint16_t i;
214 : :
215 [ # # # # : 0 : for (i = 0; i != priv->num_sq; ++i)
# # ]
216 : 0 : xsc_ethdev_txq_release(dev, i);
217 : : }
218 : :
219 : : static int
220 : 0 : xsc_txq_start(struct xsc_ethdev_priv *priv)
221 : : {
222 : : struct xsc_txq_data *txq_data;
223 : 0 : struct rte_eth_dev *dev = priv->eth_dev;
224 : : uint16_t i;
225 : : int ret;
226 : : size_t size;
227 : :
228 [ # # ]: 0 : for (i = 0; i != priv->num_sq; ++i) {
229 [ # # ]: 0 : txq_data = xsc_txq_get(priv, i);
230 : : if (txq_data == NULL)
231 : 0 : goto error;
232 : 0 : xsc_txq_elts_alloc(txq_data);
233 : 0 : ret = xsc_txq_obj_new(priv->xdev, txq_data, i);
234 [ # # ]: 0 : if (ret < 0)
235 : 0 : goto error;
236 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
237 : 0 : PMD_DRV_LOG(INFO, "Port %u create tx success", dev->data->port_id);
238 : :
239 : 0 : size = txq_data->cqe_s * sizeof(*txq_data->fcqs);
240 : 0 : txq_data->fcqs = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
241 [ # # ]: 0 : if (!txq_data->fcqs) {
242 : 0 : PMD_DRV_LOG(ERR, "Port %u txq %u alloc fcqs memory failed",
243 : : dev->data->port_id, i);
244 : 0 : rte_errno = ENOMEM;
245 : 0 : goto error;
246 : : }
247 : : }
248 : :
249 : : return 0;
250 : :
251 : 0 : error:
252 : : /* Queue resources are released by xsc_ethdev_start calling the stop interface */
253 : 0 : return -rte_errno;
254 : : }
255 : :
256 : : static int
257 : 0 : xsc_rxq_start(struct xsc_ethdev_priv *priv)
258 : : {
259 : : struct xsc_rxq_data *rxq_data;
260 : : uint16_t i;
261 : : int ret;
262 : :
263 [ # # ]: 0 : for (i = 0; i != priv->num_rq; ++i) {
264 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
265 : : if (rxq_data == NULL)
266 : 0 : goto error;
267 : 0 : ret = xsc_rxq_elts_alloc(rxq_data);
268 [ # # ]: 0 : if (ret != 0)
269 : 0 : goto error;
270 : : }
271 : :
272 : 0 : ret = xsc_rxq_rss_obj_new(priv, priv->dev_data->port_id);
273 [ # # ]: 0 : if (ret != 0)
274 : 0 : goto error;
275 : :
276 [ # # ]: 0 : for (i = 0; i != priv->num_rq; ++i)
277 : 0 : priv->dev_data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
278 : :
279 : : return 0;
280 : 0 : error:
281 : : /* Queue resources are released by xsc_ethdev_start calling the stop interface */
282 : 0 : return -rte_errno;
283 : : }
284 : :
285 : : static int
286 : 0 : xsc_ethdev_start(struct rte_eth_dev *dev)
287 : : {
288 : : int ret;
289 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
290 : :
291 : 0 : ret = xsc_txq_start(priv);
292 [ # # ]: 0 : if (ret) {
293 : 0 : PMD_DRV_LOG(ERR, "Port %u txq start failed: %s",
294 : : dev->data->port_id, strerror(rte_errno));
295 : 0 : goto error;
296 : : }
297 : :
298 : 0 : ret = xsc_rxq_start(priv);
299 [ # # ]: 0 : if (ret) {
300 : 0 : PMD_DRV_LOG(ERR, "Port %u Rx queue start failed: %s",
301 : : dev->data->port_id, strerror(rte_errno));
302 : 0 : goto error;
303 : : }
304 : :
305 : 0 : dev->data->dev_started = 1;
306 : :
307 : 0 : dev->rx_pkt_burst = xsc_rx_burst;
308 : 0 : dev->tx_pkt_burst = xsc_tx_burst;
309 : :
310 : 0 : ret = xsc_ethdev_enable(dev);
311 [ # # ]: 0 : if (ret) {
312 : 0 : PMD_DRV_LOG(ERR, "Failed to enable port: %u",
313 : : dev->data->port_id);
314 : 0 : goto error;
315 : : }
316 : :
317 : : return 0;
318 : :
319 : 0 : error:
320 : 0 : dev->data->dev_started = 0;
321 : : xsc_txq_stop(dev);
322 : : xsc_rxq_stop(dev);
323 : 0 : return -rte_errno;
324 : : }
325 : :
326 : : static int
327 : 0 : xsc_ethdev_stop(struct rte_eth_dev *dev)
328 : : {
329 : 0 : PMD_DRV_LOG(DEBUG, "Port %u stopping", dev->data->port_id);
330 : 0 : dev->data->dev_started = 0;
331 : 0 : dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
332 : 0 : dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
333 : : rte_wmb();
334 : :
335 : : xsc_txq_stop(dev);
336 : : xsc_rxq_stop(dev);
337 : :
338 : 0 : return 0;
339 : : }
340 : :
341 : : static int
342 : 0 : xsc_ethdev_close(struct rte_eth_dev *dev)
343 : : {
344 : : int idx;
345 : : struct xsc_rxq_data *rxq_data;
346 : : struct xsc_txq_data *txq_data;
347 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
348 : :
349 : 0 : PMD_DRV_LOG(DEBUG, "Port %u closing", dev->data->port_id);
350 : 0 : dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
351 : 0 : dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
352 : : rte_wmb();
353 : :
354 : : xsc_txq_stop(dev);
355 : : xsc_rxq_stop(dev);
356 : :
357 [ # # ]: 0 : for (idx = 0; idx < priv->num_rq; idx++) {
358 : : rxq_data = xsc_rxq_get(priv, idx);
359 : 0 : rte_free(rxq_data);
360 : 0 : dev->data->rx_queues[idx] = NULL;
361 : : }
362 : :
363 [ # # ]: 0 : for (idx = 0; idx < priv->num_sq; idx++) {
364 : : txq_data = xsc_txq_get(priv, idx);
365 : 0 : rte_free(txq_data);
366 : 0 : dev->data->tx_queues[idx] = NULL;
367 : : }
368 : :
369 : 0 : priv->rxqs = NULL;
370 : 0 : priv->txqs = NULL;
371 : :
372 : 0 : rte_free(priv->rss_conf.rss_key);
373 [ # # ]: 0 : if (!xsc_dev_is_vf(priv->xdev))
374 : 0 : xsc_dev_intr_handler_uninstall(priv->xdev);
375 : 0 : xsc_dev_close(priv->xdev, priv->representor_id);
376 : 0 : dev->data->mac_addrs = NULL;
377 : 0 : return 0;
378 : : }
379 : :
380 : : static int
381 : 0 : xsc_ethdev_set_link_up(struct rte_eth_dev *dev)
382 : : {
383 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
384 : 0 : struct xsc_dev *xdev = priv->xdev;
385 : :
386 [ # # ]: 0 : if (xsc_dev_is_vf(xdev))
387 : : return -ENOTSUP;
388 : 0 : return xsc_dev_link_status_set(xdev, RTE_ETH_LINK_UP);
389 : : }
390 : :
391 : : static int
392 : 0 : xsc_ethdev_set_link_down(struct rte_eth_dev *dev)
393 : : {
394 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
395 : 0 : struct xsc_dev *xdev = priv->xdev;
396 : :
397 [ # # ]: 0 : if (xsc_dev_is_vf(xdev))
398 : : return -ENOTSUP;
399 : 0 : return xsc_dev_link_status_set(xdev, RTE_ETH_LINK_DOWN);
400 : : }
401 : :
402 : : static int
403 : 0 : xsc_ethdev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
404 : : {
405 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
406 : 0 : struct xsc_dev *xdev = priv->xdev;
407 : 0 : struct rte_eth_link link = { };
408 : : int ret = 0;
409 : :
410 : : RTE_SET_USED(wait_to_complete);
411 : 0 : ret = xsc_dev_link_get(xdev, &link);
412 [ # # ]: 0 : if (ret != 0)
413 : : return ret;
414 : 0 : rte_eth_linkstatus_set(dev, &link);
415 : :
416 : 0 : return 0;
417 : : }
418 : :
419 : : static uint64_t
420 : : xsc_get_rx_queue_offloads(struct rte_eth_dev *dev)
421 : : {
422 : : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
423 : : struct xsc_dev_config *config = &priv->config;
424 : : uint64_t offloads = 0;
425 : :
426 : 0 : if (config->hw_csum)
427 : : offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
428 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
429 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM);
430 : :
431 : : return offloads;
432 : : }
433 : :
434 : : static uint64_t
435 : : xsc_get_tx_port_offloads(struct rte_eth_dev *dev)
436 : : {
437 : : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
438 : : uint64_t offloads = 0;
439 : : struct xsc_dev_config *config = &priv->config;
440 : :
441 : : if (config->hw_csum)
442 : : offloads |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
443 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
444 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
445 : 0 : if (config->tso)
446 : 0 : offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
447 : : return offloads;
448 : : }
449 : :
450 : : static int
451 : 0 : xsc_ethdev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
452 : : {
453 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
454 : :
455 : 0 : info->min_rx_bufsize = 64;
456 : 0 : info->max_rx_pktlen = 65536;
457 : 0 : info->max_lro_pkt_size = 0;
458 : 0 : info->max_rx_queues = 256;
459 : 0 : info->max_tx_queues = 1024;
460 : 0 : info->rx_desc_lim.nb_max = 4096;
461 : 0 : info->rx_desc_lim.nb_min = 16;
462 : 0 : info->tx_desc_lim.nb_max = 8192;
463 [ # # ]: 0 : info->tx_desc_lim.nb_min = 128;
464 : :
465 : 0 : info->rx_queue_offload_capa = xsc_get_rx_queue_offloads(dev);
466 [ # # ]: 0 : info->rx_offload_capa = info->rx_queue_offload_capa;
467 : 0 : info->tx_offload_capa = xsc_get_tx_port_offloads(dev);
468 : :
469 : 0 : info->if_index = priv->ifindex;
470 : 0 : info->speed_capa = priv->xdev->link_speed_capa;
471 : 0 : info->hash_key_size = XSC_RSS_HASH_KEY_LEN;
472 : 0 : info->tx_desc_lim.nb_seg_max = 8;
473 : 0 : info->tx_desc_lim.nb_mtu_seg_max = 8;
474 : 0 : info->switch_info.name = dev->data->name;
475 : 0 : info->switch_info.port_id = priv->representor_id;
476 : 0 : return 0;
477 : : }
478 : :
479 : : static int
480 : 0 : xsc_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
481 : : uint32_t socket, const struct rte_eth_rxconf *conf,
482 : : struct rte_mempool *mp)
483 : : {
484 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
485 : : struct xsc_rxq_data *rxq_data = NULL;
486 : : uint16_t desc_n;
487 : : uint16_t rx_free_thresh;
488 : 0 : uint64_t offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
489 : :
490 : 0 : desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
491 : : desc_n = desc;
492 : :
493 [ # # ]: 0 : if (!rte_is_power_of_2(desc))
494 : 0 : desc_n = 1 << rte_log2_u32(desc);
495 : :
496 : 0 : rxq_data = rte_malloc_socket(NULL, sizeof(*rxq_data) + desc_n * sizeof(struct rte_mbuf *),
497 : : RTE_CACHE_LINE_SIZE, socket);
498 [ # # ]: 0 : if (rxq_data == NULL) {
499 : 0 : PMD_DRV_LOG(ERR, "Port %u create rxq idx %d failure",
500 : : dev->data->port_id, idx);
501 : 0 : rte_errno = ENOMEM;
502 : 0 : return -rte_errno;
503 : : }
504 : 0 : rxq_data->idx = idx;
505 : 0 : rxq_data->priv = priv;
506 : 0 : (*priv->rxqs)[idx] = rxq_data;
507 : :
508 [ # # ]: 0 : rx_free_thresh = (conf->rx_free_thresh) ? conf->rx_free_thresh : XSC_RX_FREE_THRESH;
509 : 0 : rxq_data->rx_free_thresh = rx_free_thresh;
510 : :
511 : 0 : rxq_data->elts = (struct rte_mbuf *(*)[desc_n])(rxq_data + 1);
512 : 0 : rxq_data->mp = mp;
513 : 0 : rxq_data->socket = socket;
514 : :
515 : 0 : rxq_data->csum = !!(offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM);
516 : 0 : rxq_data->hw_timestamp = !!(offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP);
517 : 0 : rxq_data->crc_present = 0;
518 : :
519 : 0 : rxq_data->wqe_n = rte_log2_u32(desc_n);
520 : 0 : rxq_data->wqe_s = desc_n;
521 : 0 : rxq_data->wqe_m = desc_n - 1;
522 : :
523 : 0 : rxq_data->port_id = dev->data->port_id;
524 : 0 : dev->data->rx_queues[idx] = rxq_data;
525 : 0 : return 0;
526 : : }
527 : :
528 : : static int
529 : 0 : xsc_ethdev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
530 : : uint32_t socket, const struct rte_eth_txconf *conf)
531 : : {
532 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
533 : : struct xsc_txq_data *txq;
534 : : uint16_t desc_n;
535 : :
536 : 0 : desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
537 : : desc_n = desc;
538 : :
539 [ # # ]: 0 : if (!rte_is_power_of_2(desc))
540 : 0 : desc_n = 1 << rte_log2_u32(desc);
541 : :
542 : 0 : txq = rte_malloc_socket(NULL, sizeof(*txq) + desc_n * sizeof(struct rte_mbuf *),
543 : : RTE_CACHE_LINE_SIZE, socket);
544 : 0 : txq->offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
545 : 0 : txq->priv = priv;
546 : 0 : txq->socket = socket;
547 : :
548 : 0 : txq->elts_n = rte_log2_u32(desc_n);
549 : 0 : txq->elts_s = desc_n;
550 : 0 : txq->elts_m = desc_n - 1;
551 : 0 : txq->port_id = dev->data->port_id;
552 : 0 : txq->idx = idx;
553 : :
554 : 0 : (*priv->txqs)[idx] = txq;
555 : 0 : return 0;
556 : : }
557 : :
558 : : static int
559 : 0 : xsc_ethdev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
560 : : {
561 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
562 : : int ret = 0;
563 : :
564 [ # # ]: 0 : if (priv->eth_type != RTE_ETH_REPRESENTOR_PF) {
565 : 0 : priv->mtu = mtu;
566 : 0 : return 0;
567 : : }
568 : :
569 : 0 : ret = xsc_dev_set_mtu(priv->xdev, mtu);
570 [ # # ]: 0 : if (ret) {
571 : 0 : PMD_DRV_LOG(ERR, "Mtu set to %u failure", mtu);
572 : 0 : return -EAGAIN;
573 : : }
574 : :
575 : 0 : priv->mtu = mtu;
576 : 0 : return 0;
577 : : }
578 : :
579 : : static int
580 : 0 : xsc_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
581 : : struct eth_queue_stats *qstats)
582 : : {
583 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
584 : 0 : uint32_t rxqs_n = priv->num_rq;
585 : 0 : uint32_t txqs_n = priv->num_sq;
586 : : uint32_t i, idx;
587 : : struct xsc_rxq_data *rxq;
588 : : struct xsc_txq_data *txq;
589 : :
590 [ # # ]: 0 : for (i = 0; i < rxqs_n; ++i) {
591 [ # # ]: 0 : rxq = xsc_rxq_get(priv, i);
592 [ # # ]: 0 : if (unlikely(rxq == NULL))
593 : 0 : continue;
594 : :
595 : 0 : idx = rxq->idx;
596 [ # # ]: 0 : if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
597 : 0 : qstats->q_ipackets[idx] += rxq->stats.rx_pkts;
598 : 0 : qstats->q_ibytes[idx] += rxq->stats.rx_bytes;
599 : 0 : qstats->q_errors[idx] += rxq->stats.rx_errors +
600 : 0 : rxq->stats.rx_nombuf;
601 : : }
602 : 0 : stats->ipackets += rxq->stats.rx_pkts;
603 : 0 : stats->ibytes += rxq->stats.rx_bytes;
604 : 0 : stats->ierrors += rxq->stats.rx_errors;
605 : 0 : stats->rx_nombuf += rxq->stats.rx_nombuf;
606 : : }
607 : :
608 [ # # ]: 0 : for (i = 0; i < txqs_n; ++i) {
609 [ # # ]: 0 : txq = xsc_txq_get(priv, i);
610 [ # # ]: 0 : if (unlikely(txq == NULL))
611 : 0 : continue;
612 : :
613 : 0 : idx = txq->idx;
614 [ # # ]: 0 : if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
615 : 0 : qstats->q_opackets[idx] += txq->stats.tx_pkts;
616 : 0 : qstats->q_obytes[idx] += txq->stats.tx_bytes;
617 : 0 : qstats->q_errors[idx] += txq->stats.tx_errors;
618 : : }
619 : 0 : stats->opackets += txq->stats.tx_pkts;
620 : 0 : stats->obytes += txq->stats.tx_bytes;
621 : 0 : stats->oerrors += txq->stats.tx_errors;
622 : : }
623 : :
624 : 0 : return 0;
625 : : }
626 : :
627 : : static int
628 : 0 : xsc_ethdev_stats_reset(struct rte_eth_dev *dev)
629 : : {
630 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
631 : 0 : uint32_t rxqs_n = priv->num_rq;
632 : 0 : uint32_t txqs_n = priv->num_sq;
633 : : uint32_t i;
634 : : struct xsc_rxq_data *rxq;
635 : : struct xsc_txq_data *txq;
636 : :
637 [ # # ]: 0 : for (i = 0; i < rxqs_n; ++i) {
638 [ # # ]: 0 : rxq = xsc_rxq_get(priv, i);
639 [ # # ]: 0 : if (unlikely(rxq == NULL))
640 : 0 : continue;
641 : 0 : memset(&rxq->stats, 0, sizeof(struct xsc_rxq_stats));
642 : : }
643 [ # # ]: 0 : for (i = 0; i < txqs_n; ++i) {
644 [ # # ]: 0 : txq = xsc_txq_get(priv, i);
645 [ # # ]: 0 : if (unlikely(txq == NULL))
646 : 0 : continue;
647 : 0 : memset(&txq->stats, 0, sizeof(struct xsc_txq_stats));
648 : : }
649 : :
650 : 0 : return 0;
651 : : }
652 : :
653 : : static int
654 : 0 : xsc_ethdev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uint32_t index)
655 : : {
656 : : int i;
657 : :
658 : 0 : rte_errno = EINVAL;
659 [ # # ]: 0 : if (index > XSC_MAX_MAC_ADDRESSES)
660 : : return -rte_errno;
661 : :
662 [ # # ]: 0 : if (rte_is_zero_ether_addr(mac))
663 : : return -rte_errno;
664 : :
665 [ # # ]: 0 : for (i = 0; i != XSC_MAX_MAC_ADDRESSES; ++i) {
666 [ # # ]: 0 : if (i == (int)index)
667 : 0 : continue;
668 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac)) != 0)
669 : 0 : continue;
670 : : /* Address already configured elsewhere, return with error */
671 : 0 : rte_errno = EADDRINUSE;
672 : 0 : return -rte_errno;
673 : : }
674 : :
675 : 0 : dev->data->mac_addrs[index] = *mac;
676 : 0 : return 0;
677 : : }
678 : :
679 : : static int
680 : 0 : xsc_set_promiscuous(struct rte_eth_dev *dev, uint8_t mac_filter_en)
681 : : {
682 : : int repr_id;
683 : : struct xsc_repr_port *repr;
684 : : struct xsc_repr_info *repr_info;
685 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
686 : :
687 : 0 : repr_id = priv->representor_id;
688 : 0 : repr = &priv->xdev->repr_ports[repr_id];
689 : : repr_info = &repr->info;
690 : :
691 : 0 : return xsc_dev_modify_epat_mac_filter(priv->xdev,
692 : 0 : repr_info->local_dstinfo,
693 : : mac_filter_en);
694 : : }
695 : :
696 : : static int
697 : 0 : xsc_ethdev_promiscuous_enable(struct rte_eth_dev *dev)
698 : : {
699 : : int ret;
700 : :
701 : 0 : ret = xsc_set_promiscuous(dev, 0);
702 [ # # ]: 0 : if (ret != 0) {
703 : 0 : PMD_DRV_LOG(ERR, "Enable port %u promiscuous failure",
704 : : dev->data->port_id);
705 : 0 : return ret;
706 : : }
707 : :
708 : 0 : dev->data->promiscuous = 1;
709 : 0 : return 0;
710 : : }
711 : :
712 : : static int
713 : 0 : xsc_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
714 : : {
715 : : int ret;
716 : :
717 : 0 : ret = xsc_set_promiscuous(dev, 1);
718 [ # # ]: 0 : if (ret != 0) {
719 : 0 : PMD_DRV_LOG(ERR, "Disable port %u promiscuous failure",
720 : : dev->data->port_id);
721 : 0 : return ret;
722 : : }
723 : :
724 : 0 : dev->data->promiscuous = 0;
725 : 0 : return 0;
726 : : }
727 : :
728 : : static int
729 : 0 : xsc_ethdev_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
730 : : {
731 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
732 : :
733 : 0 : return xsc_dev_fw_version_get(priv->xdev, fw_version, fw_size);
734 : : }
735 : :
736 : : static int
737 : 0 : xsc_ethdev_get_module_info(struct rte_eth_dev *dev,
738 : : struct rte_eth_dev_module_info *modinfo)
739 : : {
740 : : int size_read = 0;
741 : 0 : uint8_t data[4] = { 0 };
742 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
743 : :
744 : 0 : size_read = xsc_dev_query_module_eeprom(priv->xdev, 0, 3, data);
745 [ # # ]: 0 : if (size_read < 3)
746 : : return -1;
747 : :
748 : : /* data[0] = identifier byte */
749 [ # # # # : 0 : switch (data[0]) {
# ]
750 : 0 : case XSC_MODULE_ID_QSFP:
751 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8436;
752 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
753 : 0 : break;
754 : 0 : case XSC_MODULE_ID_QSFP_PLUS:
755 : : case XSC_MODULE_ID_QSFP28:
756 : : /* data[1] = revision id */
757 [ # # # # ]: 0 : if (data[0] == XSC_MODULE_ID_QSFP28 || data[1] >= 0x3) {
758 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8636;
759 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
760 : : } else {
761 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8436;
762 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
763 : : }
764 : : break;
765 : 0 : case XSC_MODULE_ID_SFP:
766 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8472;
767 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
768 : 0 : break;
769 : 0 : case XSC_MODULE_ID_QSFP_DD:
770 : : case XSC_MODULE_ID_DSFP:
771 : : case XSC_MODULE_ID_QSFP_PLUS_CMIS:
772 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8636;
773 : : /* Verify if module EEPROM is a flat memory. In case of flat
774 : : * memory only page 00h (0-255 bytes) can be read. Otherwise
775 : : * upper pages 01h and 02h can also be read. Upper pages 10h
776 : : * and 11h are currently not supported by the driver.
777 : : */
778 [ # # ]: 0 : if (data[2] & 0x80)
779 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_LEN;
780 : : else
781 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
782 : : break;
783 : 0 : default:
784 : 0 : PMD_DRV_LOG(ERR, "Cable type 0x%x not recognized",
785 : : data[0]);
786 : 0 : return -EINVAL;
787 : : }
788 : :
789 : : return 0;
790 : : }
791 : :
792 : : static int
793 : 0 : xsc_ethdev_get_module_eeprom(struct rte_eth_dev *dev,
794 : : struct rte_dev_eeprom_info *info)
795 : : {
796 : : uint32_t i = 0;
797 : : uint8_t *data;
798 : : int size_read;
799 : 0 : uint32_t offset = info->offset;
800 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
801 : :
802 [ # # ]: 0 : if (info->length == 0) {
803 : 0 : PMD_DRV_LOG(ERR, "Failed to get module eeprom, eeprom length is 0");
804 : 0 : rte_errno = EINVAL;
805 : 0 : return -rte_errno;
806 : : }
807 : :
808 : 0 : data = malloc(info->length);
809 [ # # ]: 0 : if (data == NULL) {
810 : 0 : PMD_DRV_LOG(ERR, "Failed to get module eeprom, cannot allocate memory");
811 : 0 : rte_errno = ENOMEM;
812 : 0 : return -rte_errno;
813 : : }
814 : : memset(data, 0, info->length);
815 : :
816 [ # # ]: 0 : while (i < info->length) {
817 : 0 : size_read = xsc_dev_query_module_eeprom(priv->xdev, offset,
818 : 0 : info->length - i, data + i);
819 [ # # ]: 0 : if (!size_read)
820 : : /* Done reading */
821 : 0 : goto exit;
822 : :
823 [ # # ]: 0 : if (size_read < 0) {
824 : 0 : PMD_DRV_LOG(ERR, "Failed to get module eeprom, size read=%d",
825 : : size_read);
826 : 0 : goto exit;
827 : : }
828 : :
829 : 0 : i += size_read;
830 : 0 : offset += size_read;
831 : : }
832 : :
833 : 0 : memcpy(info->data, data, info->length);
834 : :
835 : 0 : exit:
836 : 0 : free(data);
837 : 0 : return 0;
838 : : }
839 : :
840 : : static int
841 : 0 : xsc_ethdev_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
842 : : {
843 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
844 : :
845 : 0 : return xsc_dev_fec_get(priv->xdev, fec_capa);
846 : : }
847 : :
848 : : static int
849 : 0 : xsc_ethdev_fec_set(struct rte_eth_dev *dev, uint32_t mode)
850 : : {
851 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
852 : :
853 : 0 : return xsc_dev_fec_set(priv->xdev, mode);
854 : : }
855 : :
856 : : const struct eth_dev_ops xsc_eth_dev_ops = {
857 : : .dev_configure = xsc_ethdev_configure,
858 : : .dev_start = xsc_ethdev_start,
859 : : .dev_stop = xsc_ethdev_stop,
860 : : .dev_set_link_up = xsc_ethdev_set_link_up,
861 : : .dev_set_link_down = xsc_ethdev_set_link_down,
862 : : .dev_close = xsc_ethdev_close,
863 : : .link_update = xsc_ethdev_link_update,
864 : : .promiscuous_enable = xsc_ethdev_promiscuous_enable,
865 : : .promiscuous_disable = xsc_ethdev_promiscuous_disable,
866 : : .stats_get = xsc_ethdev_stats_get,
867 : : .stats_reset = xsc_ethdev_stats_reset,
868 : : .dev_infos_get = xsc_ethdev_infos_get,
869 : : .rx_queue_setup = xsc_ethdev_rx_queue_setup,
870 : : .tx_queue_setup = xsc_ethdev_tx_queue_setup,
871 : : .rx_queue_release = xsc_ethdev_rxq_release,
872 : : .tx_queue_release = xsc_ethdev_txq_release,
873 : : .mtu_set = xsc_ethdev_set_mtu,
874 : : .rss_hash_update = xsc_ethdev_rss_hash_update,
875 : : .rss_hash_conf_get = xsc_ethdev_rss_hash_conf_get,
876 : : .fw_version_get = xsc_ethdev_fw_version_get,
877 : : .get_module_info = xsc_ethdev_get_module_info,
878 : : .get_module_eeprom = xsc_ethdev_get_module_eeprom,
879 : : .fec_get = xsc_ethdev_fec_get,
880 : : .fec_set = xsc_ethdev_fec_set,
881 : : };
882 : :
883 : : static int
884 : 0 : xsc_ethdev_init_one_representor(struct rte_eth_dev *eth_dev, void *init_params)
885 : : {
886 : : int ret;
887 : : struct xsc_repr_port *repr_port = (struct xsc_repr_port *)init_params;
888 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
889 : : struct xsc_dev_config *config = &priv->config;
890 : 0 : struct rte_ether_addr mac = priv->mac[0];
891 : :
892 : 0 : priv->repr_port = repr_port;
893 : 0 : repr_port->drv_data = eth_dev;
894 : 0 : priv->xdev = repr_port->xdev;
895 : 0 : priv->mtu = RTE_ETHER_MTU;
896 : 0 : priv->funcid_type = (repr_port->info.funcid & XSC_FUNCID_TYPE_MASK) >> 14;
897 : 0 : priv->funcid = repr_port->info.funcid & XSC_FUNCID_MASK;
898 [ # # ]: 0 : if (repr_port->info.port_type == XSC_PORT_TYPE_UPLINK ||
899 : : repr_port->info.port_type == XSC_PORT_TYPE_UPLINK_BOND)
900 : 0 : priv->eth_type = RTE_ETH_REPRESENTOR_PF;
901 : : else
902 : 0 : priv->eth_type = RTE_ETH_REPRESENTOR_VF;
903 : 0 : priv->representor_id = repr_port->info.repr_id;
904 : 0 : priv->dev_data = eth_dev->data;
905 : 0 : priv->ifindex = repr_port->info.ifindex;
906 : :
907 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
908 [ # # ]: 0 : eth_dev->data->mac_addrs = priv->mac;
909 [ # # ]: 0 : if (rte_is_zero_ether_addr(eth_dev->data->mac_addrs)) {
910 : 0 : ret = xsc_dev_get_mac(priv->xdev, mac.addr_bytes);
911 [ # # ]: 0 : if (ret != 0) {
912 : 0 : PMD_DRV_LOG(ERR, "Port %u cannot get MAC address",
913 : : eth_dev->data->port_id);
914 : 0 : return -ENODEV;
915 : : }
916 : : }
917 : :
918 : 0 : xsc_ethdev_mac_addr_add(eth_dev, &mac, 0);
919 : :
920 : 0 : config->hw_csum = 1;
921 : 0 : config->pph_flag = priv->xdev->devargs.pph_mode;
922 [ # # ]: 0 : if ((config->pph_flag & XSC_TX_PPH) != 0) {
923 : 0 : config->tso = 0;
924 : : } else {
925 : 0 : config->tso = 1;
926 : 0 : config->tso_max_payload_sz = 1500;
927 : : }
928 : :
929 : 0 : priv->is_representor = 1;
930 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
931 : 0 : eth_dev->data->representor_id = priv->representor_id;
932 : 0 : eth_dev->data->backer_port_id = eth_dev->data->port_id;
933 : :
934 : 0 : eth_dev->dev_ops = &xsc_eth_dev_ops;
935 : 0 : eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
936 : 0 : eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
937 : :
938 : 0 : rte_eth_dev_probing_finish(eth_dev);
939 : :
940 : 0 : return 0;
941 : : }
942 : :
943 : : static int
944 : 0 : xsc_ethdev_init_representors(struct rte_eth_dev *eth_dev)
945 : : {
946 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
947 : 0 : struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
948 : : struct rte_device *dev;
949 : : struct xsc_dev *xdev;
950 : : struct xsc_repr_port *repr_port;
951 : : char name[RTE_ETH_NAME_MAX_LEN];
952 : : int i;
953 : : int ret;
954 : :
955 : 0 : PMD_INIT_FUNC_TRACE();
956 : :
957 : 0 : dev = &priv->pci_dev->device;
958 [ # # ]: 0 : if (dev->devargs != NULL) {
959 : 0 : ret = rte_eth_devargs_parse(dev->devargs->args, ð_da, 1);
960 [ # # ]: 0 : if (ret < 0) {
961 : 0 : PMD_DRV_LOG(ERR, "Failed to parse device arguments: %s",
962 : : dev->devargs->args);
963 : 0 : return -EINVAL;
964 : : }
965 : : }
966 : :
967 : 0 : xdev = priv->xdev;
968 : 0 : ret = xsc_dev_repr_ports_probe(xdev, eth_da.nb_representor_ports, RTE_MAX_ETHPORTS);
969 [ # # ]: 0 : if (ret != 0) {
970 : 0 : PMD_DRV_LOG(ERR, "Failed to probe %d xsc device representors",
971 : : eth_da.nb_representor_ports);
972 : 0 : return ret;
973 : : }
974 : :
975 : : /* PF rep init */
976 : 0 : repr_port = &xdev->repr_ports[xdev->num_repr_ports - 1];
977 : 0 : ret = xsc_ethdev_init_one_representor(eth_dev, repr_port);
978 [ # # ]: 0 : if (ret != 0) {
979 : 0 : PMD_DRV_LOG(ERR, "Failed to init backing representor");
980 : 0 : return ret;
981 : : }
982 : :
983 : : /* VF rep init */
984 [ # # ]: 0 : for (i = 0; i < eth_da.nb_representor_ports; i++) {
985 : 0 : repr_port = &xdev->repr_ports[i];
986 : 0 : snprintf(name, sizeof(name), "%s_rep_%d",
987 : 0 : xdev->name, repr_port->info.repr_id);
988 : 0 : ret = rte_eth_dev_create(dev,
989 : : name,
990 : : sizeof(struct xsc_ethdev_priv),
991 : : NULL, NULL,
992 : : xsc_ethdev_init_one_representor,
993 : : repr_port);
994 [ # # ]: 0 : if (ret != 0) {
995 : 0 : PMD_DRV_LOG(ERR, "Failed to create representor: %d", i);
996 : 0 : goto destroy_reprs;
997 : : }
998 : : }
999 : :
1000 [ # # ]: 0 : if (!xsc_dev_is_vf(priv->xdev)) {
1001 : 0 : ret = xsc_ethdev_set_link_up(eth_dev);
1002 [ # # ]: 0 : if (ret != 0) {
1003 : 0 : PMD_DRV_LOG(ERR, "Failed to set port %u link up", eth_dev->data->port_id);
1004 : 0 : goto destroy_reprs;
1005 : : }
1006 : : }
1007 : :
1008 : : return 0;
1009 : :
1010 : 0 : destroy_reprs:
1011 : : /* Destroy vf reprs */
1012 [ # # ]: 0 : while ((i--) > 1) {
1013 : 0 : repr_port = &xdev->repr_ports[i];
1014 : 0 : rte_eth_dev_destroy((struct rte_eth_dev *)repr_port->drv_data, NULL);
1015 : : }
1016 : :
1017 : : /* Destroy pf repr */
1018 : 0 : repr_port = &xdev->repr_ports[xdev->num_repr_ports - 1];
1019 : 0 : rte_eth_dev_destroy((struct rte_eth_dev *)repr_port->drv_data, NULL);
1020 : 0 : return ret;
1021 : : }
1022 : :
1023 : : static void
1024 : 0 : xsc_ethdev_intr_handler(void *param)
1025 : : {
1026 : : struct rte_eth_dev *eth_dev = param;
1027 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
1028 : : int event_type;
1029 : :
1030 : 0 : event_type = xsc_dev_intr_event_get(priv->xdev);
1031 [ # # ]: 0 : switch (event_type) {
1032 : 0 : case XSC_EVENT_TYPE_CHANGE_LINK:
1033 : 0 : PMD_DRV_LOG(DEBUG, "Get intr event type=%04x", event_type);
1034 : 0 : xsc_ethdev_link_update(eth_dev, 0);
1035 : 0 : rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
1036 : 0 : break;
1037 : : default:
1038 : : break;
1039 : : }
1040 : 0 : }
1041 : :
1042 : : static int
1043 : 0 : xsc_ethdev_init(struct rte_eth_dev *eth_dev)
1044 : : {
1045 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
1046 : : int ret;
1047 : :
1048 : 0 : PMD_INIT_FUNC_TRACE();
1049 : :
1050 : 0 : priv->eth_dev = eth_dev;
1051 : 0 : priv->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1052 : :
1053 : 0 : ret = xsc_dev_init(priv->pci_dev, &priv->xdev);
1054 [ # # ]: 0 : if (ret) {
1055 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize xsc device");
1056 : 0 : return ret;
1057 : : }
1058 : 0 : priv->xdev->port_id = eth_dev->data->port_id;
1059 : :
1060 : 0 : ret = xsc_ethdev_init_representors(eth_dev);
1061 [ # # ]: 0 : if (ret != 0) {
1062 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize representors");
1063 : 0 : goto uninit_xsc_dev;
1064 : : }
1065 : :
1066 [ # # ]: 0 : if (!xsc_dev_is_vf(priv->xdev)) {
1067 : 0 : ret = xsc_dev_intr_handler_install(priv->xdev, xsc_ethdev_intr_handler, eth_dev);
1068 [ # # ]: 0 : if (ret != 0) {
1069 : 0 : PMD_DRV_LOG(ERR, "Failed to install intr handler");
1070 : 0 : goto uninit_xsc_dev;
1071 : : }
1072 : : }
1073 : :
1074 : : return 0;
1075 : :
1076 : 0 : uninit_xsc_dev:
1077 : 0 : xsc_dev_uninit(priv->xdev);
1078 : 0 : return ret;
1079 : : }
1080 : :
1081 : : static int
1082 : 0 : xsc_ethdev_uninit(struct rte_eth_dev *eth_dev)
1083 : : {
1084 : : int ret = 0;
1085 : : uint16_t port_id;
1086 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
1087 : :
1088 : 0 : PMD_INIT_FUNC_TRACE();
1089 [ # # ]: 0 : RTE_ETH_FOREACH_DEV_OF(port_id, eth_dev->device) {
1090 [ # # ]: 0 : if (port_id != eth_dev->data->port_id)
1091 : 0 : ret |= rte_eth_dev_close(port_id);
1092 : : }
1093 : :
1094 : 0 : ret |= xsc_ethdev_close(eth_dev);
1095 : 0 : xsc_dev_pct_uninit(priv->xdev);
1096 : 0 : rte_free(priv->xdev);
1097 : :
1098 [ # # ]: 0 : return ret == 0 ? 0 : -EIO;
1099 : : }
1100 : :
1101 : : static int
1102 : 0 : xsc_ethdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1103 : : struct rte_pci_device *pci_dev)
1104 : : {
1105 : : int ret;
1106 : :
1107 : 0 : PMD_INIT_FUNC_TRACE();
1108 : :
1109 : 0 : ret = rte_eth_dev_pci_generic_probe(pci_dev,
1110 : : sizeof(struct xsc_ethdev_priv),
1111 : : xsc_ethdev_init);
1112 [ # # ]: 0 : if (ret) {
1113 : 0 : PMD_DRV_LOG(ERR, "Failed to probe ethdev: %s", pci_dev->name);
1114 : 0 : return ret;
1115 : : }
1116 : :
1117 : : return 0;
1118 : : }
1119 : :
1120 : : static int
1121 : 0 : xsc_ethdev_pci_remove(struct rte_pci_device *pci_dev)
1122 : : {
1123 : : int ret;
1124 : :
1125 : 0 : PMD_INIT_FUNC_TRACE();
1126 : :
1127 : 0 : ret = rte_eth_dev_pci_generic_remove(pci_dev, xsc_ethdev_uninit);
1128 [ # # ]: 0 : if (ret) {
1129 : 0 : PMD_DRV_LOG(ERR, "Could not remove ethdev: %s", pci_dev->name);
1130 : 0 : return ret;
1131 : : }
1132 : :
1133 : : return 0;
1134 : : }
1135 : :
1136 : : static const struct rte_pci_id xsc_ethdev_pci_id_map[] = {
1137 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MS) },
1138 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MSVF) },
1139 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVH) },
1140 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVHVF) },
1141 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVS) },
1142 : : { RTE_PCI_DEVICE(0, 0) },
1143 : : };
1144 : :
1145 : : static struct rte_pci_driver xsc_ethdev_pci_driver = {
1146 : : .id_table = xsc_ethdev_pci_id_map,
1147 : : .probe = xsc_ethdev_pci_probe,
1148 : : .remove = xsc_ethdev_pci_remove,
1149 : : };
1150 : :
1151 : 253 : RTE_PMD_REGISTER_PCI(net_xsc, xsc_ethdev_pci_driver);
1152 : : RTE_PMD_REGISTER_PCI_TABLE(net_xsc, xsc_ethdev_pci_id_map);
1153 : : RTE_PMD_REGISTER_PARAM_STRING(net_xsc,
1154 : : XSC_PPH_MODE_ARG "=<x>"
1155 : : XSC_NIC_MODE_ARG "=<x>"
1156 : : XSC_FLOW_MODE_ARG "=<x>");
1157 : :
1158 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(xsc_logtype_init, init, NOTICE);
1159 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(xsc_logtype_driver, driver, NOTICE);
|