Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Cavium, Inc
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <stdarg.h>
7 : : #include <stdbool.h>
8 : : #include <stdint.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : : #include <unistd.h>
12 : :
13 : : #include <eventdev_pmd.h>
14 : : #include <rte_alarm.h>
15 : : #include <rte_branch_prediction.h>
16 : : #include <bus_vdev_driver.h>
17 : : #include <rte_cycles.h>
18 : : #include <rte_debug.h>
19 : : #include <dev_driver.h>
20 : : #include <rte_devargs.h>
21 : : #include <rte_kvargs.h>
22 : : #include <rte_malloc.h>
23 : : #include <rte_mbuf_pool_ops.h>
24 : : #include <rte_prefetch.h>
25 : :
26 : : #include "octeontx_ethdev.h"
27 : : #include "octeontx_rxtx.h"
28 : : #include "octeontx_logs.h"
29 : : #include "octeontx_stats.h"
30 : :
31 : : /* Useful in stopping/closing event device if no of
32 : : * eth ports are using it.
33 : : */
34 : : RTE_ATOMIC(uint16_t) evdev_refcnt;
35 : :
36 : : #define OCTEONTX_QLM_MODE_SGMII 7
37 : : #define OCTEONTX_QLM_MODE_XFI 12
38 : :
39 : : struct __rte_cache_aligned evdev_priv_data {
40 : : OFFLOAD_FLAGS; /*Sequence should not be changed */
41 : : };
42 : :
43 : : struct octeontx_vdev_init_params {
44 : : uint8_t nr_port;
45 : : };
46 : :
47 : : uint16_t
48 : : rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX];
49 : :
50 : : enum octeontx_link_speed {
51 : : OCTEONTX_LINK_SPEED_SGMII,
52 : : OCTEONTX_LINK_SPEED_XAUI,
53 : : OCTEONTX_LINK_SPEED_RXAUI,
54 : : OCTEONTX_LINK_SPEED_10G_R,
55 : : OCTEONTX_LINK_SPEED_40G_R,
56 : : OCTEONTX_LINK_SPEED_RESERVE1,
57 : : OCTEONTX_LINK_SPEED_QSGMII,
58 : : OCTEONTX_LINK_SPEED_RESERVE2,
59 : : OCTEONTX_LINK_SPEED_UNKNOWN = 255
60 : : };
61 : :
62 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(otx_net_logtype_mbox, mbox, NOTICE);
63 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(otx_net_logtype_init, init, NOTICE);
64 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(otx_net_logtype_driver, driver, NOTICE);
65 : :
66 : : /* Parse integer from integer argument */
67 : : static int
68 : 0 : parse_integer_arg(const char *key __rte_unused,
69 : : const char *value, void *extra_args)
70 : : {
71 : : int *i = (int *)extra_args;
72 : :
73 : 0 : *i = atoi(value);
74 [ # # ]: 0 : if (*i < 0) {
75 : 0 : octeontx_log_err("argument has to be positive.");
76 : 0 : return -1;
77 : : }
78 : :
79 : : return 0;
80 : : }
81 : :
82 : : static int
83 [ # # ]: 0 : octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
84 : : struct rte_vdev_device *dev)
85 : : {
86 : : struct rte_kvargs *kvlist = NULL;
87 : : int ret = 0;
88 : :
89 : : static const char * const octeontx_vdev_valid_params[] = {
90 : : OCTEONTX_VDEV_NR_PORT_ARG,
91 : : NULL
92 : : };
93 : :
94 : : const char *input_args = rte_vdev_device_args(dev);
95 [ # # ]: 0 : if (params == NULL)
96 : : return -EINVAL;
97 : :
98 : :
99 [ # # ]: 0 : if (input_args) {
100 : 0 : kvlist = rte_kvargs_parse(input_args,
101 : : octeontx_vdev_valid_params);
102 [ # # ]: 0 : if (kvlist == NULL)
103 : : return -1;
104 : :
105 : 0 : ret = rte_kvargs_process(kvlist,
106 : : OCTEONTX_VDEV_NR_PORT_ARG,
107 : : &parse_integer_arg,
108 : 0 : ¶ms->nr_port);
109 [ # # ]: 0 : if (ret < 0)
110 : 0 : goto free_kvlist;
111 : : }
112 : :
113 : 0 : free_kvlist:
114 : 0 : rte_kvargs_free(kvlist);
115 : 0 : return ret;
116 : : }
117 : :
118 : : static int
119 : 0 : octeontx_port_open(struct octeontx_nic *nic)
120 : : {
121 : : octeontx_mbox_bgx_port_conf_t bgx_port_conf;
122 : : octeontx_mbox_bgx_port_fifo_cfg_t fifo_cfg;
123 : : int res;
124 : :
125 : : res = 0;
126 : : memset(&bgx_port_conf, 0x0, sizeof(bgx_port_conf));
127 : 0 : PMD_INIT_FUNC_TRACE();
128 : :
129 : 0 : res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf);
130 [ # # ]: 0 : if (res < 0) {
131 : 0 : octeontx_log_err("failed to open port %d", res);
132 : 0 : return res;
133 : : }
134 : :
135 : 0 : nic->node = bgx_port_conf.node;
136 : 0 : nic->port_ena = bgx_port_conf.enable;
137 : 0 : nic->base_ichan = bgx_port_conf.base_chan;
138 : 0 : nic->base_ochan = bgx_port_conf.base_chan;
139 : 0 : nic->num_ichans = bgx_port_conf.num_chans;
140 : 0 : nic->num_ochans = bgx_port_conf.num_chans;
141 : 0 : nic->bgx_mtu = bgx_port_conf.mtu;
142 : 0 : nic->bpen = bgx_port_conf.bpen;
143 : 0 : nic->fcs_strip = bgx_port_conf.fcs_strip;
144 : 0 : nic->bcast_mode = bgx_port_conf.bcast_mode;
145 : 0 : nic->mcast_mode = bgx_port_conf.mcast_mode;
146 : 0 : nic->speed = bgx_port_conf.mode;
147 : :
148 : 0 : nic->duplex = RTE_ETH_LINK_FULL_DUPLEX;
149 : : memset(&fifo_cfg, 0x0, sizeof(fifo_cfg));
150 : :
151 : 0 : res = octeontx_bgx_port_get_fifo_cfg(nic->port_id, &fifo_cfg);
152 [ # # ]: 0 : if (res < 0) {
153 : 0 : octeontx_log_err("failed to get port %d fifo cfg", res);
154 : 0 : return res;
155 : : }
156 : :
157 : 0 : nic->fc.rx_fifosz = fifo_cfg.rx_fifosz;
158 : :
159 : 0 : memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0],
160 : : RTE_ETHER_ADDR_LEN);
161 : :
162 : 0 : octeontx_log_dbg("port opened %d", nic->port_id);
163 : 0 : return res;
164 : : }
165 : :
166 : : static void
167 : 0 : octeontx_link_status_print(struct rte_eth_dev *eth_dev,
168 : : struct rte_eth_link *link)
169 : : {
170 [ # # # # ]: 0 : if (link && link->link_status)
171 [ # # ]: 0 : octeontx_log_info("Port %u: Link Up - speed %u Mbps - %s",
172 : : (eth_dev->data->port_id),
173 : : link->link_speed,
174 : : link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX ?
175 : : "full-duplex" : "half-duplex");
176 : : else
177 : 0 : octeontx_log_info("Port %d: Link Down",
178 : : (int)(eth_dev->data->port_id));
179 : 0 : }
180 : :
181 : : static inline uint32_t
182 : : octeontx_parse_link_speeds(uint32_t link_speeds)
183 : : {
184 : : uint32_t link_speed = OCTEONTX_LINK_SPEED_UNKNOWN;
185 : :
186 [ # # ]: 0 : if (link_speeds & RTE_ETH_LINK_SPEED_40G)
187 : : link_speed = OCTEONTX_LINK_SPEED_40G_R;
188 : :
189 [ # # ]: 0 : if (link_speeds & RTE_ETH_LINK_SPEED_10G) {
190 : : link_speed = OCTEONTX_LINK_SPEED_XAUI;
191 : : link_speed |= OCTEONTX_LINK_SPEED_RXAUI;
192 : : link_speed |= OCTEONTX_LINK_SPEED_10G_R;
193 : : }
194 : :
195 [ # # ]: 0 : if (link_speeds & RTE_ETH_LINK_SPEED_5G)
196 : : link_speed = OCTEONTX_LINK_SPEED_QSGMII;
197 : :
198 [ # # ]: 0 : if (link_speeds & RTE_ETH_LINK_SPEED_1G)
199 : : link_speed = OCTEONTX_LINK_SPEED_SGMII;
200 : :
201 : : return link_speed;
202 : : }
203 : :
204 : : static inline uint8_t
205 : : octeontx_parse_eth_link_duplex(uint32_t link_speeds)
206 : : {
207 : 0 : if ((link_speeds & RTE_ETH_LINK_SPEED_10M_HD) ||
208 : : (link_speeds & RTE_ETH_LINK_SPEED_100M_HD))
209 : : return RTE_ETH_LINK_HALF_DUPLEX;
210 : : else
211 : 0 : return RTE_ETH_LINK_FULL_DUPLEX;
212 : : }
213 : :
214 : : static int
215 [ # # ]: 0 : octeontx_apply_link_speed(struct rte_eth_dev *dev)
216 : : {
217 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
218 : : struct rte_eth_conf *conf = &dev->data->dev_conf;
219 : : octeontx_mbox_bgx_port_change_mode_t cfg;
220 : :
221 [ # # ]: 0 : if (conf->link_speeds == RTE_ETH_LINK_SPEED_AUTONEG)
222 : : return 0;
223 : :
224 : 0 : cfg.speed = octeontx_parse_link_speeds(conf->link_speeds);
225 [ # # ]: 0 : cfg.autoneg = (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) ? 1 : 0;
226 : 0 : cfg.duplex = octeontx_parse_eth_link_duplex(conf->link_speeds);
227 [ # # # # ]: 0 : cfg.qlm_mode = ((conf->link_speeds & RTE_ETH_LINK_SPEED_1G) ?
228 : : OCTEONTX_QLM_MODE_SGMII :
229 : : (conf->link_speeds & RTE_ETH_LINK_SPEED_10G) ?
230 : : OCTEONTX_QLM_MODE_XFI : 0);
231 : :
232 [ # # ]: 0 : if (cfg.speed != OCTEONTX_LINK_SPEED_UNKNOWN &&
233 [ # # # # ]: 0 : (cfg.speed != nic->speed || cfg.duplex != nic->duplex)) {
234 : 0 : nic->speed = cfg.speed;
235 : 0 : nic->duplex = cfg.duplex;
236 : 0 : return octeontx_bgx_port_change_mode(nic->port_id, &cfg);
237 : : } else {
238 : : return 0;
239 : : }
240 : : }
241 : :
242 : : static void
243 [ # # # # : 0 : octeontx_link_status_update(struct octeontx_nic *nic,
# # ]
244 : : struct rte_eth_link *link)
245 : : {
246 : : memset(link, 0, sizeof(*link));
247 : :
248 : 0 : link->link_status = nic->link_up ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN;
249 : :
250 [ # # # # : 0 : switch (nic->speed) {
# # ]
251 : 0 : case OCTEONTX_LINK_SPEED_SGMII:
252 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_1G;
253 : 0 : break;
254 : :
255 : 0 : case OCTEONTX_LINK_SPEED_XAUI:
256 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_10G;
257 : 0 : break;
258 : :
259 : 0 : case OCTEONTX_LINK_SPEED_RXAUI:
260 : : case OCTEONTX_LINK_SPEED_10G_R:
261 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_10G;
262 : 0 : break;
263 : 0 : case OCTEONTX_LINK_SPEED_QSGMII:
264 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_5G;
265 : 0 : break;
266 : 0 : case OCTEONTX_LINK_SPEED_40G_R:
267 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_40G;
268 : 0 : break;
269 : :
270 : 0 : case OCTEONTX_LINK_SPEED_RESERVE1:
271 : : case OCTEONTX_LINK_SPEED_RESERVE2:
272 : : default:
273 : : link->link_speed = RTE_ETH_SPEED_NUM_NONE;
274 : 0 : octeontx_log_err("incorrect link speed %d", nic->speed);
275 : 0 : break;
276 : : }
277 : :
278 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
279 : 0 : link->link_autoneg = RTE_ETH_LINK_AUTONEG;
280 : 0 : }
281 : :
282 : : static void
283 : 0 : octeontx_link_status_poll(void *arg)
284 : : {
285 : : struct octeontx_nic *nic = arg;
286 : : struct rte_eth_link link;
287 : : struct rte_eth_dev *dev;
288 : : int res;
289 : :
290 : 0 : PMD_INIT_FUNC_TRACE();
291 : :
292 : 0 : dev = nic->dev;
293 : :
294 : 0 : res = octeontx_bgx_port_link_status(nic->port_id);
295 [ # # ]: 0 : if (res < 0) {
296 : 0 : octeontx_log_err("Failed to get port %d link status",
297 : : nic->port_id);
298 : : } else {
299 [ # # ]: 0 : if (nic->link_up != (uint8_t)res) {
300 : 0 : nic->link_up = (uint8_t)res;
301 : 0 : octeontx_link_status_update(nic, &link);
302 : 0 : octeontx_link_status_print(dev, &link);
303 : 0 : rte_eth_linkstatus_set(dev, &link);
304 : 0 : rte_eth_dev_callback_process(dev,
305 : : RTE_ETH_EVENT_INTR_LSC,
306 : : NULL);
307 : : }
308 : : }
309 : :
310 : 0 : res = rte_eal_alarm_set(OCCTX_INTR_POLL_INTERVAL_MS * 1000,
311 : : octeontx_link_status_poll, nic);
312 [ # # ]: 0 : if (res < 0)
313 : 0 : octeontx_log_err("Failed to restart alarm for port %d, err: %d",
314 : : nic->port_id, res);
315 : 0 : }
316 : :
317 : : static void
318 : 0 : octeontx_port_close(struct octeontx_nic *nic)
319 : : {
320 : 0 : PMD_INIT_FUNC_TRACE();
321 : :
322 : 0 : rte_eal_alarm_cancel(octeontx_link_status_poll, nic);
323 : 0 : octeontx_bgx_port_close(nic->port_id);
324 : 0 : octeontx_log_dbg("port closed %d", nic->port_id);
325 : 0 : }
326 : :
327 : : static int
328 : 0 : octeontx_port_start(struct octeontx_nic *nic)
329 : : {
330 : 0 : PMD_INIT_FUNC_TRACE();
331 : :
332 : 0 : return octeontx_bgx_port_start(nic->port_id);
333 : : }
334 : :
335 : : static int
336 : 0 : octeontx_port_stop(struct octeontx_nic *nic)
337 : : {
338 : 0 : PMD_INIT_FUNC_TRACE();
339 : :
340 : 0 : return octeontx_bgx_port_stop(nic->port_id);
341 : : }
342 : :
343 : : static int
344 : 0 : octeontx_port_promisc_set(struct octeontx_nic *nic, int en)
345 : : {
346 : : struct rte_eth_dev *dev;
347 : : int res;
348 : :
349 : : res = 0;
350 : 0 : PMD_INIT_FUNC_TRACE();
351 : 0 : dev = nic->dev;
352 : :
353 : 0 : res = octeontx_bgx_port_promisc_set(nic->port_id, en);
354 [ # # ]: 0 : if (res < 0) {
355 : 0 : octeontx_log_err("failed to set promiscuous mode %d",
356 : : nic->port_id);
357 : 0 : return res;
358 : : }
359 : :
360 : : /* Set proper flag for the mode */
361 : 0 : dev->data->promiscuous = (en != 0) ? 1 : 0;
362 : :
363 [ # # ]: 0 : octeontx_log_dbg("port %d : promiscuous mode %s",
364 : : nic->port_id, en ? "set" : "unset");
365 : :
366 : 0 : return 0;
367 : : }
368 : :
369 : : static int
370 : 0 : octeontx_port_stats(struct octeontx_nic *nic, struct rte_eth_stats *stats)
371 : : {
372 : : octeontx_mbox_bgx_port_stats_t bgx_stats;
373 : : int res;
374 : :
375 : 0 : PMD_INIT_FUNC_TRACE();
376 : :
377 : 0 : res = octeontx_bgx_port_stats(nic->port_id, &bgx_stats);
378 [ # # ]: 0 : if (res < 0) {
379 : 0 : octeontx_log_err("failed to get port stats %d", nic->port_id);
380 : 0 : return res;
381 : : }
382 : :
383 : 0 : stats->ipackets = bgx_stats.rx_packets;
384 : 0 : stats->ibytes = bgx_stats.rx_bytes;
385 : 0 : stats->imissed = bgx_stats.rx_dropped;
386 : 0 : stats->ierrors = bgx_stats.rx_errors;
387 : 0 : stats->opackets = bgx_stats.tx_packets;
388 : 0 : stats->obytes = bgx_stats.tx_bytes;
389 : 0 : stats->oerrors = bgx_stats.tx_errors;
390 : :
391 : 0 : octeontx_log_dbg("port%d stats inpkts=%" PRIx64 " outpkts=%" PRIx64 "",
392 : : nic->port_id, stats->ipackets, stats->opackets);
393 : :
394 : 0 : return 0;
395 : : }
396 : :
397 : : static int
398 : 0 : octeontx_port_stats_clr(struct octeontx_nic *nic)
399 : : {
400 : 0 : PMD_INIT_FUNC_TRACE();
401 : :
402 : 0 : return octeontx_bgx_port_stats_clr(nic->port_id);
403 : : }
404 : :
405 : : static inline void
406 : 0 : devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
407 : : struct rte_event_dev_info *info)
408 : : {
409 : : memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
410 : 0 : dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
411 : :
412 : 0 : dev_conf->nb_event_ports = info->max_event_ports;
413 : 0 : dev_conf->nb_event_queues = info->max_event_queues;
414 : :
415 : 0 : dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
416 : 0 : dev_conf->nb_event_port_dequeue_depth =
417 : 0 : info->max_event_port_dequeue_depth;
418 : 0 : dev_conf->nb_event_port_enqueue_depth =
419 : 0 : info->max_event_port_enqueue_depth;
420 : : dev_conf->nb_event_port_enqueue_depth =
421 : : info->max_event_port_enqueue_depth;
422 : 0 : dev_conf->nb_events_limit =
423 : 0 : info->max_num_events;
424 : 0 : }
425 : :
426 : : static uint16_t
427 [ # # ]: 0 : octeontx_tx_offload_flags(struct rte_eth_dev *eth_dev)
428 : : {
429 : : struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
430 : : uint16_t flags = 0;
431 : :
432 [ # # ]: 0 : if (nic->tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM ||
433 : : nic->tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
434 : : flags |= OCCTX_TX_OFFLOAD_OL3_OL4_CSUM_F;
435 : :
436 : 0 : if (nic->tx_offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM ||
437 : : nic->tx_offloads & RTE_ETH_TX_OFFLOAD_TCP_CKSUM ||
438 [ # # ]: 0 : nic->tx_offloads & RTE_ETH_TX_OFFLOAD_UDP_CKSUM ||
439 : : nic->tx_offloads & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)
440 : 0 : flags |= OCCTX_TX_OFFLOAD_L3_L4_CSUM_F;
441 : :
442 [ # # ]: 0 : if (!(nic->tx_offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE))
443 : 0 : flags |= OCCTX_TX_OFFLOAD_MBUF_NOFF_F;
444 : :
445 [ # # ]: 0 : if (nic->tx_offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
446 : 0 : flags |= OCCTX_TX_MULTI_SEG_F;
447 : :
448 : 0 : return flags;
449 : : }
450 : :
451 : : static uint16_t
452 : : octeontx_rx_offload_flags(struct rte_eth_dev *eth_dev)
453 : : {
454 : : struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
455 : : uint16_t flags = 0;
456 : :
457 [ # # ]: 0 : if (nic->rx_offloads & (RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
458 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM))
459 : : flags |= OCCTX_RX_OFFLOAD_CSUM_F;
460 : :
461 [ # # # # ]: 0 : if (nic->rx_offloads & (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
462 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM))
463 : : flags |= OCCTX_RX_OFFLOAD_CSUM_F;
464 : :
465 [ # # ]: 0 : if (nic->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER) {
466 : 0 : flags |= OCCTX_RX_MULTI_SEG_F;
467 : 0 : eth_dev->data->scattered_rx = 1;
468 : : /* If scatter mode is enabled, TX should also be in multi
469 : : * seg mode, else memory leak will occur
470 : : */
471 : 0 : nic->tx_offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
472 : : }
473 : :
474 : : return flags;
475 : : }
476 : :
477 : : static int
478 : 0 : octeontx_dev_configure(struct rte_eth_dev *dev)
479 : : {
480 : 0 : struct rte_eth_dev_data *data = dev->data;
481 : : struct rte_eth_conf *conf = &data->dev_conf;
482 : : struct rte_eth_rxmode *rxmode = &conf->rxmode;
483 : : struct rte_eth_txmode *txmode = &conf->txmode;
484 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
485 : : int ret;
486 : :
487 : 0 : PMD_INIT_FUNC_TRACE();
488 : : RTE_SET_USED(conf);
489 : :
490 [ # # ]: 0 : if (!rte_eal_has_hugepages()) {
491 : 0 : octeontx_log_err("huge page is not configured");
492 : 0 : return -EINVAL;
493 : : }
494 : :
495 [ # # ]: 0 : if (txmode->mq_mode) {
496 : 0 : octeontx_log_err("tx mq_mode DCB or VMDq not supported");
497 : 0 : return -EINVAL;
498 : : }
499 : :
500 [ # # ]: 0 : if (rxmode->mq_mode != RTE_ETH_MQ_RX_NONE &&
501 : : rxmode->mq_mode != RTE_ETH_MQ_RX_RSS) {
502 : 0 : octeontx_log_err("unsupported rx qmode %d", rxmode->mq_mode);
503 : 0 : return -EINVAL;
504 : : }
505 : :
506 [ # # ]: 0 : if (!(txmode->offloads & RTE_ETH_TX_OFFLOAD_MT_LOCKFREE)) {
507 : 0 : PMD_INIT_LOG(NOTICE, "cant disable lockfree tx");
508 : 0 : txmode->offloads |= RTE_ETH_TX_OFFLOAD_MT_LOCKFREE;
509 : : }
510 : :
511 [ # # ]: 0 : if (conf->dcb_capability_en) {
512 : 0 : octeontx_log_err("DCB enable not supported");
513 : 0 : return -EINVAL;
514 : : }
515 : :
516 : 0 : nic->num_tx_queues = dev->data->nb_tx_queues;
517 : :
518 [ # # ]: 0 : if (!nic->reconfigure) {
519 : 0 : ret = octeontx_pko_channel_open(nic->pko_vfid * PKO_VF_NUM_DQ,
520 : : nic->num_tx_queues,
521 : : nic->base_ochan);
522 [ # # ]: 0 : if (ret) {
523 : 0 : octeontx_log_err("failed to open channel %d no-of-txq %d",
524 : : nic->base_ochan, nic->num_tx_queues);
525 : 0 : return -EFAULT;
526 : : }
527 : :
528 : 0 : ret = octeontx_dev_vlan_offload_init(dev);
529 [ # # ]: 0 : if (ret) {
530 : 0 : octeontx_log_err("failed to initialize vlan offload");
531 : 0 : return -EFAULT;
532 : : }
533 : :
534 : 0 : nic->pki.classifier_enable = false;
535 : 0 : nic->pki.hash_enable = true;
536 : 0 : nic->pki.initialized = false;
537 : : }
538 : :
539 : 0 : nic->rx_offloads |= rxmode->offloads;
540 [ # # ]: 0 : nic->tx_offloads |= txmode->offloads;
541 : 0 : nic->rx_offload_flags |= octeontx_rx_offload_flags(dev);
542 : 0 : nic->tx_offload_flags |= octeontx_tx_offload_flags(dev);
543 : :
544 : 0 : nic->reconfigure = true;
545 : :
546 : 0 : return 0;
547 : : }
548 : :
549 : : static int
550 : 0 : octeontx_dev_close(struct rte_eth_dev *dev)
551 : : {
552 : : struct octeontx_txq *txq = NULL;
553 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
554 : : unsigned int i;
555 : : int ret;
556 : :
557 : 0 : PMD_INIT_FUNC_TRACE();
558 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
559 : : return 0;
560 : :
561 : : /* Stopping/closing event device once all eth ports are closed. */
562 [ # # ]: 0 : if (rte_atomic_fetch_sub_explicit(&evdev_refcnt, 1, rte_memory_order_acquire) - 1 == 0) {
563 : 0 : rte_event_dev_stop(nic->evdev);
564 : 0 : rte_event_dev_close(nic->evdev);
565 : : }
566 : :
567 : 0 : octeontx_dev_flow_ctrl_fini(dev);
568 : :
569 : 0 : octeontx_dev_vlan_offload_fini(dev);
570 : :
571 : 0 : ret = octeontx_pko_channel_close(nic->base_ochan);
572 [ # # ]: 0 : if (ret < 0) {
573 : 0 : octeontx_log_err("failed to close channel %d VF%d %d %d",
574 : : nic->base_ochan, nic->port_id, nic->num_tx_queues,
575 : : ret);
576 : : }
577 : : /* Free txq resources for this port */
578 [ # # ]: 0 : for (i = 0; i < nic->num_tx_queues; i++) {
579 : 0 : txq = dev->data->tx_queues[i];
580 [ # # ]: 0 : if (!txq)
581 : 0 : continue;
582 : :
583 : 0 : rte_free(txq);
584 : : }
585 : :
586 : 0 : octeontx_port_close(nic);
587 : 0 : nic->reconfigure = false;
588 : :
589 : 0 : return 0;
590 : : }
591 : :
592 : : static int
593 : 0 : octeontx_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
594 : : {
595 [ # # ]: 0 : uint32_t buffsz, frame_size = mtu + OCCTX_L2_OVERHEAD;
596 : : struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
597 : : struct rte_eth_dev_data *data = eth_dev->data;
598 : : int rc = 0;
599 : :
600 : 0 : buffsz = data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM;
601 : :
602 : : /* Refuse MTU that requires the support of scattered packets
603 : : * when this feature has not been enabled before.
604 : : */
605 [ # # # # ]: 0 : if (data->dev_started && frame_size > buffsz &&
606 [ # # ]: 0 : !(nic->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER)) {
607 : 0 : octeontx_log_err("Scatter mode is disabled");
608 : 0 : return -EINVAL;
609 : : }
610 : :
611 : : /* Check <seg size> * <max_seg> >= max_frame */
612 [ # # ]: 0 : if ((nic->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER) &&
613 [ # # ]: 0 : (frame_size > buffsz * OCCTX_RX_NB_SEG_MAX))
614 : : return -EINVAL;
615 : :
616 : 0 : rc = octeontx_pko_send_mtu(nic->port_id, frame_size);
617 [ # # ]: 0 : if (rc)
618 : : return rc;
619 : :
620 : 0 : rc = octeontx_bgx_port_mtu_set(nic->port_id, frame_size);
621 [ # # ]: 0 : if (rc)
622 : : return rc;
623 : :
624 : 0 : octeontx_log_info("Received pkt beyond maxlen %d will be dropped",
625 : : frame_size);
626 : :
627 : 0 : return rc;
628 : : }
629 : :
630 : : static int
631 : 0 : octeontx_recheck_rx_offloads(struct octeontx_rxq *rxq)
632 : : {
633 [ # # ]: 0 : struct rte_eth_dev *eth_dev = rxq->eth_dev;
634 : : struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
635 : : struct rte_eth_dev_data *data = eth_dev->data;
636 : : struct rte_pktmbuf_pool_private *mbp_priv;
637 : : struct evdev_priv_data *evdev_priv;
638 : : struct rte_eventdev *dev;
639 : : uint32_t buffsz;
640 : :
641 : : /* Get rx buffer size */
642 [ # # ]: 0 : mbp_priv = rte_mempool_get_priv(rxq->pool);
643 : 0 : buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
644 : :
645 : : /* Setup scatter mode if needed by jumbo */
646 [ # # ]: 0 : if (data->mtu > buffsz) {
647 [ # # ]: 0 : nic->rx_offloads |= RTE_ETH_RX_OFFLOAD_SCATTER;
648 : 0 : nic->rx_offload_flags |= octeontx_rx_offload_flags(eth_dev);
649 : 0 : nic->tx_offload_flags |= octeontx_tx_offload_flags(eth_dev);
650 : : }
651 : :
652 : : /* Sharing offload flags via eventdev priv region */
653 : 0 : dev = &rte_eventdevs[rxq->evdev];
654 : 0 : evdev_priv = dev->data->dev_private;
655 : 0 : evdev_priv->rx_offload_flags = nic->rx_offload_flags;
656 : 0 : evdev_priv->tx_offload_flags = nic->tx_offload_flags;
657 : :
658 : : /* Setup MTU */
659 : 0 : nic->mtu = data->mtu;
660 : :
661 : 0 : return 0;
662 : : }
663 : :
664 : : static int
665 : 0 : octeontx_dev_start(struct rte_eth_dev *dev)
666 : : {
667 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
668 : : struct octeontx_rxq *rxq;
669 : : int ret, i;
670 : :
671 : 0 : PMD_INIT_FUNC_TRACE();
672 : : /* Rechecking if any new offload set to update
673 : : * rx/tx burst function pointer accordingly.
674 : : */
675 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
676 : 0 : rxq = dev->data->rx_queues[i];
677 : 0 : octeontx_recheck_rx_offloads(rxq);
678 : : }
679 : :
680 : : /* Setting up the mtu */
681 : 0 : ret = octeontx_dev_mtu_set(dev, nic->mtu);
682 [ # # ]: 0 : if (ret) {
683 : 0 : octeontx_log_err("Failed to set default MTU size %d", ret);
684 : 0 : goto error;
685 : : }
686 : :
687 : : /* Apply new link configurations if changed */
688 : 0 : ret = octeontx_apply_link_speed(dev);
689 [ # # ]: 0 : if (ret) {
690 : 0 : octeontx_log_err("Failed to set link configuration: %d", ret);
691 : 0 : goto error;
692 : : }
693 : :
694 : : /*
695 : : * Tx start
696 : : */
697 : 0 : octeontx_set_tx_function(dev);
698 : 0 : ret = octeontx_pko_channel_start(nic->base_ochan);
699 [ # # ]: 0 : if (ret < 0) {
700 : 0 : octeontx_log_err("fail to conf VF%d no. txq %d chan %d ret %d",
701 : : nic->port_id, nic->num_tx_queues, nic->base_ochan,
702 : : ret);
703 : 0 : goto error;
704 : : }
705 : :
706 : : /*
707 : : * Rx start
708 : : */
709 : 0 : dev->rx_pkt_burst = octeontx_recv_pkts;
710 : 0 : ret = octeontx_pki_port_start(nic->port_id);
711 [ # # ]: 0 : if (ret < 0) {
712 : 0 : octeontx_log_err("fail to start Rx on port %d", nic->port_id);
713 : 0 : goto channel_stop_error;
714 : : }
715 : :
716 : : /*
717 : : * Start port
718 : : */
719 : 0 : ret = octeontx_port_start(nic);
720 [ # # ]: 0 : if (ret < 0) {
721 : 0 : octeontx_log_err("failed start port %d", ret);
722 : 0 : goto pki_port_stop_error;
723 : : }
724 : :
725 : 0 : PMD_TX_LOG(DEBUG, "pko: start channel %d no.of txq %d port %d",
726 : : nic->base_ochan, nic->num_tx_queues, nic->port_id);
727 : :
728 : 0 : ret = rte_event_dev_start(nic->evdev);
729 [ # # ]: 0 : if (ret < 0) {
730 : 0 : octeontx_log_err("failed to start evdev: ret (%d)", ret);
731 : 0 : goto pki_port_stop_error;
732 : : }
733 : :
734 : : /* Success */
735 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
736 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
737 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
738 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
739 : :
740 : : return ret;
741 : :
742 : 0 : pki_port_stop_error:
743 : 0 : octeontx_pki_port_stop(nic->port_id);
744 : 0 : channel_stop_error:
745 : 0 : octeontx_pko_channel_stop(nic->base_ochan);
746 : : error:
747 : : return ret;
748 : : }
749 : :
750 : : static int
751 : 0 : octeontx_dev_stop(struct rte_eth_dev *dev)
752 : : {
753 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
754 : : uint16_t i;
755 : : int ret;
756 : :
757 : 0 : PMD_INIT_FUNC_TRACE();
758 : :
759 : 0 : ret = octeontx_port_stop(nic);
760 [ # # ]: 0 : if (ret < 0) {
761 : 0 : octeontx_log_err("failed to req stop port %d res=%d",
762 : : nic->port_id, ret);
763 : 0 : return ret;
764 : : }
765 : :
766 : 0 : ret = octeontx_pki_port_stop(nic->port_id);
767 [ # # ]: 0 : if (ret < 0) {
768 : 0 : octeontx_log_err("failed to stop pki port %d res=%d",
769 : : nic->port_id, ret);
770 : 0 : return ret;
771 : : }
772 : :
773 : 0 : ret = octeontx_pko_channel_stop(nic->base_ochan);
774 [ # # ]: 0 : if (ret < 0) {
775 : 0 : octeontx_log_err("failed to stop channel %d VF%d %d %d",
776 : : nic->base_ochan, nic->port_id, nic->num_tx_queues,
777 : : ret);
778 : 0 : return ret;
779 : : }
780 : :
781 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
782 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
783 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
784 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
785 : :
786 : : return 0;
787 : : }
788 : :
789 : : static int
790 : 0 : octeontx_dev_promisc_enable(struct rte_eth_dev *dev)
791 : : {
792 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
793 : :
794 : 0 : PMD_INIT_FUNC_TRACE();
795 : 0 : return octeontx_port_promisc_set(nic, 1);
796 : : }
797 : :
798 : : static int
799 : 0 : octeontx_dev_promisc_disable(struct rte_eth_dev *dev)
800 : : {
801 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
802 : :
803 : 0 : PMD_INIT_FUNC_TRACE();
804 : 0 : return octeontx_port_promisc_set(nic, 0);
805 : : }
806 : :
807 : : static int
808 : 0 : octeontx_port_link_status(struct octeontx_nic *nic)
809 : : {
810 : : int res;
811 : :
812 : 0 : PMD_INIT_FUNC_TRACE();
813 : 0 : res = octeontx_bgx_port_link_status(nic->port_id);
814 [ # # ]: 0 : if (res < 0) {
815 : 0 : octeontx_log_err("failed to get port %d link status",
816 : : nic->port_id);
817 : 0 : return res;
818 : : }
819 : :
820 [ # # # # ]: 0 : if (nic->link_up != (uint8_t)res || nic->print_flag == -1) {
821 : 0 : nic->link_up = (uint8_t)res;
822 : 0 : nic->print_flag = 1;
823 : : }
824 : 0 : octeontx_log_dbg("port %d link status %d", nic->port_id, nic->link_up);
825 : :
826 : 0 : return res;
827 : : }
828 : :
829 : : /*
830 : : * Return 0 means link status changed, -1 means not changed
831 : : */
832 : : static int
833 : 0 : octeontx_dev_link_update(struct rte_eth_dev *dev,
834 : : int wait_to_complete __rte_unused)
835 : : {
836 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
837 : : struct rte_eth_link link;
838 : : int res;
839 : :
840 : 0 : PMD_INIT_FUNC_TRACE();
841 : :
842 : 0 : res = octeontx_port_link_status(nic);
843 [ # # ]: 0 : if (res < 0) {
844 : 0 : octeontx_log_err("failed to request link status %d", res);
845 : 0 : return res;
846 : : }
847 : :
848 : 0 : octeontx_link_status_update(nic, &link);
849 [ # # ]: 0 : if (nic->print_flag) {
850 : 0 : octeontx_link_status_print(nic->dev, &link);
851 : 0 : nic->print_flag = 0;
852 : : }
853 : :
854 : : return rte_eth_linkstatus_set(dev, &link);
855 : : }
856 : :
857 : : static int
858 : 0 : octeontx_port_mcast_set(struct octeontx_nic *nic, int en)
859 : : {
860 : : struct rte_eth_dev *dev;
861 : : int res;
862 : :
863 : : res = 0;
864 : 0 : PMD_INIT_FUNC_TRACE();
865 : 0 : dev = nic->dev;
866 : :
867 : 0 : res = octeontx_bgx_port_multicast_set(nic->port_id, en);
868 [ # # ]: 0 : if (res < 0) {
869 : 0 : octeontx_log_err("failed to set multicast mode %d",
870 : : nic->port_id);
871 : 0 : return res;
872 : : }
873 : :
874 : : /* Set proper flag for the mode */
875 : 0 : dev->data->all_multicast = (en != 0) ? 1 : 0;
876 : :
877 [ # # ]: 0 : octeontx_log_dbg("port %d : multicast mode %s",
878 : : nic->port_id, en ? "set" : "unset");
879 : :
880 : 0 : return 0;
881 : : }
882 : :
883 : : static int
884 : 0 : octeontx_allmulticast_enable(struct rte_eth_dev *dev)
885 : : {
886 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
887 : :
888 : 0 : PMD_INIT_FUNC_TRACE();
889 : 0 : return octeontx_port_mcast_set(nic, 1);
890 : : }
891 : :
892 : : static int
893 : 0 : octeontx_allmulticast_disable(struct rte_eth_dev *dev)
894 : : {
895 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
896 : :
897 : 0 : PMD_INIT_FUNC_TRACE();
898 : 0 : return octeontx_port_mcast_set(nic, 0);
899 : : }
900 : :
901 : : static inline int octeontx_dev_total_xstat(void)
902 : : {
903 : : return NUM_BGX_XSTAT;
904 : : }
905 : :
906 : : static int
907 : 0 : octeontx_port_xstats(struct octeontx_nic *nic, struct rte_eth_xstat *xstats,
908 : : unsigned int n)
909 : : {
910 : : octeontx_mbox_bgx_port_stats_t bgx_stats;
911 : : int stat_cnt, res, si, i;
912 : :
913 : 0 : res = octeontx_bgx_port_xstats(nic->port_id, &bgx_stats);
914 [ # # ]: 0 : if (res < 0) {
915 : 0 : octeontx_log_err("failed to get port stats %d", nic->port_id);
916 : 0 : return res;
917 : : }
918 : :
919 : : si = 0;
920 : : /* Fill BGX stats */
921 : 0 : stat_cnt = (n > NUM_BGX_XSTAT) ? NUM_BGX_XSTAT : n;
922 : : n = n - stat_cnt;
923 [ # # ]: 0 : for (i = 0; i < stat_cnt; i++) {
924 : 0 : xstats[si].id = si;
925 : 0 : xstats[si].value = *(uint64_t *)(((char *)&bgx_stats) +
926 : 0 : octeontx_bgx_xstats[i].soffset);
927 : 0 : si++;
928 : : }
929 : : /*TODO: Similarly fill rest of HW stats */
930 : :
931 : : return si;
932 : : }
933 : :
934 : : static int
935 : 0 : octeontx_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
936 : : uint64_t *stat_val, unsigned int n)
937 : 0 : {
938 : : unsigned int i, xstat_cnt = octeontx_dev_total_xstat();
939 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
940 : 0 : struct rte_eth_xstat xstats[xstat_cnt];
941 : :
942 : 0 : octeontx_port_xstats(nic, xstats, xstat_cnt);
943 [ # # ]: 0 : for (i = 0; i < n; i++) {
944 [ # # ]: 0 : if (ids[i] >= xstat_cnt) {
945 : 0 : PMD_INIT_LOG(ERR, "out of range id value");
946 : 0 : return -1;
947 : : }
948 : 0 : stat_val[i] = xstats[ids[i]].value;
949 : : }
950 : 0 : return n;
951 : : }
952 : :
953 : : static int
954 : 0 : octeontx_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
955 : : struct rte_eth_xstat_name *xstats_names,
956 : : unsigned int size)
957 : : {
958 : : int stat_cnt, si, i;
959 : :
960 [ # # ]: 0 : if (xstats_names) {
961 : : si = 0;
962 : : /* Fill BGX stats */
963 : 0 : stat_cnt = (size > NUM_BGX_XSTAT) ? NUM_BGX_XSTAT : size;
964 : : size = size - stat_cnt;
965 [ # # ]: 0 : for (i = 0; i < stat_cnt; i++) {
966 : 0 : strlcpy(xstats_names[si].name,
967 : : octeontx_bgx_xstats[i].sname,
968 : : sizeof(xstats_names[si].name));
969 : 0 : si++;
970 : : }
971 : : /*TODO: Similarly fill rest of HW stats */
972 : 0 : return si;
973 : : } else {
974 : : return octeontx_dev_total_xstat();
975 : : }
976 : : }
977 : :
978 : 0 : static void build_xstat_names(struct rte_eth_xstat_name *xstat_names)
979 : : {
980 : : unsigned int i;
981 : :
982 [ # # ]: 0 : for (i = 0; i < NUM_BGX_XSTAT; i++) {
983 : 0 : strlcpy(xstat_names[i].name, octeontx_bgx_xstats[i].sname,
984 : : RTE_ETH_XSTATS_NAME_SIZE);
985 : : }
986 : 0 : }
987 : :
988 : : static int
989 : 0 : octeontx_dev_xstats_get_names_by_id(struct rte_eth_dev *dev __rte_unused,
990 : : const uint64_t *ids,
991 : : struct rte_eth_xstat_name *stat_names,
992 : : unsigned int n)
993 : 0 : {
994 : : unsigned int i, xstat_cnt = octeontx_dev_total_xstat();
995 : 0 : struct rte_eth_xstat_name xstat_names[xstat_cnt];
996 : :
997 : 0 : build_xstat_names(xstat_names);
998 [ # # ]: 0 : for (i = 0; i < n; i++) {
999 [ # # ]: 0 : if (ids[i] >= xstat_cnt) {
1000 : 0 : PMD_INIT_LOG(ERR, "out of range id value");
1001 : 0 : return -1;
1002 : : }
1003 : 0 : strlcpy(stat_names[i].name, xstat_names[ids[i]].name,
1004 : : sizeof(stat_names[i].name));
1005 : : }
1006 : : /*TODO: Similarly fill rest of HW stats */
1007 : :
1008 : 0 : return n;
1009 : : }
1010 : :
1011 : : static int
1012 : 0 : octeontx_dev_xstats_get(struct rte_eth_dev *dev,
1013 : : struct rte_eth_xstat *xstats,
1014 : : unsigned int n)
1015 : : {
1016 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1017 : :
1018 : 0 : PMD_INIT_FUNC_TRACE();
1019 : 0 : return octeontx_port_xstats(nic, xstats, n);
1020 : : }
1021 : :
1022 : : static int
1023 : 0 : octeontx_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
1024 : : {
1025 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1026 : :
1027 : 0 : PMD_INIT_FUNC_TRACE();
1028 : 0 : return octeontx_port_stats(nic, stats);
1029 : : }
1030 : :
1031 : : static int
1032 : 0 : octeontx_dev_stats_reset(struct rte_eth_dev *dev)
1033 : : {
1034 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1035 : :
1036 : 0 : PMD_INIT_FUNC_TRACE();
1037 : 0 : return octeontx_port_stats_clr(nic);
1038 : : }
1039 : :
1040 : : static void
1041 : 0 : octeontx_dev_mac_addr_del(struct rte_eth_dev *dev, uint32_t index)
1042 : : {
1043 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1044 : : int ret;
1045 : :
1046 : 0 : ret = octeontx_bgx_port_mac_del(nic->port_id, index);
1047 [ # # ]: 0 : if (ret != 0)
1048 : 0 : octeontx_log_err("failed to del MAC address filter on port %d",
1049 : : nic->port_id);
1050 : 0 : }
1051 : :
1052 : : static int
1053 : 0 : octeontx_dev_mac_addr_add(struct rte_eth_dev *dev,
1054 : : struct rte_ether_addr *mac_addr,
1055 : : uint32_t index,
1056 : : __rte_unused uint32_t vmdq)
1057 : : {
1058 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1059 : : int ret;
1060 : :
1061 : 0 : ret = octeontx_bgx_port_mac_add(nic->port_id, mac_addr->addr_bytes,
1062 : : index);
1063 [ # # ]: 0 : if (ret < 0) {
1064 : 0 : octeontx_log_err("failed to add MAC address filter on port %d",
1065 : : nic->port_id);
1066 : 0 : return ret;
1067 : : }
1068 : :
1069 : : return 0;
1070 : : }
1071 : :
1072 : : static int
1073 : 0 : octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
1074 : : struct rte_ether_addr *addr)
1075 : : {
1076 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1077 : : int ret;
1078 : :
1079 : 0 : ret = octeontx_bgx_port_mac_set(nic->port_id, addr->addr_bytes);
1080 [ # # ]: 0 : if (ret == 0) {
1081 : : /* Update same mac address to BGX CAM table */
1082 : 0 : ret = octeontx_bgx_port_mac_add(nic->port_id, addr->addr_bytes,
1083 : : 0);
1084 : : }
1085 [ # # ]: 0 : if (ret < 0) {
1086 : 0 : octeontx_log_err("failed to set MAC address on port %d",
1087 : : nic->port_id);
1088 : : }
1089 : :
1090 : 0 : return ret;
1091 : : }
1092 : :
1093 : : static int
1094 : 0 : octeontx_dev_info(struct rte_eth_dev *dev,
1095 : : struct rte_eth_dev_info *dev_info)
1096 : : {
1097 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1098 : :
1099 : : /* Autonegotiation may be disabled */
1100 : : dev_info->speed_capa = RTE_ETH_LINK_SPEED_FIXED;
1101 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_10M | RTE_ETH_LINK_SPEED_100M |
1102 : : RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_10G |
1103 : : RTE_ETH_LINK_SPEED_40G;
1104 : :
1105 : : /* Min/Max MTU supported */
1106 : 0 : dev_info->min_rx_bufsize = OCCTX_MIN_FRS;
1107 : 0 : dev_info->max_rx_pktlen = OCCTX_MAX_FRS;
1108 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - OCCTX_L2_OVERHEAD;
1109 : 0 : dev_info->min_mtu = dev_info->min_rx_bufsize - OCCTX_L2_OVERHEAD;
1110 : :
1111 : 0 : dev_info->max_mac_addrs =
1112 : 0 : octeontx_bgx_port_mac_entries_get(nic->port_id);
1113 : 0 : dev_info->max_rx_queues = 1;
1114 : 0 : dev_info->max_tx_queues = PKO_MAX_NUM_DQ;
1115 : 0 : dev_info->min_rx_bufsize = 0;
1116 : :
1117 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
1118 : : .rx_free_thresh = 0,
1119 : : .rx_drop_en = 0,
1120 : : .offloads = OCTEONTX_RX_OFFLOADS,
1121 : : };
1122 : :
1123 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
1124 : : .tx_free_thresh = 0,
1125 : : .offloads = OCTEONTX_TX_OFFLOADS,
1126 : : };
1127 : :
1128 : 0 : dev_info->rx_offload_capa = OCTEONTX_RX_OFFLOADS;
1129 : 0 : dev_info->tx_offload_capa = OCTEONTX_TX_OFFLOADS;
1130 : 0 : dev_info->rx_queue_offload_capa = OCTEONTX_RX_OFFLOADS;
1131 : 0 : dev_info->tx_queue_offload_capa = OCTEONTX_TX_OFFLOADS;
1132 : :
1133 : 0 : return 0;
1134 : : }
1135 : :
1136 : : static void
1137 : 0 : octeontx_dq_info_getter(octeontx_dq_t *dq, void *out)
1138 : : {
1139 : 0 : ((octeontx_dq_t *)out)->lmtline_va = dq->lmtline_va;
1140 : 0 : ((octeontx_dq_t *)out)->ioreg_va = dq->ioreg_va;
1141 : 0 : ((octeontx_dq_t *)out)->fc_status_va = dq->fc_status_va;
1142 : 0 : }
1143 : :
1144 : : static int
1145 : 0 : octeontx_vf_start_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic,
1146 : : uint16_t qidx)
1147 : : {
1148 : : struct octeontx_txq *txq;
1149 : : int res;
1150 : :
1151 : 0 : PMD_INIT_FUNC_TRACE();
1152 : :
1153 [ # # ]: 0 : if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED)
1154 : : return 0;
1155 : :
1156 : 0 : txq = dev->data->tx_queues[qidx];
1157 : :
1158 : 0 : res = octeontx_pko_channel_query_dqs(nic->base_ochan,
1159 : 0 : &txq->dq,
1160 : : sizeof(octeontx_dq_t),
1161 : 0 : txq->queue_id,
1162 : : octeontx_dq_info_getter);
1163 [ # # ]: 0 : if (res < 0) {
1164 : : res = -EFAULT;
1165 : 0 : goto close_port;
1166 : : }
1167 : :
1168 : 0 : dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
1169 : 0 : return res;
1170 : :
1171 : : close_port:
1172 : 0 : (void)octeontx_port_stop(nic);
1173 : 0 : octeontx_pko_channel_stop(nic->base_ochan);
1174 : 0 : octeontx_pko_channel_close(nic->base_ochan);
1175 : 0 : dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
1176 : 0 : return res;
1177 : : }
1178 : :
1179 : : int
1180 : 0 : octeontx_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t qidx)
1181 : : {
1182 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1183 : :
1184 : 0 : PMD_INIT_FUNC_TRACE();
1185 : 0 : qidx = qidx % PKO_VF_NUM_DQ;
1186 : 0 : return octeontx_vf_start_tx_queue(dev, nic, qidx);
1187 : : }
1188 : :
1189 : : static inline int
1190 : 0 : octeontx_vf_stop_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic,
1191 : : uint16_t qidx)
1192 : : {
1193 : : int ret = 0;
1194 : :
1195 : : RTE_SET_USED(nic);
1196 : 0 : PMD_INIT_FUNC_TRACE();
1197 : :
1198 [ # # ]: 0 : if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED)
1199 : : return 0;
1200 : :
1201 : 0 : dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
1202 : 0 : return ret;
1203 : : }
1204 : :
1205 : : int
1206 : 0 : octeontx_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx)
1207 : : {
1208 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1209 : :
1210 : 0 : PMD_INIT_FUNC_TRACE();
1211 : 0 : qidx = qidx % PKO_VF_NUM_DQ;
1212 : :
1213 : 0 : return octeontx_vf_stop_tx_queue(dev, nic, qidx);
1214 : : }
1215 : :
1216 : : static void
1217 : 0 : octeontx_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
1218 : : {
1219 : : int res;
1220 : :
1221 : 0 : PMD_INIT_FUNC_TRACE();
1222 : :
1223 [ # # ]: 0 : if (dev->data->tx_queues[qid]) {
1224 : 0 : res = octeontx_dev_tx_queue_stop(dev, qid);
1225 [ # # ]: 0 : if (res < 0)
1226 : 0 : octeontx_log_err("failed stop tx_queue(%d)", qid);
1227 : :
1228 : 0 : rte_free(dev->data->tx_queues[qid]);
1229 : : }
1230 : 0 : }
1231 : :
1232 : : static int
1233 [ # # ]: 0 : octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
1234 : : uint16_t nb_desc, unsigned int socket_id,
1235 : : const struct rte_eth_txconf *tx_conf __rte_unused)
1236 : : {
1237 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1238 : : struct octeontx_txq *txq = NULL;
1239 : : uint16_t dq_num;
1240 : : int res = 0;
1241 : :
1242 : : RTE_SET_USED(nb_desc);
1243 : : RTE_SET_USED(socket_id);
1244 : :
1245 : 0 : dq_num = (nic->pko_vfid * PKO_VF_NUM_DQ) + qidx;
1246 : :
1247 : : /* Socket id check */
1248 [ # # ]: 0 : if (socket_id != (unsigned int)SOCKET_ID_ANY &&
1249 [ # # ]: 0 : socket_id != (unsigned int)nic->node)
1250 : 0 : PMD_TX_LOG(INFO, "socket_id expected %d, configured %d",
1251 : : socket_id, nic->node);
1252 : :
1253 : : /* Free memory prior to re-allocation if needed. */
1254 [ # # ]: 0 : if (dev->data->tx_queues[qidx] != NULL) {
1255 : 0 : PMD_TX_LOG(DEBUG, "freeing memory prior to re-allocation %d",
1256 : : qidx);
1257 : 0 : octeontx_dev_tx_queue_release(dev, qidx);
1258 : 0 : dev->data->tx_queues[qidx] = NULL;
1259 : : }
1260 : :
1261 : : /* Allocating tx queue data structure */
1262 : 0 : txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq),
1263 : : RTE_CACHE_LINE_SIZE, nic->node);
1264 [ # # ]: 0 : if (txq == NULL) {
1265 : 0 : octeontx_log_err("failed to allocate txq=%d", qidx);
1266 : : res = -ENOMEM;
1267 : 0 : goto err;
1268 : : }
1269 : :
1270 : 0 : txq->eth_dev = dev;
1271 : 0 : txq->queue_id = dq_num;
1272 : 0 : dev->data->tx_queues[qidx] = txq;
1273 : 0 : dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
1274 : :
1275 : 0 : res = octeontx_pko_channel_query_dqs(nic->base_ochan,
1276 : 0 : &txq->dq,
1277 : : sizeof(octeontx_dq_t),
1278 : : txq->queue_id,
1279 : : octeontx_dq_info_getter);
1280 [ # # ]: 0 : if (res < 0) {
1281 : : res = -EFAULT;
1282 : 0 : goto err;
1283 : : }
1284 : :
1285 : 0 : PMD_TX_LOG(DEBUG, "[%d]:[%d] txq=%p nb_desc=%d lmtline=%p ioreg_va=%p fc_status_va=%p",
1286 : : qidx, txq->queue_id, txq, nb_desc, txq->dq.lmtline_va,
1287 : : txq->dq.ioreg_va,
1288 : : txq->dq.fc_status_va);
1289 : :
1290 : 0 : return res;
1291 : :
1292 : 0 : err:
1293 : 0 : rte_free(txq);
1294 : :
1295 : 0 : return res;
1296 : : }
1297 : :
1298 : : static int
1299 [ # # ]: 0 : octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
1300 : : uint16_t nb_desc, unsigned int socket_id,
1301 : : const struct rte_eth_rxconf *rx_conf,
1302 : : struct rte_mempool *mb_pool)
1303 : : {
1304 : : struct octeontx_nic *nic = octeontx_pmd_priv(dev);
1305 : : struct rte_mempool_ops *mp_ops = NULL;
1306 : : struct octeontx_rxq *rxq = NULL;
1307 : : pki_pktbuf_cfg_t pktbuf_conf;
1308 : : pki_hash_cfg_t pki_hash;
1309 : : pki_qos_cfg_t pki_qos;
1310 : : uintptr_t pool;
1311 : : int ret, port;
1312 : : uint16_t gaura;
1313 : 0 : unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx;
1314 [ # # ]: 0 : unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx;
1315 : :
1316 : : RTE_SET_USED(nb_desc);
1317 : :
1318 : : memset(&pktbuf_conf, 0, sizeof(pktbuf_conf));
1319 : : memset(&pki_hash, 0, sizeof(pki_hash));
1320 : : memset(&pki_qos, 0, sizeof(pki_qos));
1321 : :
1322 [ # # ]: 0 : mp_ops = rte_mempool_get_ops(mb_pool->ops_index);
1323 [ # # ]: 0 : if (strcmp(mp_ops->name, "octeontx_fpavf")) {
1324 : 0 : octeontx_log_err("failed to find octeontx_fpavf mempool");
1325 : 0 : return -ENOTSUP;
1326 : : }
1327 : :
1328 : : /* Handle forbidden configurations */
1329 [ # # ]: 0 : if (nic->pki.classifier_enable) {
1330 : 0 : octeontx_log_err("cannot setup queue %d. "
1331 : : "Classifier option unsupported", qidx);
1332 : 0 : return -EINVAL;
1333 : : }
1334 : :
1335 : 0 : port = nic->port_id;
1336 : :
1337 : : /* Rx deferred start is not supported */
1338 [ # # ]: 0 : if (rx_conf->rx_deferred_start) {
1339 : 0 : octeontx_log_err("rx deferred start not supported");
1340 : 0 : return -EINVAL;
1341 : : }
1342 : :
1343 : : /* Verify queue index */
1344 [ # # ]: 0 : if (qidx >= dev->data->nb_rx_queues) {
1345 : 0 : octeontx_log_err("QID %d not supported (0 - %d available)",
1346 : : qidx, (dev->data->nb_rx_queues - 1));
1347 : 0 : return -ENOTSUP;
1348 : : }
1349 : :
1350 : : /* Socket id check */
1351 [ # # ]: 0 : if (socket_id != (unsigned int)SOCKET_ID_ANY &&
1352 [ # # ]: 0 : socket_id != (unsigned int)nic->node)
1353 : 0 : PMD_RX_LOG(INFO, "socket_id expected %d, configured %d",
1354 : : socket_id, nic->node);
1355 : :
1356 : : /* Allocating rx queue data structure */
1357 : 0 : rxq = rte_zmalloc_socket("ethdev RX queue", sizeof(struct octeontx_rxq),
1358 : : RTE_CACHE_LINE_SIZE, nic->node);
1359 [ # # ]: 0 : if (rxq == NULL) {
1360 : 0 : octeontx_log_err("failed to allocate rxq=%d", qidx);
1361 : 0 : return -ENOMEM;
1362 : : }
1363 : :
1364 [ # # ]: 0 : if (!nic->pki.initialized) {
1365 : 0 : pktbuf_conf.port_type = 0;
1366 : 0 : pki_hash.port_type = 0;
1367 : 0 : pki_qos.port_type = 0;
1368 : :
1369 : 0 : pktbuf_conf.mmask.f_wqe_skip = 1;
1370 : 0 : pktbuf_conf.mmask.f_first_skip = 1;
1371 : 0 : pktbuf_conf.mmask.f_later_skip = 1;
1372 : 0 : pktbuf_conf.mmask.f_mbuff_size = 1;
1373 : 0 : pktbuf_conf.mmask.f_cache_mode = 1;
1374 : :
1375 [ # # ]: 0 : pktbuf_conf.wqe_skip = OCTTX_PACKET_WQE_SKIP;
1376 : 0 : pktbuf_conf.first_skip = OCTTX_PACKET_FIRST_SKIP(mb_pool);
1377 : 0 : pktbuf_conf.later_skip = OCTTX_PACKET_LATER_SKIP;
1378 : 0 : pktbuf_conf.mbuff_size = (mb_pool->elt_size -
1379 : 0 : RTE_PKTMBUF_HEADROOM -
1380 : 0 : rte_pktmbuf_priv_size(mb_pool) -
1381 : : sizeof(struct rte_mbuf));
1382 : :
1383 : 0 : pktbuf_conf.cache_mode = PKI_OPC_MODE_STF2_STT;
1384 : :
1385 : 0 : ret = octeontx_pki_port_pktbuf_config(port, &pktbuf_conf);
1386 [ # # ]: 0 : if (ret != 0) {
1387 : 0 : octeontx_log_err("fail to configure pktbuf for port %d",
1388 : : port);
1389 : 0 : rte_free(rxq);
1390 : 0 : return ret;
1391 : : }
1392 : 0 : PMD_RX_LOG(DEBUG, "Port %d Rx pktbuf configured:",
1393 : : port);
1394 : 0 : PMD_RX_LOG(DEBUG, "\tmbuf_size:\t0x%0x",
1395 : : pktbuf_conf.mbuff_size);
1396 : 0 : PMD_RX_LOG(DEBUG, "\twqe_skip:\t0x%0x",
1397 : : pktbuf_conf.wqe_skip);
1398 : 0 : PMD_RX_LOG(DEBUG, "\tfirst_skip:\t0x%0x",
1399 : : pktbuf_conf.first_skip);
1400 : 0 : PMD_RX_LOG(DEBUG, "\tlater_skip:\t0x%0x",
1401 : : pktbuf_conf.later_skip);
1402 [ # # # # : 0 : PMD_RX_LOG(DEBUG, "\tcache_mode:\t%s",
# # ]
1403 : : (pktbuf_conf.cache_mode ==
1404 : : PKI_OPC_MODE_STT) ?
1405 : : "STT" :
1406 : : (pktbuf_conf.cache_mode ==
1407 : : PKI_OPC_MODE_STF) ?
1408 : : "STF" :
1409 : : (pktbuf_conf.cache_mode ==
1410 : : PKI_OPC_MODE_STF1_STT) ?
1411 : : "STF1_STT" : "STF2_STT");
1412 : :
1413 [ # # ]: 0 : if (nic->pki.hash_enable) {
1414 : 0 : pki_hash.tag_dlc = 1;
1415 : 0 : pki_hash.tag_slc = 1;
1416 : 0 : pki_hash.tag_dlf = 1;
1417 : 0 : pki_hash.tag_slf = 1;
1418 : 0 : pki_hash.tag_prt = 1;
1419 : 0 : octeontx_pki_port_hash_config(port, &pki_hash);
1420 : : }
1421 : :
1422 : 0 : pool = (uintptr_t)mb_pool->pool_id;
1423 : :
1424 : : /* Get the gaura Id */
1425 : : gaura = octeontx_fpa_bufpool_gaura(pool);
1426 : :
1427 : 0 : pki_qos.qpg_qos = PKI_QPG_QOS_NONE;
1428 : 0 : pki_qos.num_entry = 1;
1429 : 0 : pki_qos.drop_policy = 0;
1430 : 0 : pki_qos.tag_type = 0L;
1431 : 0 : pki_qos.qos_entry[0].port_add = 0;
1432 : 0 : pki_qos.qos_entry[0].gaura = gaura;
1433 : 0 : pki_qos.qos_entry[0].ggrp_ok = ev_queues;
1434 : 0 : pki_qos.qos_entry[0].ggrp_bad = ev_queues;
1435 : 0 : pki_qos.qos_entry[0].grptag_bad = 0;
1436 : 0 : pki_qos.qos_entry[0].grptag_ok = 0;
1437 : :
1438 : 0 : ret = octeontx_pki_port_create_qos(port, &pki_qos);
1439 [ # # ]: 0 : if (ret < 0) {
1440 : 0 : octeontx_log_err("failed to create QOS port=%d, q=%d",
1441 : : port, qidx);
1442 : 0 : rte_free(rxq);
1443 : 0 : return ret;
1444 : : }
1445 : 0 : nic->pki.initialized = true;
1446 : : }
1447 : :
1448 : 0 : rxq->port_id = nic->port_id;
1449 : 0 : rxq->eth_dev = dev;
1450 : 0 : rxq->queue_id = qidx;
1451 : 0 : rxq->evdev = nic->evdev;
1452 : 0 : rxq->ev_queues = ev_queues;
1453 : 0 : rxq->ev_ports = ev_ports;
1454 : 0 : rxq->pool = mb_pool;
1455 : :
1456 : 0 : octeontx_recheck_rx_offloads(rxq);
1457 : 0 : dev->data->rx_queues[qidx] = rxq;
1458 : 0 : dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
1459 : :
1460 : 0 : return 0;
1461 : : }
1462 : :
1463 : : static void
1464 : 0 : octeontx_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
1465 : : {
1466 : 0 : rte_free(dev->data->rx_queues[qid]);
1467 : 0 : }
1468 : :
1469 : : static const uint32_t *
1470 : 0 : octeontx_dev_supported_ptypes_get(struct rte_eth_dev *dev,
1471 : : size_t *no_of_elements)
1472 : : {
1473 : : static const uint32_t ptypes[] = {
1474 : : RTE_PTYPE_L3_IPV4,
1475 : : RTE_PTYPE_L3_IPV4_EXT,
1476 : : RTE_PTYPE_L3_IPV6,
1477 : : RTE_PTYPE_L3_IPV6_EXT,
1478 : : RTE_PTYPE_L4_TCP,
1479 : : RTE_PTYPE_L4_UDP,
1480 : : RTE_PTYPE_L4_FRAG,
1481 : : };
1482 : :
1483 [ # # ]: 0 : if (dev->rx_pkt_burst == octeontx_recv_pkts) {
1484 : 0 : *no_of_elements = RTE_DIM(ptypes);
1485 : 0 : return ptypes;
1486 : : }
1487 : : return NULL;
1488 : : }
1489 : :
1490 : : static int
1491 : 0 : octeontx_pool_ops(struct rte_eth_dev *dev, const char *pool)
1492 : : {
1493 : : RTE_SET_USED(dev);
1494 : :
1495 [ # # ]: 0 : if (!strcmp(pool, "octeontx_fpavf"))
1496 : 0 : return 0;
1497 : :
1498 : : return -ENOTSUP;
1499 : : }
1500 : :
1501 : : /* Initialize and register driver with DPDK Application */
1502 : : static const struct eth_dev_ops octeontx_dev_ops = {
1503 : : .dev_configure = octeontx_dev_configure,
1504 : : .dev_infos_get = octeontx_dev_info,
1505 : : .dev_close = octeontx_dev_close,
1506 : : .dev_start = octeontx_dev_start,
1507 : : .dev_stop = octeontx_dev_stop,
1508 : : .promiscuous_enable = octeontx_dev_promisc_enable,
1509 : : .promiscuous_disable = octeontx_dev_promisc_disable,
1510 : : .link_update = octeontx_dev_link_update,
1511 : : .stats_get = octeontx_dev_stats_get,
1512 : : .stats_reset = octeontx_dev_stats_reset,
1513 : : .mac_addr_remove = octeontx_dev_mac_addr_del,
1514 : : .mac_addr_add = octeontx_dev_mac_addr_add,
1515 : : .mac_addr_set = octeontx_dev_default_mac_addr_set,
1516 : : .vlan_offload_set = octeontx_dev_vlan_offload_set,
1517 : : .vlan_filter_set = octeontx_dev_vlan_filter_set,
1518 : : .tx_queue_start = octeontx_dev_tx_queue_start,
1519 : : .tx_queue_stop = octeontx_dev_tx_queue_stop,
1520 : : .tx_queue_setup = octeontx_dev_tx_queue_setup,
1521 : : .tx_queue_release = octeontx_dev_tx_queue_release,
1522 : : .rx_queue_setup = octeontx_dev_rx_queue_setup,
1523 : : .rx_queue_release = octeontx_dev_rx_queue_release,
1524 : : .dev_set_link_up = octeontx_dev_set_link_up,
1525 : : .dev_set_link_down = octeontx_dev_set_link_down,
1526 : : .dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get,
1527 : : .mtu_set = octeontx_dev_mtu_set,
1528 : : .pool_ops_supported = octeontx_pool_ops,
1529 : : .flow_ctrl_get = octeontx_dev_flow_ctrl_get,
1530 : : .flow_ctrl_set = octeontx_dev_flow_ctrl_set,
1531 : : .xstats_get = octeontx_dev_xstats_get,
1532 : : .xstats_get_by_id = octeontx_dev_xstats_get_by_id,
1533 : : .xstats_get_names = octeontx_dev_xstats_get_names,
1534 : : .xstats_get_names_by_id = octeontx_dev_xstats_get_names_by_id,
1535 : : .allmulticast_enable = octeontx_allmulticast_enable,
1536 : : .allmulticast_disable = octeontx_allmulticast_disable,
1537 : : };
1538 : :
1539 : : /* Create Ethdev interface per BGX LMAC ports */
1540 : : static int
1541 [ # # ]: 0 : octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
1542 : : int socket_id)
1543 : : {
1544 : : int res;
1545 : : size_t pko_vfid;
1546 : : char octtx_name[OCTEONTX_MAX_NAME_LEN];
1547 : : struct octeontx_nic *nic = NULL;
1548 : : struct rte_eth_dev *eth_dev = NULL;
1549 : : struct rte_eth_dev_data *data;
1550 : : const char *name = rte_vdev_device_name(dev);
1551 : : int max_entries;
1552 : :
1553 : 0 : PMD_INIT_FUNC_TRACE();
1554 : :
1555 : : sprintf(octtx_name, "%s_%d", name, port);
1556 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1557 : 0 : eth_dev = rte_eth_dev_attach_secondary(octtx_name);
1558 [ # # ]: 0 : if (eth_dev == NULL)
1559 : : return -ENODEV;
1560 : :
1561 : 0 : eth_dev->dev_ops = &octeontx_dev_ops;
1562 : 0 : eth_dev->device = &dev->device;
1563 : 0 : octeontx_set_tx_function(eth_dev);
1564 : 0 : eth_dev->rx_pkt_burst = octeontx_recv_pkts;
1565 : 0 : rte_eth_dev_probing_finish(eth_dev);
1566 : 0 : return 0;
1567 : : }
1568 : :
1569 : : /* Reserve an ethdev entry */
1570 : 0 : eth_dev = rte_eth_dev_allocate(octtx_name);
1571 [ # # ]: 0 : if (eth_dev == NULL) {
1572 : 0 : octeontx_log_err("failed to allocate rte_eth_dev");
1573 : : res = -ENOMEM;
1574 : 0 : goto err;
1575 : : }
1576 : 0 : data = eth_dev->data;
1577 : :
1578 : 0 : nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id);
1579 [ # # ]: 0 : if (nic == NULL) {
1580 : 0 : octeontx_log_err("failed to allocate nic structure");
1581 : : res = -ENOMEM;
1582 : 0 : goto err;
1583 : : }
1584 : 0 : data->dev_private = nic;
1585 : 0 : pko_vfid = octeontx_pko_get_vfid();
1586 : :
1587 [ # # ]: 0 : if (pko_vfid == SIZE_MAX) {
1588 : 0 : octeontx_log_err("failed to get pko vfid");
1589 : : res = -ENODEV;
1590 : 0 : goto err;
1591 : : }
1592 : :
1593 : 0 : nic->pko_vfid = pko_vfid;
1594 : 0 : nic->port_id = port;
1595 : 0 : nic->evdev = evdev;
1596 : 0 : rte_atomic_fetch_add_explicit(&evdev_refcnt, 1, rte_memory_order_acquire);
1597 : :
1598 : 0 : res = octeontx_port_open(nic);
1599 [ # # ]: 0 : if (res < 0)
1600 : 0 : goto err;
1601 : :
1602 : : /* Rx side port configuration */
1603 : 0 : res = octeontx_pki_port_open(port);
1604 [ # # ]: 0 : if (res != 0) {
1605 : 0 : octeontx_log_err("failed to open PKI port %d", port);
1606 : : res = -ENODEV;
1607 : 0 : goto err;
1608 : : }
1609 : :
1610 : 0 : eth_dev->device = &dev->device;
1611 : 0 : eth_dev->intr_handle = NULL;
1612 : 0 : eth_dev->data->numa_node = dev->device.numa_node;
1613 : :
1614 : 0 : data->port_id = eth_dev->data->port_id;
1615 : :
1616 : 0 : nic->ev_queues = 1;
1617 : 0 : nic->ev_ports = 1;
1618 : 0 : nic->print_flag = -1;
1619 : 0 : nic->reconfigure = false;
1620 : :
1621 : 0 : data->dev_link.link_status = RTE_ETH_LINK_DOWN;
1622 : 0 : data->dev_started = 0;
1623 : 0 : data->promiscuous = 0;
1624 : 0 : data->all_multicast = 0;
1625 : 0 : data->scattered_rx = 0;
1626 : :
1627 : : /* Get maximum number of supported MAC entries */
1628 : 0 : max_entries = octeontx_bgx_port_mac_entries_get(nic->port_id);
1629 [ # # ]: 0 : if (max_entries < 0) {
1630 : 0 : octeontx_log_err("Failed to get max entries for mac addr");
1631 : : res = -ENOTSUP;
1632 : 0 : goto err;
1633 : : }
1634 : :
1635 : 0 : data->mac_addrs = rte_zmalloc_socket(octtx_name, max_entries *
1636 : : RTE_ETHER_ADDR_LEN, 0,
1637 : : socket_id);
1638 [ # # ]: 0 : if (data->mac_addrs == NULL) {
1639 : 0 : octeontx_log_err("failed to allocate memory for mac_addrs");
1640 : : res = -ENOMEM;
1641 : 0 : goto err;
1642 : : }
1643 : :
1644 : 0 : eth_dev->dev_ops = &octeontx_dev_ops;
1645 : :
1646 : : /* Finally save ethdev pointer to the NIC structure */
1647 : 0 : nic->dev = eth_dev;
1648 : :
1649 [ # # ]: 0 : if (nic->port_id != data->port_id) {
1650 : 0 : octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)",
1651 : : data->port_id, nic->port_id);
1652 : : res = -EINVAL;
1653 : 0 : goto free_mac_addrs;
1654 : : }
1655 : :
1656 : 0 : res = rte_eal_alarm_set(OCCTX_INTR_POLL_INTERVAL_MS * 1000,
1657 : : octeontx_link_status_poll, nic);
1658 [ # # ]: 0 : if (res) {
1659 : 0 : octeontx_log_err("Failed to start link polling alarm");
1660 : 0 : goto err;
1661 : : }
1662 : :
1663 : : /* Update port_id mac to eth_dev */
1664 : 0 : memcpy(data->mac_addrs, nic->mac_addr, RTE_ETHER_ADDR_LEN);
1665 : :
1666 : : /* Update same mac address to BGX CAM table at index 0 */
1667 : 0 : octeontx_bgx_port_mac_add(nic->port_id, nic->mac_addr, 0);
1668 : :
1669 : 0 : res = octeontx_dev_flow_ctrl_init(eth_dev);
1670 [ # # ]: 0 : if (res < 0)
1671 : 0 : goto err;
1672 : :
1673 : 0 : PMD_INIT_LOG(DEBUG, "ethdev info: ");
1674 : 0 : PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
1675 : : nic->port_id, nic->port_ena,
1676 : : nic->base_ochan, nic->num_ochans,
1677 : : nic->num_tx_queues);
1678 : 0 : PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->bgx_mtu);
1679 : :
1680 : 0 : rte_octeontx_pchan_map[(nic->base_ochan >> 8) & 0x7]
1681 : 0 : [(nic->base_ochan >> 4) & 0xF] = data->port_id;
1682 : :
1683 : 0 : rte_eth_dev_probing_finish(eth_dev);
1684 : 0 : return data->port_id;
1685 : :
1686 : : free_mac_addrs:
1687 : 0 : rte_free(data->mac_addrs);
1688 : 0 : data->mac_addrs = NULL;
1689 : 0 : err:
1690 [ # # ]: 0 : if (nic)
1691 : 0 : octeontx_port_close(nic);
1692 : :
1693 : 0 : rte_eth_dev_release_port(eth_dev);
1694 : :
1695 : 0 : return res;
1696 : : }
1697 : :
1698 : : /* Un initialize octeontx device */
1699 : : static int
1700 : 0 : octeontx_remove(struct rte_vdev_device *dev)
1701 : : {
1702 : : char octtx_name[OCTEONTX_MAX_NAME_LEN];
1703 : : struct rte_eth_dev *eth_dev = NULL;
1704 : : struct octeontx_nic *nic = NULL;
1705 : : int i;
1706 : :
1707 [ # # ]: 0 : if (dev == NULL)
1708 : : return -EINVAL;
1709 : :
1710 [ # # ]: 0 : for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
1711 : : sprintf(octtx_name, "eth_octeontx_%d", i);
1712 : :
1713 : 0 : eth_dev = rte_eth_dev_allocated(octtx_name);
1714 [ # # ]: 0 : if (eth_dev == NULL)
1715 : 0 : continue; /* port already released */
1716 : :
1717 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1718 : 0 : rte_eth_dev_release_port(eth_dev);
1719 : 0 : continue;
1720 : : }
1721 : :
1722 : : nic = octeontx_pmd_priv(eth_dev);
1723 : 0 : rte_event_dev_stop(nic->evdev);
1724 : 0 : PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
1725 : 0 : octeontx_dev_close(eth_dev);
1726 : 0 : rte_eth_dev_release_port(eth_dev);
1727 : : }
1728 : :
1729 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1730 : : return 0;
1731 : :
1732 : : /* Free FC resource */
1733 : 0 : octeontx_pko_fc_free();
1734 : :
1735 : 0 : return 0;
1736 : : }
1737 : :
1738 : : /* Initialize octeontx device */
1739 : : static int
1740 : 0 : octeontx_probe(struct rte_vdev_device *dev)
1741 : : {
1742 : : const char *dev_name;
1743 : : static int probe_once;
1744 : : uint8_t socket_id, qlist;
1745 : : int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
1746 : : struct rte_event_dev_config dev_conf;
1747 : : const char *eventdev_name = "event_octeontx";
1748 : : struct rte_event_dev_info info;
1749 : : struct rte_eth_dev *eth_dev;
1750 : :
1751 [ # # ]: 0 : struct octeontx_vdev_init_params init_params = {
1752 : : OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
1753 : : };
1754 : :
1755 : : dev_name = rte_vdev_device_name(dev);
1756 : :
1757 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
1758 [ # # ]: 0 : strlen(rte_vdev_device_args(dev)) == 0) {
1759 : 0 : eth_dev = rte_eth_dev_attach_secondary(dev_name);
1760 [ # # ]: 0 : if (!eth_dev) {
1761 : 0 : PMD_INIT_LOG(ERR, "Failed to probe %s", dev_name);
1762 : 0 : return -1;
1763 : : }
1764 : : /* TODO: request info from primary to set up Rx and Tx */
1765 : 0 : eth_dev->dev_ops = &octeontx_dev_ops;
1766 : 0 : eth_dev->device = &dev->device;
1767 : 0 : rte_eth_dev_probing_finish(eth_dev);
1768 : 0 : return 0;
1769 : : }
1770 : :
1771 : 0 : res = octeontx_parse_vdev_init_params(&init_params, dev);
1772 [ # # ]: 0 : if (res < 0)
1773 : : return -EINVAL;
1774 : :
1775 [ # # ]: 0 : if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
1776 : 0 : octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
1777 : : OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
1778 : 0 : return -ENOTSUP;
1779 : : }
1780 : :
1781 : 0 : PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
1782 : :
1783 : 0 : socket_id = rte_socket_id();
1784 : :
1785 : 0 : tx_vfcnt = octeontx_pko_vf_count();
1786 : :
1787 [ # # ]: 0 : if (tx_vfcnt < init_params.nr_port) {
1788 : 0 : octeontx_log_err("not enough PKO (%d) for port number (%d)",
1789 : : tx_vfcnt, init_params.nr_port);
1790 : 0 : return -EINVAL;
1791 : : }
1792 : 0 : evdev = rte_event_dev_get_dev_id(eventdev_name);
1793 [ # # ]: 0 : if (evdev < 0) {
1794 : 0 : octeontx_log_err("eventdev %s not found", eventdev_name);
1795 : 0 : return -ENODEV;
1796 : : }
1797 : :
1798 : 0 : res = rte_event_dev_info_get(evdev, &info);
1799 [ # # ]: 0 : if (res < 0) {
1800 : 0 : octeontx_log_err("failed to eventdev info %d", res);
1801 : 0 : return -EINVAL;
1802 : : }
1803 : :
1804 : 0 : PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
1805 : : info.max_event_queues, info.max_event_ports);
1806 : :
1807 [ # # ]: 0 : if (octeontx_pko_init_fc(tx_vfcnt))
1808 : : return -ENOMEM;
1809 : :
1810 : 0 : devconf_set_default_sane_values(&dev_conf, &info);
1811 : 0 : res = rte_event_dev_configure(evdev, &dev_conf);
1812 [ # # ]: 0 : if (res < 0)
1813 : 0 : goto parse_error;
1814 : :
1815 : 0 : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
1816 : : (uint32_t *)&pnum);
1817 : 0 : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
1818 : : (uint32_t *)&qnum);
1819 [ # # ]: 0 : if (pnum < qnum) {
1820 : 0 : octeontx_log_err("too few event ports (%d) for event_q(%d)",
1821 : : pnum, qnum);
1822 : : res = -EINVAL;
1823 : 0 : goto parse_error;
1824 : : }
1825 : :
1826 : : /* Enable all queues available */
1827 [ # # ]: 0 : for (i = 0; i < qnum; i++) {
1828 : 0 : res = rte_event_queue_setup(evdev, i, NULL);
1829 [ # # ]: 0 : if (res < 0) {
1830 : 0 : octeontx_log_err("failed to setup event_q(%d): res %d",
1831 : : i, res);
1832 : 0 : goto parse_error;
1833 : : }
1834 : : }
1835 : :
1836 : : /* Enable all ports available */
1837 [ # # ]: 0 : for (i = 0; i < pnum; i++) {
1838 : 0 : res = rte_event_port_setup(evdev, i, NULL);
1839 [ # # ]: 0 : if (res < 0) {
1840 : : res = -ENODEV;
1841 : 0 : octeontx_log_err("failed to setup ev port(%d) res=%d",
1842 : : i, res);
1843 : 0 : goto parse_error;
1844 : : }
1845 : : }
1846 : :
1847 : 0 : rte_atomic_store_explicit(&evdev_refcnt, 0, rte_memory_order_release);
1848 : : /*
1849 : : * Do 1:1 links for ports & queues. All queues would be mapped to
1850 : : * one port. If there are more ports than queues, then some ports
1851 : : * won't be linked to any queue.
1852 : : */
1853 [ # # ]: 0 : for (i = 0; i < qnum; i++) {
1854 : : /* Link one queue to one event port */
1855 : 0 : qlist = i;
1856 : 0 : res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
1857 [ # # ]: 0 : if (res < 0) {
1858 : : res = -ENODEV;
1859 : 0 : octeontx_log_err("failed to link port (%d): res=%d",
1860 : : i, res);
1861 : 0 : goto parse_error;
1862 : : }
1863 : : }
1864 : :
1865 : : /* Create ethdev interface */
1866 [ # # ]: 0 : for (i = 0; i < init_params.nr_port; i++) {
1867 : 0 : port_id = octeontx_create(dev, i, evdev, socket_id);
1868 [ # # ]: 0 : if (port_id < 0) {
1869 : 0 : octeontx_log_err("failed to create device %s",
1870 : : dev_name);
1871 : : res = -ENODEV;
1872 : 0 : goto parse_error;
1873 : : }
1874 : :
1875 : 0 : PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
1876 : : port_id);
1877 : : }
1878 : :
1879 [ # # ]: 0 : if (probe_once) {
1880 : 0 : octeontx_log_err("interface %s not supported", dev_name);
1881 : 0 : octeontx_remove(dev);
1882 : : res = -ENOTSUP;
1883 : 0 : goto parse_error;
1884 : : }
1885 : 0 : rte_mbuf_set_platform_mempool_ops("octeontx_fpavf");
1886 : 0 : probe_once = 1;
1887 : :
1888 : 0 : return 0;
1889 : :
1890 : 0 : parse_error:
1891 : 0 : octeontx_pko_fc_free();
1892 : 0 : return res;
1893 : : }
1894 : :
1895 : : static struct rte_vdev_driver octeontx_pmd_drv = {
1896 : : .probe = octeontx_probe,
1897 : : .remove = octeontx_remove,
1898 : : };
1899 : :
1900 : 252 : RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
1901 : : RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
1902 : : RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");
|