Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2025 Yunsilicon Technology Co., Ltd.
3 : : */
4 : :
5 : : #include <ethdev_pci.h>
6 : :
7 : : #include "xsc_log.h"
8 : : #include "xsc_defs.h"
9 : : #include "xsc_ethdev.h"
10 : : #include "xsc_rx.h"
11 : : #include "xsc_tx.h"
12 : : #include "xsc_dev.h"
13 : : #include "xsc_cmd.h"
14 : :
15 : : static int
16 : 0 : xsc_ethdev_rss_hash_conf_get(struct rte_eth_dev *dev,
17 : : struct rte_eth_rss_conf *rss_conf)
18 : : {
19 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
20 : :
21 [ # # # # ]: 0 : if (rss_conf->rss_key != NULL && rss_conf->rss_key_len >= priv->rss_conf.rss_key_len)
22 : 0 : memcpy(rss_conf->rss_key, priv->rss_conf.rss_key, priv->rss_conf.rss_key_len);
23 : :
24 : 0 : rss_conf->rss_key_len = priv->rss_conf.rss_key_len;
25 : 0 : rss_conf->rss_hf = priv->rss_conf.rss_hf;
26 : 0 : return 0;
27 : : }
28 : :
29 : : static int
30 : 0 : xsc_ethdev_rss_hash_update(struct rte_eth_dev *dev,
31 : : struct rte_eth_rss_conf *rss_conf)
32 : : {
33 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
34 : : int ret = 0;
35 : :
36 : 0 : ret = xsc_dev_rss_key_modify(priv->xdev, rss_conf->rss_key, rss_conf->rss_key_len);
37 [ # # ]: 0 : if (ret == 0) {
38 : 0 : memcpy(priv->rss_conf.rss_key, rss_conf->rss_key,
39 : 0 : priv->rss_conf.rss_key_len);
40 : 0 : priv->rss_conf.rss_key_len = rss_conf->rss_key_len;
41 : 0 : priv->rss_conf.rss_hf = rss_conf->rss_hf;
42 : : }
43 : :
44 : 0 : return ret;
45 : : }
46 : :
47 : : static int
48 : 0 : xsc_ethdev_configure(struct rte_eth_dev *dev)
49 : : {
50 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
51 : : int ret;
52 : : struct rte_eth_rss_conf *rss_conf;
53 : :
54 : 0 : priv->num_sq = dev->data->nb_tx_queues;
55 : 0 : priv->num_rq = dev->data->nb_rx_queues;
56 : :
57 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
58 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
59 : :
60 [ # # ]: 0 : if (priv->rss_conf.rss_key == NULL) {
61 : 0 : priv->rss_conf.rss_key = rte_zmalloc(NULL, XSC_RSS_HASH_KEY_LEN,
62 : : RTE_CACHE_LINE_SIZE);
63 [ # # ]: 0 : if (priv->rss_conf.rss_key == NULL) {
64 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc rss key");
65 : 0 : rte_errno = ENOMEM;
66 : : ret = -rte_errno;
67 : 0 : goto error;
68 : : }
69 : 0 : priv->rss_conf.rss_key_len = XSC_RSS_HASH_KEY_LEN;
70 : : }
71 : :
72 [ # # ]: 0 : if (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key != NULL) {
73 : 0 : rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
74 : 0 : ret = xsc_ethdev_rss_hash_update(dev, rss_conf);
75 [ # # ]: 0 : if (ret != 0) {
76 : 0 : PMD_DRV_LOG(ERR, "Xsc pmd set rss key error!");
77 : 0 : rte_errno = -ENOEXEC;
78 : 0 : goto error;
79 : : }
80 : : }
81 : :
82 : 0 : priv->txqs = (void *)dev->data->tx_queues;
83 : 0 : priv->rxqs = (void *)dev->data->rx_queues;
84 : 0 : return 0;
85 : :
86 : 0 : error:
87 : 0 : return -rte_errno;
88 : : }
89 : :
90 : : static void
91 : 0 : xsc_ethdev_txq_release(struct rte_eth_dev *dev, uint16_t idx)
92 : : {
93 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
94 [ # # ]: 0 : struct xsc_txq_data *txq_data = xsc_txq_get(priv, idx);
95 : :
96 : : if (txq_data == NULL)
97 : : return;
98 : :
99 : 0 : xsc_dev_set_qpsetid(priv->xdev, txq_data->qpn, 0);
100 : 0 : xsc_txq_obj_release(priv->xdev, txq_data);
101 : 0 : rte_free(txq_data->fcqs);
102 : 0 : txq_data->fcqs = NULL;
103 : 0 : xsc_txq_elts_free(txq_data);
104 : 0 : rte_free(txq_data);
105 : 0 : (*priv->txqs)[idx] = NULL;
106 : :
107 : 0 : dev->data->tx_queues[idx] = NULL;
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 : :
117 : : if (rxq_data == NULL)
118 : : return;
119 : 0 : xsc_rxq_rss_obj_release(priv->xdev, rxq_data);
120 : 0 : xsc_rxq_elts_free(rxq_data);
121 : 0 : rte_free(rxq_data);
122 : 0 : (*priv->rxqs)[idx] = NULL;
123 : :
124 : 0 : dev->data->rx_queues[idx] = NULL;
125 : 0 : dev->data->rx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED;
126 : : }
127 : :
128 : : static int
129 : 0 : xsc_ethdev_enable(struct rte_eth_dev *dev)
130 : : {
131 [ # # ]: 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
132 : : struct xsc_hwinfo *hwinfo;
133 : : int peer_dstinfo = 0;
134 : : int peer_logicalport = 0;
135 : : int logical_port = 0;
136 : : int local_dstinfo = 0;
137 : : int pcie_logic_port = 0;
138 : : int qp_set_id;
139 : : int repr_id;
140 : : struct xsc_rxq_data *rxq = xsc_rxq_get(priv, 0);
141 : 0 : uint16_t rx_qpn = (uint16_t)rxq->qpn;
142 : : int i, vld;
143 : : struct xsc_txq_data *txq;
144 : : struct xsc_repr_port *repr;
145 : : struct xsc_repr_info *repr_info;
146 : :
147 [ # # ]: 0 : if (priv->funcid_type != XSC_PHYPORT_MAC_FUNCID)
148 : : return -ENODEV;
149 : :
150 : 0 : hwinfo = &priv->xdev->hwinfo;
151 : 0 : repr_id = priv->representor_id;
152 : 0 : repr = &priv->xdev->repr_ports[repr_id];
153 : : repr_info = &repr->info;
154 : :
155 : 0 : qp_set_id = xsc_dev_qp_set_id_get(priv->xdev, repr_id);
156 : 0 : logical_port = repr_info->logical_port;
157 : 0 : local_dstinfo = repr_info->local_dstinfo;
158 : 0 : peer_logicalport = repr_info->peer_logical_port;
159 : 0 : peer_dstinfo = repr_info->peer_dstinfo;
160 : :
161 : 0 : pcie_logic_port = hwinfo->pcie_no + 8;
162 : :
163 [ # # ]: 0 : for (i = 0; i < priv->num_sq; i++) {
164 : : txq = xsc_txq_get(priv, i);
165 : 0 : xsc_dev_modify_qp_status(priv->xdev, txq->qpn, 1, XSC_CMD_OP_RTR2RTS_QP);
166 : 0 : xsc_dev_modify_qp_qostree(priv->xdev, txq->qpn);
167 : 0 : xsc_dev_set_qpsetid(priv->xdev, txq->qpn, qp_set_id);
168 : : }
169 : :
170 [ # # ]: 0 : if (!xsc_dev_is_vf(priv->xdev)) {
171 : 0 : xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo);
172 : 0 : xsc_dev_create_vfos_baselp(priv->xdev);
173 : 0 : xsc_dev_create_epat(priv->xdev, local_dstinfo, pcie_logic_port,
174 : 0 : rx_qpn - hwinfo->raw_rss_qp_id_base,
175 : 0 : priv->num_rq, &priv->rss_conf);
176 : 0 : xsc_dev_create_pct(priv->xdev, repr_id, logical_port, peer_dstinfo);
177 : 0 : xsc_dev_create_pct(priv->xdev, repr_id, peer_logicalport, local_dstinfo);
178 : : } else {
179 : 0 : vld = xsc_dev_get_ipat_vld(priv->xdev, logical_port);
180 [ # # ]: 0 : if (vld == 0)
181 : 0 : xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo);
182 : 0 : xsc_dev_vf_modify_epat(priv->xdev, local_dstinfo,
183 : 0 : rx_qpn - hwinfo->raw_rss_qp_id_base,
184 : 0 : priv->num_rq, &priv->rss_conf);
185 : : }
186 : :
187 : : return 0;
188 : : }
189 : :
190 : : static void
191 : 0 : xsc_rxq_stop(struct rte_eth_dev *dev)
192 : : {
193 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
194 : : uint16_t i;
195 : :
196 [ # # ]: 0 : for (i = 0; i != priv->num_rq; ++i)
197 : 0 : xsc_ethdev_rxq_release(dev, i);
198 : 0 : priv->rxqs = NULL;
199 : 0 : priv->flags &= ~XSC_FLAG_RX_QUEUE_INIT;
200 : 0 : }
201 : :
202 : : static void
203 : 0 : xsc_txq_stop(struct rte_eth_dev *dev)
204 : : {
205 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
206 : : uint16_t i;
207 : :
208 [ # # ]: 0 : for (i = 0; i != priv->num_sq; ++i)
209 : 0 : xsc_ethdev_txq_release(dev, i);
210 : 0 : priv->txqs = NULL;
211 : 0 : priv->flags &= ~XSC_FLAG_TX_QUEUE_INIT;
212 : 0 : }
213 : :
214 : : static int
215 : 0 : xsc_txq_start(struct xsc_ethdev_priv *priv)
216 : : {
217 : : struct xsc_txq_data *txq_data;
218 : 0 : struct rte_eth_dev *dev = priv->eth_dev;
219 : 0 : uint64_t offloads = dev->data->dev_conf.txmode.offloads;
220 : : uint16_t i;
221 : : int ret;
222 : : size_t size;
223 : :
224 [ # # ]: 0 : if (priv->flags & XSC_FLAG_TX_QUEUE_INIT) {
225 [ # # ]: 0 : for (i = 0; i != priv->num_sq; ++i)
226 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
227 : : return 0;
228 : : }
229 : :
230 [ # # ]: 0 : for (i = 0; i != priv->num_sq; ++i) {
231 [ # # ]: 0 : txq_data = xsc_txq_get(priv, i);
232 : 0 : xsc_txq_elts_alloc(txq_data);
233 : 0 : ret = xsc_txq_obj_new(priv->xdev, txq_data, offloads, 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 : 0 : priv->flags |= XSC_FLAG_TX_QUEUE_INIT;
250 : 0 : return 0;
251 : :
252 : 0 : error:
253 : : /* Queue resources are released by xsc_ethdev_start calling the stop interface */
254 : 0 : return -rte_errno;
255 : : }
256 : :
257 : : static int
258 : 0 : xsc_rxq_start(struct xsc_ethdev_priv *priv)
259 : : {
260 : : struct xsc_rxq_data *rxq_data;
261 : 0 : struct rte_eth_dev *dev = priv->eth_dev;
262 : : uint16_t i;
263 : : int ret;
264 : :
265 [ # # ]: 0 : if (priv->flags & XSC_FLAG_RX_QUEUE_INIT) {
266 [ # # ]: 0 : for (i = 0; i != priv->num_sq; ++i)
267 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
268 : : return 0;
269 : : }
270 : :
271 [ # # ]: 0 : for (i = 0; i != priv->num_rq; ++i) {
272 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
273 [ # # ]: 0 : if (dev->data->rx_queue_state[i] != RTE_ETH_QUEUE_STATE_STARTED) {
274 : 0 : ret = xsc_rxq_elts_alloc(rxq_data);
275 [ # # ]: 0 : if (ret != 0)
276 : 0 : goto error;
277 : : }
278 : : }
279 : :
280 : 0 : ret = xsc_rxq_rss_obj_new(priv, priv->dev_data->port_id);
281 [ # # ]: 0 : if (ret != 0)
282 : 0 : goto error;
283 : :
284 : 0 : priv->flags |= XSC_FLAG_RX_QUEUE_INIT;
285 : 0 : return 0;
286 : 0 : error:
287 : : /* Queue resources are released by xsc_ethdev_start calling the stop interface */
288 : 0 : return -rte_errno;
289 : : }
290 : :
291 : : static int
292 : 0 : xsc_ethdev_start(struct rte_eth_dev *dev)
293 : : {
294 : : int ret;
295 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
296 : :
297 : 0 : ret = xsc_txq_start(priv);
298 [ # # ]: 0 : if (ret) {
299 : 0 : PMD_DRV_LOG(ERR, "Port %u txq start failed: %s",
300 : : dev->data->port_id, strerror(rte_errno));
301 : 0 : goto error;
302 : : }
303 : :
304 : 0 : ret = xsc_rxq_start(priv);
305 [ # # ]: 0 : if (ret) {
306 : 0 : PMD_DRV_LOG(ERR, "Port %u Rx queue start failed: %s",
307 : : dev->data->port_id, strerror(rte_errno));
308 : 0 : goto error;
309 : : }
310 : :
311 : 0 : dev->data->dev_started = 1;
312 : :
313 : 0 : dev->rx_pkt_burst = xsc_rx_burst;
314 : 0 : dev->tx_pkt_burst = xsc_tx_burst;
315 : :
316 : 0 : ret = xsc_ethdev_enable(dev);
317 : :
318 : 0 : return 0;
319 : :
320 : 0 : error:
321 : 0 : dev->data->dev_started = 0;
322 : 0 : xsc_txq_stop(dev);
323 : 0 : xsc_rxq_stop(dev);
324 : 0 : return -rte_errno;
325 : : }
326 : :
327 : : static int
328 : 0 : xsc_ethdev_stop(struct rte_eth_dev *dev)
329 : : {
330 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
331 : : uint16_t i;
332 : :
333 : 0 : PMD_DRV_LOG(DEBUG, "Port %u stopping", dev->data->port_id);
334 : 0 : dev->data->dev_started = 0;
335 : 0 : dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
336 : 0 : dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
337 : : rte_wmb();
338 : :
339 : 0 : rte_delay_us_sleep(1000 * priv->num_rq);
340 [ # # ]: 0 : for (i = 0; i < priv->num_rq; ++i)
341 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
342 [ # # ]: 0 : for (i = 0; i < priv->num_sq; ++i)
343 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
344 : :
345 : 0 : return 0;
346 : : }
347 : :
348 : : static int
349 : 0 : xsc_ethdev_close(struct rte_eth_dev *dev)
350 : : {
351 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
352 : :
353 : 0 : PMD_DRV_LOG(DEBUG, "Port %u closing", dev->data->port_id);
354 : 0 : dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
355 : 0 : dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
356 : : rte_wmb();
357 : :
358 : 0 : xsc_txq_stop(dev);
359 : 0 : xsc_rxq_stop(dev);
360 : :
361 : 0 : rte_free(priv->rss_conf.rss_key);
362 : 0 : xsc_dev_close(priv->xdev, priv->representor_id);
363 : 0 : dev->data->mac_addrs = NULL;
364 : 0 : return 0;
365 : : }
366 : :
367 : : static int
368 : 0 : xsc_ethdev_set_link_up(struct rte_eth_dev *dev)
369 : : {
370 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
371 : 0 : struct xsc_dev *xdev = priv->xdev;
372 : :
373 : 0 : return xsc_dev_set_link_up(xdev);
374 : : }
375 : :
376 : : static int
377 : 0 : xsc_ethdev_set_link_down(struct rte_eth_dev *dev)
378 : : {
379 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
380 : 0 : struct xsc_dev *xdev = priv->xdev;
381 : :
382 : 0 : return xsc_dev_set_link_down(xdev);
383 : : }
384 : :
385 : : static int
386 : 0 : xsc_ethdev_link_update(struct rte_eth_dev *dev,
387 : : int wait_to_complete)
388 : : {
389 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
390 : 0 : struct xsc_dev *xdev = priv->xdev;
391 : : int ret = 0;
392 : :
393 : 0 : ret = xsc_dev_link_update(xdev, priv->funcid_type, wait_to_complete);
394 [ # # ]: 0 : if (ret == 0) {
395 : 0 : dev->data->dev_link = xdev->pf_dev_link;
396 : 0 : dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
397 : : RTE_ETH_LINK_SPEED_FIXED);
398 : : }
399 : 0 : return ret;
400 : : }
401 : :
402 : : static uint64_t
403 : : xsc_get_rx_queue_offloads(struct rte_eth_dev *dev)
404 : : {
405 : : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
406 : : struct xsc_dev_config *config = &priv->config;
407 : : uint64_t offloads = 0;
408 : :
409 : 0 : if (config->hw_csum)
410 : : offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
411 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
412 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM);
413 : :
414 : : return offloads;
415 : : }
416 : :
417 : : static uint64_t
418 : : xsc_get_tx_port_offloads(struct rte_eth_dev *dev)
419 : : {
420 : : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
421 : : uint64_t offloads = 0;
422 : : struct xsc_dev_config *config = &priv->config;
423 : :
424 : : if (config->hw_csum)
425 : : offloads |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
426 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
427 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
428 : 0 : if (config->tso)
429 : 0 : offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
430 : : return offloads;
431 : : }
432 : :
433 : : static int
434 : 0 : xsc_ethdev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
435 : : {
436 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
437 : :
438 : 0 : info->min_rx_bufsize = 64;
439 : 0 : info->max_rx_pktlen = 65536;
440 : 0 : info->max_lro_pkt_size = 0;
441 : 0 : info->max_rx_queues = 256;
442 : 0 : info->max_tx_queues = 1024;
443 : 0 : info->rx_desc_lim.nb_max = 4096;
444 : 0 : info->rx_desc_lim.nb_min = 16;
445 : 0 : info->tx_desc_lim.nb_max = 8192;
446 [ # # ]: 0 : info->tx_desc_lim.nb_min = 128;
447 : :
448 : 0 : info->rx_queue_offload_capa = xsc_get_rx_queue_offloads(dev);
449 [ # # ]: 0 : info->rx_offload_capa = info->rx_queue_offload_capa;
450 : 0 : info->tx_offload_capa = xsc_get_tx_port_offloads(dev);
451 : :
452 : 0 : info->if_index = priv->ifindex;
453 : 0 : info->speed_capa = priv->xdev->link_speed_capa;
454 : 0 : info->hash_key_size = XSC_RSS_HASH_KEY_LEN;
455 : 0 : info->tx_desc_lim.nb_seg_max = 8;
456 : 0 : info->tx_desc_lim.nb_mtu_seg_max = 8;
457 : 0 : info->switch_info.name = dev->data->name;
458 : 0 : info->switch_info.port_id = priv->representor_id;
459 : 0 : return 0;
460 : : }
461 : :
462 : : static int
463 : 0 : xsc_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
464 : : uint32_t socket, const struct rte_eth_rxconf *conf,
465 : : struct rte_mempool *mp)
466 : : {
467 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
468 : : struct xsc_rxq_data *rxq_data = NULL;
469 : : uint16_t desc_n;
470 : : uint16_t rx_free_thresh;
471 : 0 : uint64_t offloads = conf->offloads | dev->data->dev_conf.rxmode.offloads;
472 : :
473 : 0 : desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
474 : : desc_n = desc;
475 : :
476 [ # # ]: 0 : if (!rte_is_power_of_2(desc))
477 : 0 : desc_n = 1 << rte_log2_u32(desc);
478 : :
479 : 0 : rxq_data = rte_malloc_socket(NULL, sizeof(*rxq_data) + desc_n * sizeof(struct rte_mbuf *),
480 : : RTE_CACHE_LINE_SIZE, socket);
481 [ # # ]: 0 : if (rxq_data == NULL) {
482 : 0 : PMD_DRV_LOG(ERR, "Port %u create rxq idx %d failure",
483 : : dev->data->port_id, idx);
484 : 0 : rte_errno = ENOMEM;
485 : 0 : return -rte_errno;
486 : : }
487 : 0 : rxq_data->idx = idx;
488 : 0 : rxq_data->priv = priv;
489 : 0 : (*priv->rxqs)[idx] = rxq_data;
490 : :
491 [ # # ]: 0 : rx_free_thresh = (conf->rx_free_thresh) ? conf->rx_free_thresh : XSC_RX_FREE_THRESH;
492 : 0 : rxq_data->rx_free_thresh = rx_free_thresh;
493 : :
494 : 0 : rxq_data->elts = (struct rte_mbuf *(*)[desc_n])(rxq_data + 1);
495 : 0 : rxq_data->mp = mp;
496 : 0 : rxq_data->socket = socket;
497 : :
498 : 0 : rxq_data->csum = !!(offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM);
499 : 0 : rxq_data->hw_timestamp = !!(offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP);
500 : 0 : rxq_data->crc_present = 0;
501 : :
502 : 0 : rxq_data->wqe_n = rte_log2_u32(desc_n);
503 : 0 : rxq_data->wqe_s = desc_n;
504 : 0 : rxq_data->wqe_m = desc_n - 1;
505 : :
506 : 0 : rxq_data->port_id = dev->data->port_id;
507 : 0 : dev->data->rx_queues[idx] = rxq_data;
508 : 0 : return 0;
509 : : }
510 : :
511 : : static int
512 : 0 : xsc_ethdev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
513 : : uint32_t socket, const struct rte_eth_txconf *conf)
514 : : {
515 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
516 : : struct xsc_txq_data *txq;
517 : : uint16_t desc_n;
518 : :
519 : 0 : desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
520 : : desc_n = desc;
521 : :
522 [ # # ]: 0 : if (!rte_is_power_of_2(desc))
523 : 0 : desc_n = 1 << rte_log2_u32(desc);
524 : :
525 : 0 : txq = rte_malloc_socket(NULL, sizeof(*txq) + desc_n * sizeof(struct rte_mbuf *),
526 : : RTE_CACHE_LINE_SIZE, socket);
527 : 0 : txq->offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
528 : 0 : txq->priv = priv;
529 : 0 : txq->socket = socket;
530 : :
531 : 0 : txq->elts_n = rte_log2_u32(desc_n);
532 : 0 : txq->elts_s = desc_n;
533 : 0 : txq->elts_m = desc_n - 1;
534 : 0 : txq->port_id = dev->data->port_id;
535 : 0 : txq->idx = idx;
536 : :
537 : 0 : (*priv->txqs)[idx] = txq;
538 : 0 : return 0;
539 : : }
540 : :
541 : : static int
542 : 0 : xsc_ethdev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
543 : : {
544 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
545 : : int ret = 0;
546 : :
547 [ # # ]: 0 : if (priv->eth_type != RTE_ETH_REPRESENTOR_PF) {
548 : 0 : priv->mtu = mtu;
549 : 0 : return 0;
550 : : }
551 : :
552 : 0 : ret = xsc_dev_set_mtu(priv->xdev, mtu);
553 [ # # ]: 0 : if (ret) {
554 : 0 : PMD_DRV_LOG(ERR, "Mtu set to %u failure", mtu);
555 : 0 : return -EAGAIN;
556 : : }
557 : :
558 : 0 : priv->mtu = mtu;
559 : 0 : return 0;
560 : : }
561 : :
562 : : static int
563 : 0 : xsc_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
564 : : {
565 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
566 : 0 : uint32_t rxqs_n = priv->num_rq;
567 : 0 : uint32_t txqs_n = priv->num_sq;
568 : : uint32_t i, idx;
569 : : struct xsc_rxq_data *rxq;
570 : : struct xsc_txq_data *txq;
571 : :
572 [ # # ]: 0 : for (i = 0; i < rxqs_n; ++i) {
573 [ # # ]: 0 : rxq = xsc_rxq_get(priv, i);
574 [ # # ]: 0 : if (unlikely(rxq == NULL))
575 : 0 : continue;
576 : :
577 : 0 : idx = rxq->idx;
578 [ # # ]: 0 : if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
579 : 0 : stats->q_ipackets[idx] += rxq->stats.rx_pkts;
580 : 0 : stats->q_ibytes[idx] += rxq->stats.rx_bytes;
581 : 0 : stats->q_errors[idx] += rxq->stats.rx_errors +
582 : 0 : rxq->stats.rx_nombuf;
583 : : }
584 : 0 : stats->ipackets += rxq->stats.rx_pkts;
585 : 0 : stats->ibytes += rxq->stats.rx_bytes;
586 : 0 : stats->ierrors += rxq->stats.rx_errors;
587 : 0 : stats->rx_nombuf += rxq->stats.rx_nombuf;
588 : : }
589 : :
590 [ # # ]: 0 : for (i = 0; i < txqs_n; ++i) {
591 [ # # ]: 0 : txq = xsc_txq_get(priv, i);
592 [ # # ]: 0 : if (unlikely(txq == NULL))
593 : 0 : continue;
594 : :
595 : 0 : idx = txq->idx;
596 [ # # ]: 0 : if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
597 : 0 : stats->q_opackets[idx] += txq->stats.tx_pkts;
598 : 0 : stats->q_obytes[idx] += txq->stats.tx_bytes;
599 : 0 : stats->q_errors[idx] += txq->stats.tx_errors;
600 : : }
601 : 0 : stats->opackets += txq->stats.tx_pkts;
602 : 0 : stats->obytes += txq->stats.tx_bytes;
603 : 0 : stats->oerrors += txq->stats.tx_errors;
604 : : }
605 : :
606 : 0 : return 0;
607 : : }
608 : :
609 : : static int
610 : 0 : xsc_ethdev_stats_reset(struct rte_eth_dev *dev)
611 : : {
612 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
613 : 0 : uint32_t rxqs_n = priv->num_rq;
614 : 0 : uint32_t txqs_n = priv->num_sq;
615 : : uint32_t i;
616 : : struct xsc_rxq_data *rxq;
617 : : struct xsc_txq_data *txq;
618 : :
619 [ # # ]: 0 : for (i = 0; i < rxqs_n; ++i) {
620 [ # # ]: 0 : rxq = xsc_rxq_get(priv, i);
621 [ # # ]: 0 : if (unlikely(rxq == NULL))
622 : 0 : continue;
623 : 0 : memset(&rxq->stats, 0, sizeof(struct xsc_rxq_stats));
624 : : }
625 [ # # ]: 0 : for (i = 0; i < txqs_n; ++i) {
626 [ # # ]: 0 : txq = xsc_txq_get(priv, i);
627 [ # # ]: 0 : if (unlikely(txq == NULL))
628 : 0 : continue;
629 : 0 : memset(&txq->stats, 0, sizeof(struct xsc_txq_stats));
630 : : }
631 : :
632 : 0 : return 0;
633 : : }
634 : :
635 : : static int
636 : 0 : xsc_ethdev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uint32_t index)
637 : : {
638 : : int i;
639 : :
640 : 0 : rte_errno = EINVAL;
641 [ # # ]: 0 : if (index > XSC_MAX_MAC_ADDRESSES)
642 : : return -rte_errno;
643 : :
644 [ # # ]: 0 : if (rte_is_zero_ether_addr(mac))
645 : : return -rte_errno;
646 : :
647 [ # # ]: 0 : for (i = 0; i != XSC_MAX_MAC_ADDRESSES; ++i) {
648 [ # # ]: 0 : if (i == (int)index)
649 : 0 : continue;
650 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac)))
651 : 0 : continue;
652 : : /* Address already configured elsewhere, return with error */
653 : 0 : rte_errno = EADDRINUSE;
654 : 0 : return -rte_errno;
655 : : }
656 : :
657 : 0 : dev->data->mac_addrs[index] = *mac;
658 : 0 : return 0;
659 : : }
660 : :
661 : : const struct eth_dev_ops xsc_eth_dev_ops = {
662 : : .dev_configure = xsc_ethdev_configure,
663 : : .dev_start = xsc_ethdev_start,
664 : : .dev_stop = xsc_ethdev_stop,
665 : : .dev_set_link_up = xsc_ethdev_set_link_up,
666 : : .dev_set_link_down = xsc_ethdev_set_link_down,
667 : : .dev_close = xsc_ethdev_close,
668 : : .link_update = xsc_ethdev_link_update,
669 : : .stats_get = xsc_ethdev_stats_get,
670 : : .stats_reset = xsc_ethdev_stats_reset,
671 : : .dev_infos_get = xsc_ethdev_infos_get,
672 : : .rx_queue_setup = xsc_ethdev_rx_queue_setup,
673 : : .tx_queue_setup = xsc_ethdev_tx_queue_setup,
674 : : .rx_queue_release = xsc_ethdev_rxq_release,
675 : : .tx_queue_release = xsc_ethdev_txq_release,
676 : : .mtu_set = xsc_ethdev_set_mtu,
677 : : .rss_hash_update = xsc_ethdev_rss_hash_update,
678 : : .rss_hash_conf_get = xsc_ethdev_rss_hash_conf_get,
679 : : };
680 : :
681 : : static int
682 : 0 : xsc_ethdev_init_one_representor(struct rte_eth_dev *eth_dev, void *init_params)
683 : : {
684 : : int ret;
685 : : struct xsc_repr_port *repr_port = (struct xsc_repr_port *)init_params;
686 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
687 : : struct xsc_dev_config *config = &priv->config;
688 : : struct rte_ether_addr mac;
689 : :
690 : 0 : priv->repr_port = repr_port;
691 : 0 : repr_port->drv_data = eth_dev;
692 : 0 : priv->xdev = repr_port->xdev;
693 : 0 : priv->mtu = RTE_ETHER_MTU;
694 : 0 : priv->funcid_type = (repr_port->info.funcid & XSC_FUNCID_TYPE_MASK) >> 14;
695 : 0 : priv->funcid = repr_port->info.funcid & XSC_FUNCID_MASK;
696 [ # # ]: 0 : if (repr_port->info.port_type == XSC_PORT_TYPE_UPLINK ||
697 : : repr_port->info.port_type == XSC_PORT_TYPE_UPLINK_BOND)
698 : 0 : priv->eth_type = RTE_ETH_REPRESENTOR_PF;
699 : : else
700 : 0 : priv->eth_type = RTE_ETH_REPRESENTOR_VF;
701 : 0 : priv->representor_id = repr_port->info.repr_id;
702 : 0 : priv->dev_data = eth_dev->data;
703 : 0 : priv->ifindex = repr_port->info.ifindex;
704 : :
705 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
706 [ # # ]: 0 : eth_dev->data->mac_addrs = priv->mac;
707 [ # # ]: 0 : if (rte_is_zero_ether_addr(eth_dev->data->mac_addrs)) {
708 : 0 : ret = xsc_dev_get_mac(priv->xdev, mac.addr_bytes);
709 [ # # ]: 0 : if (ret != 0) {
710 : 0 : PMD_DRV_LOG(ERR, "Port %u cannot get MAC address",
711 : : eth_dev->data->port_id);
712 : 0 : return -ENODEV;
713 : : }
714 : : }
715 : :
716 : 0 : xsc_ethdev_mac_addr_add(eth_dev, &mac, 0);
717 : :
718 : 0 : config->hw_csum = 1;
719 : 0 : config->pph_flag = priv->xdev->devargs.pph_mode;
720 [ # # ]: 0 : if ((config->pph_flag & XSC_TX_PPH) != 0) {
721 : 0 : config->tso = 0;
722 : : } else {
723 : 0 : config->tso = 1;
724 : : if (config->tso)
725 : 0 : config->tso_max_payload_sz = 1500;
726 : : }
727 : :
728 : 0 : priv->is_representor = (priv->eth_type == RTE_ETH_REPRESENTOR_NONE) ? 0 : 1;
729 [ # # ]: 0 : if (priv->is_representor) {
730 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
731 : 0 : eth_dev->data->representor_id = priv->representor_id;
732 : 0 : eth_dev->data->backer_port_id = eth_dev->data->port_id;
733 : : }
734 : :
735 : 0 : eth_dev->dev_ops = &xsc_eth_dev_ops;
736 : 0 : eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
737 : 0 : eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
738 : :
739 : 0 : rte_eth_dev_probing_finish(eth_dev);
740 : :
741 : 0 : return 0;
742 : : }
743 : :
744 : : static int
745 : 0 : xsc_ethdev_init_representors(struct rte_eth_dev *eth_dev)
746 : : {
747 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
748 : 0 : struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
749 : : struct rte_device *dev;
750 : : struct xsc_dev *xdev;
751 : : struct xsc_repr_port *repr_port;
752 : : char name[RTE_ETH_NAME_MAX_LEN];
753 : : int i;
754 : : int ret;
755 : :
756 : 0 : PMD_INIT_FUNC_TRACE();
757 : :
758 : 0 : dev = &priv->pci_dev->device;
759 [ # # ]: 0 : if (dev->devargs != NULL) {
760 : 0 : ret = rte_eth_devargs_parse(dev->devargs->args, ð_da, 1);
761 [ # # ]: 0 : if (ret < 0) {
762 : 0 : PMD_DRV_LOG(ERR, "Failed to parse device arguments: %s",
763 : : dev->devargs->args);
764 : 0 : return -EINVAL;
765 : : }
766 : : }
767 : :
768 : 0 : xdev = priv->xdev;
769 : 0 : ret = xsc_dev_repr_ports_probe(xdev, eth_da.nb_representor_ports, RTE_MAX_ETHPORTS);
770 [ # # ]: 0 : if (ret != 0) {
771 : 0 : PMD_DRV_LOG(ERR, "Failed to probe %d xsc device representors",
772 : : eth_da.nb_representor_ports);
773 : 0 : return ret;
774 : : }
775 : :
776 : : /* PF rep init */
777 : 0 : repr_port = &xdev->repr_ports[xdev->num_repr_ports - 1];
778 : 0 : ret = xsc_ethdev_init_one_representor(eth_dev, repr_port);
779 [ # # ]: 0 : if (ret != 0) {
780 : 0 : PMD_DRV_LOG(ERR, "Failed to init backing representor");
781 : 0 : return ret;
782 : : }
783 : :
784 : : /* VF rep init */
785 [ # # ]: 0 : for (i = 0; i < eth_da.nb_representor_ports; i++) {
786 : 0 : repr_port = &xdev->repr_ports[i];
787 : 0 : snprintf(name, sizeof(name), "%s_rep_%d",
788 : 0 : xdev->name, repr_port->info.repr_id);
789 : 0 : ret = rte_eth_dev_create(dev,
790 : : name,
791 : : sizeof(struct xsc_ethdev_priv),
792 : : NULL, NULL,
793 : : xsc_ethdev_init_one_representor,
794 : : repr_port);
795 [ # # ]: 0 : if (ret != 0) {
796 : 0 : PMD_DRV_LOG(ERR, "Failed to create representor: %d", i);
797 : 0 : goto destroy_reprs;
798 : : }
799 : : }
800 : :
801 : : return 0;
802 : :
803 : : destroy_reprs:
804 : : /* Destroy vf reprs */
805 [ # # ]: 0 : while ((i--) > 1) {
806 : 0 : repr_port = &xdev->repr_ports[i];
807 : 0 : rte_eth_dev_destroy((struct rte_eth_dev *)repr_port->drv_data, NULL);
808 : : }
809 : :
810 : : /* Destroy pf repr */
811 : 0 : repr_port = &xdev->repr_ports[xdev->num_repr_ports - 1];
812 : 0 : rte_eth_dev_destroy((struct rte_eth_dev *)repr_port->drv_data, NULL);
813 : 0 : return ret;
814 : : }
815 : :
816 : : static int
817 : 0 : xsc_ethdev_init(struct rte_eth_dev *eth_dev)
818 : : {
819 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
820 : : int ret;
821 : :
822 : 0 : PMD_INIT_FUNC_TRACE();
823 : :
824 : 0 : priv->eth_dev = eth_dev;
825 : 0 : priv->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
826 : :
827 : 0 : ret = xsc_dev_init(priv->pci_dev, &priv->xdev);
828 [ # # ]: 0 : if (ret) {
829 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize xsc device");
830 : 0 : return ret;
831 : : }
832 : 0 : priv->xdev->port_id = eth_dev->data->port_id;
833 : :
834 : 0 : ret = xsc_ethdev_init_representors(eth_dev);
835 [ # # ]: 0 : if (ret != 0) {
836 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize representors");
837 : 0 : goto uninit_xsc_dev;
838 : : }
839 : :
840 : : return 0;
841 : :
842 : : uninit_xsc_dev:
843 : 0 : xsc_dev_uninit(priv->xdev);
844 : 0 : return ret;
845 : : }
846 : :
847 : : static int
848 : 0 : xsc_ethdev_uninit(struct rte_eth_dev *eth_dev)
849 : : {
850 : 0 : struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
851 : :
852 : 0 : PMD_INIT_FUNC_TRACE();
853 : :
854 : 0 : xsc_dev_uninit(priv->xdev);
855 : :
856 : 0 : return 0;
857 : : }
858 : :
859 : : static int
860 : 0 : xsc_ethdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
861 : : struct rte_pci_device *pci_dev)
862 : : {
863 : : int ret;
864 : :
865 : 0 : PMD_INIT_FUNC_TRACE();
866 : :
867 : 0 : ret = rte_eth_dev_pci_generic_probe(pci_dev,
868 : : sizeof(struct xsc_ethdev_priv),
869 : : xsc_ethdev_init);
870 [ # # ]: 0 : if (ret) {
871 : 0 : PMD_DRV_LOG(ERR, "Failed to probe ethdev: %s", pci_dev->name);
872 : 0 : return ret;
873 : : }
874 : :
875 : : return 0;
876 : : }
877 : :
878 : : static int
879 : 0 : xsc_ethdev_pci_remove(struct rte_pci_device *pci_dev)
880 : : {
881 : : int ret;
882 : :
883 : 0 : PMD_INIT_FUNC_TRACE();
884 : :
885 : 0 : ret = rte_eth_dev_pci_generic_remove(pci_dev, xsc_ethdev_uninit);
886 [ # # ]: 0 : if (ret) {
887 : 0 : PMD_DRV_LOG(ERR, "Could not remove ethdev: %s", pci_dev->name);
888 : 0 : return ret;
889 : : }
890 : :
891 : : return 0;
892 : : }
893 : :
894 : : static const struct rte_pci_id xsc_ethdev_pci_id_map[] = {
895 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MS) },
896 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MSVF) },
897 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVH) },
898 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVHVF) },
899 : : { RTE_PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_PCI_DEV_ID_MVS) },
900 : : { RTE_PCI_DEVICE(0, 0) },
901 : : };
902 : :
903 : : static struct rte_pci_driver xsc_ethdev_pci_driver = {
904 : : .id_table = xsc_ethdev_pci_id_map,
905 : : .probe = xsc_ethdev_pci_probe,
906 : : .remove = xsc_ethdev_pci_remove,
907 : : };
908 : :
909 : 252 : RTE_PMD_REGISTER_PCI(net_xsc, xsc_ethdev_pci_driver);
910 : : RTE_PMD_REGISTER_PCI_TABLE(net_xsc, xsc_ethdev_pci_id_map);
911 : : RTE_PMD_REGISTER_PARAM_STRING(net_xsc,
912 : : XSC_PPH_MODE_ARG "=<x>"
913 : : XSC_NIC_MODE_ARG "=<x>"
914 : : XSC_FLOW_MODE_ARG "=<x>");
915 : :
916 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(xsc_logtype_init, init, NOTICE);
917 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(xsc_logtype_driver, driver, NOTICE);
|