drivers: use SPDX tag in NXP dpaa2 files
[dpdk.git] / drivers / net / dpaa2 / dpaa2_ethdev.c
1 /* * SPDX-License-Identifier: BSD-3-Clause
2  *
3  *   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
4  *   Copyright 2016 NXP
5  *
6  */
7
8 #include <time.h>
9 #include <net/if.h>
10
11 #include <rte_mbuf.h>
12 #include <rte_ethdev.h>
13 #include <rte_malloc.h>
14 #include <rte_memcpy.h>
15 #include <rte_string_fns.h>
16 #include <rte_cycles.h>
17 #include <rte_kvargs.h>
18 #include <rte_dev.h>
19 #include <rte_fslmc.h>
20
21 #include <fslmc_logs.h>
22 #include <fslmc_vfio.h>
23 #include <dpaa2_hw_pvt.h>
24 #include <dpaa2_hw_mempool.h>
25 #include <dpaa2_hw_dpio.h>
26 #include <mc/fsl_dpmng.h>
27 #include "dpaa2_ethdev.h"
28
29 struct rte_dpaa2_xstats_name_off {
30         char name[RTE_ETH_XSTATS_NAME_SIZE];
31         uint8_t page_id; /* dpni statistics page id */
32         uint8_t stats_id; /* stats id in the given page */
33 };
34
35 static const struct rte_dpaa2_xstats_name_off dpaa2_xstats_strings[] = {
36         {"ingress_multicast_frames", 0, 2},
37         {"ingress_multicast_bytes", 0, 3},
38         {"ingress_broadcast_frames", 0, 4},
39         {"ingress_broadcast_bytes", 0, 5},
40         {"egress_multicast_frames", 1, 2},
41         {"egress_multicast_bytes", 1, 3},
42         {"egress_broadcast_frames", 1, 4},
43         {"egress_broadcast_bytes", 1, 5},
44         {"ingress_filtered_frames", 2, 0},
45         {"ingress_discarded_frames", 2, 1},
46         {"ingress_nobuffer_discards", 2, 2},
47         {"egress_discarded_frames", 2, 3},
48         {"egress_confirmed_frames", 2, 4},
49 };
50
51 static struct rte_dpaa2_driver rte_dpaa2_pmd;
52 static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev);
53 static int dpaa2_dev_link_update(struct rte_eth_dev *dev,
54                                  int wait_to_complete);
55 static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev);
56 static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev);
57 static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
58
59 /**
60  * Atomically reads the link status information from global
61  * structure rte_eth_dev.
62  *
63  * @param dev
64  *   - Pointer to the structure rte_eth_dev to read from.
65  *   - Pointer to the buffer to be saved with the link status.
66  *
67  * @return
68  *   - On success, zero.
69  *   - On failure, negative value.
70  */
71 static inline int
72 dpaa2_dev_atomic_read_link_status(struct rte_eth_dev *dev,
73                                   struct rte_eth_link *link)
74 {
75         struct rte_eth_link *dst = link;
76         struct rte_eth_link *src = &dev->data->dev_link;
77
78         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
79                                 *(uint64_t *)src) == 0)
80                 return -1;
81
82         return 0;
83 }
84
85 /**
86  * Atomically writes the link status information into global
87  * structure rte_eth_dev.
88  *
89  * @param dev
90  *   - Pointer to the structure rte_eth_dev to read from.
91  *   - Pointer to the buffer to be saved with the link status.
92  *
93  * @return
94  *   - On success, zero.
95  *   - On failure, negative value.
96  */
97 static inline int
98 dpaa2_dev_atomic_write_link_status(struct rte_eth_dev *dev,
99                                    struct rte_eth_link *link)
100 {
101         struct rte_eth_link *dst = &dev->data->dev_link;
102         struct rte_eth_link *src = link;
103
104         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
105                                 *(uint64_t *)src) == 0)
106                 return -1;
107
108         return 0;
109 }
110
111 static int
112 dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
113 {
114         int ret;
115         struct dpaa2_dev_priv *priv = dev->data->dev_private;
116         struct fsl_mc_io *dpni = priv->hw;
117
118         PMD_INIT_FUNC_TRACE();
119
120         if (dpni == NULL) {
121                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
122                 return -1;
123         }
124
125         if (on)
126                 ret = dpni_add_vlan_id(dpni, CMD_PRI_LOW,
127                                        priv->token, vlan_id);
128         else
129                 ret = dpni_remove_vlan_id(dpni, CMD_PRI_LOW,
130                                           priv->token, vlan_id);
131
132         if (ret < 0)
133                 PMD_DRV_LOG(ERR, "ret = %d Unable to add/rem vlan %d hwid =%d",
134                             ret, vlan_id, priv->hw_id);
135
136         return ret;
137 }
138
139 static int
140 dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask)
141 {
142         struct dpaa2_dev_priv *priv = dev->data->dev_private;
143         struct fsl_mc_io *dpni = priv->hw;
144         int ret;
145
146         PMD_INIT_FUNC_TRACE();
147
148         if (mask & ETH_VLAN_FILTER_MASK) {
149                 if (dev->data->dev_conf.rxmode.hw_vlan_filter)
150                         ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW,
151                                                       priv->token, true);
152                 else
153                         ret = dpni_enable_vlan_filter(dpni, CMD_PRI_LOW,
154                                                       priv->token, false);
155                 if (ret < 0)
156                         RTE_LOG(ERR, PMD, "Unable to set vlan filter = %d\n",
157                                 ret);
158         }
159
160         if (mask & ETH_VLAN_EXTEND_MASK) {
161                 if (dev->data->dev_conf.rxmode.hw_vlan_extend)
162                         RTE_LOG(INFO, PMD,
163                                 "VLAN extend offload not supported\n");
164         }
165
166         return 0;
167 }
168
169 static int
170 dpaa2_fw_version_get(struct rte_eth_dev *dev,
171                      char *fw_version,
172                      size_t fw_size)
173 {
174         int ret;
175         struct dpaa2_dev_priv *priv = dev->data->dev_private;
176         struct fsl_mc_io *dpni = priv->hw;
177         struct mc_soc_version mc_plat_info = {0};
178         struct mc_version mc_ver_info = {0};
179
180         PMD_INIT_FUNC_TRACE();
181
182         if (mc_get_soc_version(dpni, CMD_PRI_LOW, &mc_plat_info))
183                 RTE_LOG(WARNING, PMD, "\tmc_get_soc_version failed\n");
184
185         if (mc_get_version(dpni, CMD_PRI_LOW, &mc_ver_info))
186                 RTE_LOG(WARNING, PMD, "\tmc_get_version failed\n");
187
188         ret = snprintf(fw_version, fw_size,
189                        "%x-%d.%d.%d",
190                        mc_plat_info.svr,
191                        mc_ver_info.major,
192                        mc_ver_info.minor,
193                        mc_ver_info.revision);
194
195         ret += 1; /* add the size of '\0' */
196         if (fw_size < (uint32_t)ret)
197                 return ret;
198         else
199                 return 0;
200 }
201
202 static void
203 dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
204 {
205         struct dpaa2_dev_priv *priv = dev->data->dev_private;
206
207         PMD_INIT_FUNC_TRACE();
208
209         dev_info->if_index = priv->hw_id;
210
211         dev_info->max_mac_addrs = priv->max_mac_filters;
212         dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN;
213         dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE;
214         dev_info->max_rx_queues = (uint16_t)priv->nb_rx_queues;
215         dev_info->max_tx_queues = (uint16_t)priv->nb_tx_queues;
216         dev_info->rx_offload_capa =
217                 DEV_RX_OFFLOAD_IPV4_CKSUM |
218                 DEV_RX_OFFLOAD_UDP_CKSUM |
219                 DEV_RX_OFFLOAD_TCP_CKSUM |
220                 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
221         dev_info->tx_offload_capa =
222                 DEV_TX_OFFLOAD_IPV4_CKSUM |
223                 DEV_TX_OFFLOAD_UDP_CKSUM |
224                 DEV_TX_OFFLOAD_TCP_CKSUM |
225                 DEV_TX_OFFLOAD_SCTP_CKSUM |
226                 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
227         dev_info->speed_capa = ETH_LINK_SPEED_1G |
228                         ETH_LINK_SPEED_2_5G |
229                         ETH_LINK_SPEED_10G;
230 }
231
232 static int
233 dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev)
234 {
235         struct dpaa2_dev_priv *priv = dev->data->dev_private;
236         uint16_t dist_idx;
237         uint32_t vq_id;
238         struct dpaa2_queue *mc_q, *mcq;
239         uint32_t tot_queues;
240         int i;
241         struct dpaa2_queue *dpaa2_q;
242
243         PMD_INIT_FUNC_TRACE();
244
245         tot_queues = priv->nb_rx_queues + priv->nb_tx_queues;
246         mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues,
247                           RTE_CACHE_LINE_SIZE);
248         if (!mc_q) {
249                 PMD_INIT_LOG(ERR, "malloc failed for rx/tx queues\n");
250                 return -1;
251         }
252
253         for (i = 0; i < priv->nb_rx_queues; i++) {
254                 mc_q->dev = dev;
255                 priv->rx_vq[i] = mc_q++;
256                 dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
257                 dpaa2_q->q_storage = rte_malloc("dq_storage",
258                                         sizeof(struct queue_storage_info_t),
259                                         RTE_CACHE_LINE_SIZE);
260                 if (!dpaa2_q->q_storage)
261                         goto fail;
262
263                 memset(dpaa2_q->q_storage, 0,
264                        sizeof(struct queue_storage_info_t));
265                 if (dpaa2_alloc_dq_storage(dpaa2_q->q_storage))
266                         goto fail;
267         }
268
269         for (i = 0; i < priv->nb_tx_queues; i++) {
270                 mc_q->dev = dev;
271                 mc_q->flow_id = 0xffff;
272                 priv->tx_vq[i] = mc_q++;
273                 dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
274                 dpaa2_q->cscn = rte_malloc(NULL,
275                                            sizeof(struct qbman_result), 16);
276                 if (!dpaa2_q->cscn)
277                         goto fail_tx;
278         }
279
280         vq_id = 0;
281         for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) {
282                 mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id];
283                 mcq->tc_index = DPAA2_DEF_TC;
284                 mcq->flow_id = dist_idx;
285                 vq_id++;
286         }
287
288         return 0;
289 fail_tx:
290         i -= 1;
291         while (i >= 0) {
292                 dpaa2_q = (struct dpaa2_queue *)priv->tx_vq[i];
293                 rte_free(dpaa2_q->cscn);
294                 priv->tx_vq[i--] = NULL;
295         }
296         i = priv->nb_rx_queues;
297 fail:
298         i -= 1;
299         mc_q = priv->rx_vq[0];
300         while (i >= 0) {
301                 dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
302                 dpaa2_free_dq_storage(dpaa2_q->q_storage);
303                 rte_free(dpaa2_q->q_storage);
304                 priv->rx_vq[i--] = NULL;
305         }
306         rte_free(mc_q);
307         return -1;
308 }
309
310 static int
311 dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
312 {
313         struct dpaa2_dev_priv *priv = dev->data->dev_private;
314         struct fsl_mc_io *dpni = priv->hw;
315         struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
316         int rx_ip_csum_offload = false;
317         int ret;
318
319         PMD_INIT_FUNC_TRACE();
320
321         if (eth_conf->rxmode.jumbo_frame == 1) {
322                 if (eth_conf->rxmode.max_rx_pkt_len <= DPAA2_MAX_RX_PKT_LEN) {
323                         ret = dpaa2_dev_mtu_set(dev,
324                                         eth_conf->rxmode.max_rx_pkt_len);
325                         if (ret) {
326                                 PMD_INIT_LOG(ERR,
327                                              "unable to set mtu. check config\n");
328                                 return ret;
329                         }
330                 } else {
331                         return -1;
332                 }
333         }
334
335         if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) {
336                 ret = dpaa2_setup_flow_dist(dev,
337                                 eth_conf->rx_adv_conf.rss_conf.rss_hf);
338                 if (ret) {
339                         PMD_INIT_LOG(ERR, "unable to set flow distribution."
340                                      "please check queue config\n");
341                         return ret;
342                 }
343         }
344
345         if (eth_conf->rxmode.hw_ip_checksum)
346                 rx_ip_csum_offload = true;
347
348         ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
349                                DPNI_OFF_RX_L3_CSUM, rx_ip_csum_offload);
350         if (ret) {
351                 PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret);
352                 return ret;
353         }
354
355         ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
356                                DPNI_OFF_RX_L4_CSUM, rx_ip_csum_offload);
357         if (ret) {
358                 PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret);
359                 return ret;
360         }
361
362         ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
363                                DPNI_OFF_TX_L3_CSUM, true);
364         if (ret) {
365                 PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret);
366                 return ret;
367         }
368
369         ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
370                                DPNI_OFF_TX_L4_CSUM, true);
371         if (ret) {
372                 PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret);
373                 return ret;
374         }
375
376         /* update the current status */
377         dpaa2_dev_link_update(dev, 0);
378
379         return 0;
380 }
381
382 /* Function to setup RX flow information. It contains traffic class ID,
383  * flow ID, destination configuration etc.
384  */
385 static int
386 dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
387                          uint16_t rx_queue_id,
388                          uint16_t nb_rx_desc __rte_unused,
389                          unsigned int socket_id __rte_unused,
390                          const struct rte_eth_rxconf *rx_conf __rte_unused,
391                          struct rte_mempool *mb_pool)
392 {
393         struct dpaa2_dev_priv *priv = dev->data->dev_private;
394         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
395         struct mc_soc_version mc_plat_info = {0};
396         struct dpaa2_queue *dpaa2_q;
397         struct dpni_queue cfg;
398         uint8_t options = 0;
399         uint8_t flow_id;
400         uint32_t bpid;
401         int ret;
402
403         PMD_INIT_FUNC_TRACE();
404
405         PMD_DRV_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
406                     dev, rx_queue_id, mb_pool, rx_conf);
407
408         if (!priv->bp_list || priv->bp_list->mp != mb_pool) {
409                 bpid = mempool_to_bpid(mb_pool);
410                 ret = dpaa2_attach_bp_list(priv,
411                                            rte_dpaa2_bpid_info[bpid].bp_list);
412                 if (ret)
413                         return ret;
414         }
415         dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[rx_queue_id];
416         dpaa2_q->mb_pool = mb_pool; /**< mbuf pool to populate RX ring. */
417
418         /*Get the flow id from given VQ id*/
419         flow_id = rx_queue_id % priv->nb_rx_queues;
420         memset(&cfg, 0, sizeof(struct dpni_queue));
421
422         options = options | DPNI_QUEUE_OPT_USER_CTX;
423         cfg.user_context = (uint64_t)(dpaa2_q);
424
425         /*if ls2088 or rev2 device, enable the stashing */
426
427         if (mc_get_soc_version(dpni, CMD_PRI_LOW, &mc_plat_info))
428                 PMD_INIT_LOG(ERR, "\tmc_get_soc_version failed\n");
429
430         if ((mc_plat_info.svr & 0xffff0000) != SVR_LS2080A) {
431                 options |= DPNI_QUEUE_OPT_FLC;
432                 cfg.flc.stash_control = true;
433                 cfg.flc.value &= 0xFFFFFFFFFFFFFFC0;
434                 /* 00 00 00 - last 6 bit represent annotation, context stashing,
435                  * data stashing setting 01 01 00 (0x14) to enable
436                  * 1 line data, 1 line annotation
437                  */
438                 cfg.flc.value |= 0x14;
439         }
440         ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_RX,
441                              dpaa2_q->tc_index, flow_id, options, &cfg);
442         if (ret) {
443                 PMD_INIT_LOG(ERR, "Error in setting the rx flow: = %d\n", ret);
444                 return -1;
445         }
446
447         if (!(priv->flags & DPAA2_RX_TAILDROP_OFF)) {
448                 struct dpni_taildrop taildrop;
449
450                 taildrop.enable = 1;
451                 /*enabling per rx queue congestion control */
452                 taildrop.threshold = CONG_THRESHOLD_RX_Q;
453                 taildrop.units = DPNI_CONGESTION_UNIT_BYTES;
454                 taildrop.oal = CONG_RX_OAL;
455                 PMD_DRV_LOG(DEBUG, "Enabling Early Drop on queue = %d",
456                             rx_queue_id);
457                 ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
458                                         DPNI_CP_QUEUE, DPNI_QUEUE_RX,
459                                         dpaa2_q->tc_index, flow_id, &taildrop);
460                 if (ret) {
461                         PMD_INIT_LOG(ERR, "Error in setting the rx flow"
462                                      " err : = %d\n", ret);
463                         return -1;
464                 }
465         }
466
467         dev->data->rx_queues[rx_queue_id] = dpaa2_q;
468         return 0;
469 }
470
471 static int
472 dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev,
473                          uint16_t tx_queue_id,
474                          uint16_t nb_tx_desc __rte_unused,
475                          unsigned int socket_id __rte_unused,
476                          const struct rte_eth_txconf *tx_conf __rte_unused)
477 {
478         struct dpaa2_dev_priv *priv = dev->data->dev_private;
479         struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)
480                 priv->tx_vq[tx_queue_id];
481         struct fsl_mc_io *dpni = priv->hw;
482         struct dpni_queue tx_conf_cfg;
483         struct dpni_queue tx_flow_cfg;
484         uint8_t options = 0, flow_id;
485         uint32_t tc_id;
486         int ret;
487
488         PMD_INIT_FUNC_TRACE();
489
490         /* Return if queue already configured */
491         if (dpaa2_q->flow_id != 0xffff) {
492                 dev->data->tx_queues[tx_queue_id] = dpaa2_q;
493                 return 0;
494         }
495
496         memset(&tx_conf_cfg, 0, sizeof(struct dpni_queue));
497         memset(&tx_flow_cfg, 0, sizeof(struct dpni_queue));
498
499         tc_id = tx_queue_id;
500         flow_id = 0;
501
502         ret = dpni_set_queue(dpni, CMD_PRI_LOW, priv->token, DPNI_QUEUE_TX,
503                              tc_id, flow_id, options, &tx_flow_cfg);
504         if (ret) {
505                 PMD_INIT_LOG(ERR, "Error in setting the tx flow: "
506                              "tc_id=%d, flow =%d ErrorCode = %x\n",
507                              tc_id, flow_id, -ret);
508                         return -1;
509         }
510
511         dpaa2_q->flow_id = flow_id;
512
513         if (tx_queue_id == 0) {
514                 /*Set tx-conf and error configuration*/
515                 ret = dpni_set_tx_confirmation_mode(dpni, CMD_PRI_LOW,
516                                                     priv->token,
517                                                     DPNI_CONF_DISABLE);
518                 if (ret) {
519                         PMD_INIT_LOG(ERR, "Error in set tx conf mode settings"
520                                      " ErrorCode = %x", ret);
521                         return -1;
522                 }
523         }
524         dpaa2_q->tc_index = tc_id;
525
526         if (!(priv->flags & DPAA2_TX_CGR_OFF)) {
527                 struct dpni_congestion_notification_cfg cong_notif_cfg;
528
529                 cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES;
530                 cong_notif_cfg.threshold_entry = CONG_ENTER_TX_THRESHOLD;
531                 /* Notify that the queue is not congested when the data in
532                  * the queue is below this thershold.
533                  */
534                 cong_notif_cfg.threshold_exit = CONG_EXIT_TX_THRESHOLD;
535                 cong_notif_cfg.message_ctx = 0;
536                 cong_notif_cfg.message_iova = (uint64_t)dpaa2_q->cscn;
537                 cong_notif_cfg.dest_cfg.dest_type = DPNI_DEST_NONE;
538                 cong_notif_cfg.notification_mode =
539                                          DPNI_CONG_OPT_WRITE_MEM_ON_ENTER |
540                                          DPNI_CONG_OPT_WRITE_MEM_ON_EXIT |
541                                          DPNI_CONG_OPT_COHERENT_WRITE;
542
543                 ret = dpni_set_congestion_notification(dpni, CMD_PRI_LOW,
544                                                        priv->token,
545                                                        DPNI_QUEUE_TX,
546                                                        tc_id,
547                                                        &cong_notif_cfg);
548                 if (ret) {
549                         PMD_INIT_LOG(ERR,
550                            "Error in setting tx congestion notification: = %d",
551                            -ret);
552                         return -ret;
553                 }
554         }
555         dev->data->tx_queues[tx_queue_id] = dpaa2_q;
556         return 0;
557 }
558
559 static void
560 dpaa2_dev_rx_queue_release(void *q __rte_unused)
561 {
562         PMD_INIT_FUNC_TRACE();
563 }
564
565 static void
566 dpaa2_dev_tx_queue_release(void *q __rte_unused)
567 {
568         PMD_INIT_FUNC_TRACE();
569 }
570
571 static const uint32_t *
572 dpaa2_supported_ptypes_get(struct rte_eth_dev *dev)
573 {
574         static const uint32_t ptypes[] = {
575                 /*todo -= add more types */
576                 RTE_PTYPE_L2_ETHER,
577                 RTE_PTYPE_L3_IPV4,
578                 RTE_PTYPE_L3_IPV4_EXT,
579                 RTE_PTYPE_L3_IPV6,
580                 RTE_PTYPE_L3_IPV6_EXT,
581                 RTE_PTYPE_L4_TCP,
582                 RTE_PTYPE_L4_UDP,
583                 RTE_PTYPE_L4_SCTP,
584                 RTE_PTYPE_L4_ICMP,
585                 RTE_PTYPE_UNKNOWN
586         };
587
588         if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx)
589                 return ptypes;
590         return NULL;
591 }
592
593 /**
594  * Dpaa2 link Interrupt handler
595  *
596  * @param param
597  *  The address of parameter (struct rte_eth_dev *) regsitered before.
598  *
599  * @return
600  *  void
601  */
602 static void
603 dpaa2_interrupt_handler(void *param)
604 {
605         struct rte_eth_dev *dev = param;
606         struct dpaa2_dev_priv *priv = dev->data->dev_private;
607         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
608         int ret;
609         int irq_index = DPNI_IRQ_INDEX;
610         unsigned int status = 0, clear = 0;
611
612         PMD_INIT_FUNC_TRACE();
613
614         if (dpni == NULL) {
615                 RTE_LOG(ERR, PMD, "dpni is NULL");
616                 return;
617         }
618
619         ret = dpni_get_irq_status(dpni, CMD_PRI_LOW, priv->token,
620                                   irq_index, &status);
621         if (unlikely(ret)) {
622                 RTE_LOG(ERR, PMD, "Can't get irq status (err %d)", ret);
623                 clear = 0xffffffff;
624                 goto out;
625         }
626
627         if (status & DPNI_IRQ_EVENT_LINK_CHANGED) {
628                 clear = DPNI_IRQ_EVENT_LINK_CHANGED;
629                 dpaa2_dev_link_update(dev, 0);
630                 /* calling all the apps registered for link status event */
631                 _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
632                                               NULL, NULL);
633         }
634 out:
635         ret = dpni_clear_irq_status(dpni, CMD_PRI_LOW, priv->token,
636                                     irq_index, clear);
637         if (unlikely(ret))
638                 RTE_LOG(ERR, PMD, "Can't clear irq status (err %d)", ret);
639 }
640
641 static int
642 dpaa2_eth_setup_irqs(struct rte_eth_dev *dev, int enable)
643 {
644         int err = 0;
645         struct dpaa2_dev_priv *priv = dev->data->dev_private;
646         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
647         int irq_index = DPNI_IRQ_INDEX;
648         unsigned int mask = DPNI_IRQ_EVENT_LINK_CHANGED;
649
650         PMD_INIT_FUNC_TRACE();
651
652         err = dpni_set_irq_mask(dpni, CMD_PRI_LOW, priv->token,
653                                 irq_index, mask);
654         if (err < 0) {
655                 PMD_INIT_LOG(ERR, "Error: dpni_set_irq_mask():%d (%s)", err,
656                              strerror(-err));
657                 return err;
658         }
659
660         err = dpni_set_irq_enable(dpni, CMD_PRI_LOW, priv->token,
661                                   irq_index, enable);
662         if (err < 0)
663                 PMD_INIT_LOG(ERR, "Error: dpni_set_irq_enable():%d (%s)", err,
664                              strerror(-err));
665
666         return err;
667 }
668
669 static int
670 dpaa2_dev_start(struct rte_eth_dev *dev)
671 {
672         struct rte_device *rdev = dev->device;
673         struct rte_dpaa2_device *dpaa2_dev;
674         struct rte_eth_dev_data *data = dev->data;
675         struct dpaa2_dev_priv *priv = data->dev_private;
676         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
677         struct dpni_queue cfg;
678         struct dpni_error_cfg   err_cfg;
679         uint16_t qdid;
680         struct dpni_queue_id qid;
681         struct dpaa2_queue *dpaa2_q;
682         int ret, i;
683         struct rte_intr_handle *intr_handle;
684
685         dpaa2_dev = container_of(rdev, struct rte_dpaa2_device, device);
686         intr_handle = &dpaa2_dev->intr_handle;
687
688         PMD_INIT_FUNC_TRACE();
689
690         ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
691         if (ret) {
692                 PMD_INIT_LOG(ERR, "Failure %d in enabling dpni %d device\n",
693                              ret, priv->hw_id);
694                 return ret;
695         }
696
697         /* Power up the phy. Needed to make the link go UP */
698         dpaa2_dev_set_link_up(dev);
699
700         ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token,
701                             DPNI_QUEUE_TX, &qdid);
702         if (ret) {
703                 PMD_INIT_LOG(ERR, "Error to get qdid:ErrorCode = %d\n", ret);
704                 return ret;
705         }
706         priv->qdid = qdid;
707
708         for (i = 0; i < data->nb_rx_queues; i++) {
709                 dpaa2_q = (struct dpaa2_queue *)data->rx_queues[i];
710                 ret = dpni_get_queue(dpni, CMD_PRI_LOW, priv->token,
711                                      DPNI_QUEUE_RX, dpaa2_q->tc_index,
712                                        dpaa2_q->flow_id, &cfg, &qid);
713                 if (ret) {
714                         PMD_INIT_LOG(ERR, "Error to get flow "
715                                      "information Error code = %d\n", ret);
716                         return ret;
717                 }
718                 dpaa2_q->fqid = qid.fqid;
719         }
720
721         /*checksum errors, send them to normal path and set it in annotation */
722         err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE;
723
724         err_cfg.error_action = DPNI_ERROR_ACTION_CONTINUE;
725         err_cfg.set_frame_annotation = true;
726
727         ret = dpni_set_errors_behavior(dpni, CMD_PRI_LOW,
728                                        priv->token, &err_cfg);
729         if (ret) {
730                 PMD_INIT_LOG(ERR, "Error to dpni_set_errors_behavior:"
731                              "code = %d\n", ret);
732                 return ret;
733         }
734         /* VLAN Offload Settings */
735         if (priv->max_vlan_filters) {
736                 ret = dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
737                 if (ret) {
738                         PMD_INIT_LOG(ERR, "Error to dpaa2_vlan_offload_set:"
739                                      "code = %d\n", ret);
740                         return ret;
741                 }
742         }
743
744
745         /* if the interrupts were configured on this devices*/
746         if (intr_handle && (intr_handle->fd) &&
747             (dev->data->dev_conf.intr_conf.lsc != 0)) {
748                 /* Registering LSC interrupt handler */
749                 rte_intr_callback_register(intr_handle,
750                                            dpaa2_interrupt_handler,
751                                            (void *)dev);
752
753                 /* enable vfio intr/eventfd mapping
754                  * Interrupt index 0 is required, so we can not use
755                  * rte_intr_enable.
756                  */
757                 rte_dpaa2_intr_enable(intr_handle, DPNI_IRQ_INDEX);
758
759                 /* enable dpni_irqs */
760                 dpaa2_eth_setup_irqs(dev, 1);
761         }
762
763         return 0;
764 }
765
766 /**
767  *  This routine disables all traffic on the adapter by issuing a
768  *  global reset on the MAC.
769  */
770 static void
771 dpaa2_dev_stop(struct rte_eth_dev *dev)
772 {
773         struct dpaa2_dev_priv *priv = dev->data->dev_private;
774         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
775         int ret;
776         struct rte_eth_link link;
777         struct rte_intr_handle *intr_handle = dev->intr_handle;
778
779         PMD_INIT_FUNC_TRACE();
780
781         /* reset interrupt callback  */
782         if (intr_handle && (intr_handle->fd) &&
783             (dev->data->dev_conf.intr_conf.lsc != 0)) {
784                 /*disable dpni irqs */
785                 dpaa2_eth_setup_irqs(dev, 0);
786
787                 /* disable vfio intr before callback unregister */
788                 rte_dpaa2_intr_disable(intr_handle, DPNI_IRQ_INDEX);
789
790                 /* Unregistering LSC interrupt handler */
791                 rte_intr_callback_unregister(intr_handle,
792                                              dpaa2_interrupt_handler,
793                                              (void *)dev);
794         }
795
796         dpaa2_dev_set_link_down(dev);
797
798         ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token);
799         if (ret) {
800                 PMD_INIT_LOG(ERR, "Failure (ret %d) in disabling dpni %d dev\n",
801                              ret, priv->hw_id);
802                 return;
803         }
804
805         /* clear the recorded link status */
806         memset(&link, 0, sizeof(link));
807         dpaa2_dev_atomic_write_link_status(dev, &link);
808 }
809
810 static void
811 dpaa2_dev_close(struct rte_eth_dev *dev)
812 {
813         struct rte_eth_dev_data *data = dev->data;
814         struct dpaa2_dev_priv *priv = dev->data->dev_private;
815         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
816         int i, ret;
817         struct rte_eth_link link;
818         struct dpaa2_queue *dpaa2_q;
819
820         PMD_INIT_FUNC_TRACE();
821
822         for (i = 0; i < data->nb_tx_queues; i++) {
823                 dpaa2_q = (struct dpaa2_queue *)data->tx_queues[i];
824                 if (!dpaa2_q->cscn) {
825                         rte_free(dpaa2_q->cscn);
826                         dpaa2_q->cscn = NULL;
827                 }
828         }
829
830         /* Clean the device first */
831         ret = dpni_reset(dpni, CMD_PRI_LOW, priv->token);
832         if (ret) {
833                 PMD_INIT_LOG(ERR, "Failure cleaning dpni device with"
834                              " error code %d\n", ret);
835                 return;
836         }
837
838         memset(&link, 0, sizeof(link));
839         dpaa2_dev_atomic_write_link_status(dev, &link);
840 }
841
842 static void
843 dpaa2_dev_promiscuous_enable(
844                 struct rte_eth_dev *dev)
845 {
846         int ret;
847         struct dpaa2_dev_priv *priv = dev->data->dev_private;
848         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
849
850         PMD_INIT_FUNC_TRACE();
851
852         if (dpni == NULL) {
853                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
854                 return;
855         }
856
857         ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
858         if (ret < 0)
859                 RTE_LOG(ERR, PMD, "Unable to enable U promisc mode %d\n", ret);
860
861         ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
862         if (ret < 0)
863                 RTE_LOG(ERR, PMD, "Unable to enable M promisc mode %d\n", ret);
864 }
865
866 static void
867 dpaa2_dev_promiscuous_disable(
868                 struct rte_eth_dev *dev)
869 {
870         int ret;
871         struct dpaa2_dev_priv *priv = dev->data->dev_private;
872         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
873
874         PMD_INIT_FUNC_TRACE();
875
876         if (dpni == NULL) {
877                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
878                 return;
879         }
880
881         ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
882         if (ret < 0)
883                 RTE_LOG(ERR, PMD, "Unable to disable U promisc mode %d\n", ret);
884
885         if (dev->data->all_multicast == 0) {
886                 ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW,
887                                                  priv->token, false);
888                 if (ret < 0)
889                         RTE_LOG(ERR, PMD,
890                                 "Unable to disable M promisc mode %d\n",
891                                 ret);
892         }
893 }
894
895 static void
896 dpaa2_dev_allmulticast_enable(
897                 struct rte_eth_dev *dev)
898 {
899         int ret;
900         struct dpaa2_dev_priv *priv = dev->data->dev_private;
901         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
902
903         PMD_INIT_FUNC_TRACE();
904
905         if (dpni == NULL) {
906                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
907                 return;
908         }
909
910         ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
911         if (ret < 0)
912                 RTE_LOG(ERR, PMD, "Unable to enable multicast mode %d\n", ret);
913 }
914
915 static void
916 dpaa2_dev_allmulticast_disable(struct rte_eth_dev *dev)
917 {
918         int ret;
919         struct dpaa2_dev_priv *priv = dev->data->dev_private;
920         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
921
922         PMD_INIT_FUNC_TRACE();
923
924         if (dpni == NULL) {
925                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
926                 return;
927         }
928
929         /* must remain on for all promiscuous */
930         if (dev->data->promiscuous == 1)
931                 return;
932
933         ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
934         if (ret < 0)
935                 RTE_LOG(ERR, PMD, "Unable to disable multicast mode %d\n", ret);
936 }
937
938 static int
939 dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
940 {
941         int ret;
942         struct dpaa2_dev_priv *priv = dev->data->dev_private;
943         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
944         uint32_t frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
945
946         PMD_INIT_FUNC_TRACE();
947
948         if (dpni == NULL) {
949                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
950                 return -EINVAL;
951         }
952
953         /* check that mtu is within the allowed range */
954         if ((mtu < ETHER_MIN_MTU) || (frame_size > DPAA2_MAX_RX_PKT_LEN))
955                 return -EINVAL;
956
957         if (frame_size > ETHER_MAX_LEN)
958                 dev->data->dev_conf.rxmode.jumbo_frame = 1;
959         else
960                 dev->data->dev_conf.rxmode.jumbo_frame = 0;
961
962         /* Set the Max Rx frame length as 'mtu' +
963          * Maximum Ethernet header length
964          */
965         ret = dpni_set_max_frame_length(dpni, CMD_PRI_LOW, priv->token,
966                                         mtu + ETH_VLAN_HLEN);
967         if (ret) {
968                 PMD_DRV_LOG(ERR, "setting the max frame length failed");
969                 return -1;
970         }
971         PMD_DRV_LOG(INFO, "MTU is configured %d for the device", mtu);
972         return 0;
973 }
974
975 static int
976 dpaa2_dev_add_mac_addr(struct rte_eth_dev *dev,
977                        struct ether_addr *addr,
978                        __rte_unused uint32_t index,
979                        __rte_unused uint32_t pool)
980 {
981         int ret;
982         struct dpaa2_dev_priv *priv = dev->data->dev_private;
983         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
984
985         PMD_INIT_FUNC_TRACE();
986
987         if (dpni == NULL) {
988                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
989                 return -1;
990         }
991
992         ret = dpni_add_mac_addr(dpni, CMD_PRI_LOW,
993                                 priv->token, addr->addr_bytes);
994         if (ret)
995                 RTE_LOG(ERR, PMD,
996                         "error: Adding the MAC ADDR failed: err = %d\n", ret);
997         return 0;
998 }
999
1000 static void
1001 dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
1002                           uint32_t index)
1003 {
1004         int ret;
1005         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1006         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1007         struct rte_eth_dev_data *data = dev->data;
1008         struct ether_addr *macaddr;
1009
1010         PMD_INIT_FUNC_TRACE();
1011
1012         macaddr = &data->mac_addrs[index];
1013
1014         if (dpni == NULL) {
1015                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1016                 return;
1017         }
1018
1019         ret = dpni_remove_mac_addr(dpni, CMD_PRI_LOW,
1020                                    priv->token, macaddr->addr_bytes);
1021         if (ret)
1022                 RTE_LOG(ERR, PMD,
1023                         "error: Removing the MAC ADDR failed: err = %d\n", ret);
1024 }
1025
1026 static void
1027 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
1028                        struct ether_addr *addr)
1029 {
1030         int ret;
1031         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1032         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1033
1034         PMD_INIT_FUNC_TRACE();
1035
1036         if (dpni == NULL) {
1037                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1038                 return;
1039         }
1040
1041         ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
1042                                         priv->token, addr->addr_bytes);
1043
1044         if (ret)
1045                 RTE_LOG(ERR, PMD,
1046                         "error: Setting the MAC ADDR failed %d\n", ret);
1047 }
1048 static
1049 int dpaa2_dev_stats_get(struct rte_eth_dev *dev,
1050                          struct rte_eth_stats *stats)
1051 {
1052         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1053         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1054         int32_t  retcode;
1055         uint8_t page0 = 0, page1 = 1, page2 = 2;
1056         union dpni_statistics value;
1057
1058         memset(&value, 0, sizeof(union dpni_statistics));
1059
1060         PMD_INIT_FUNC_TRACE();
1061
1062         if (!dpni) {
1063                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1064                 return -EINVAL;
1065         }
1066
1067         if (!stats) {
1068                 RTE_LOG(ERR, PMD, "stats is NULL\n");
1069                 return -EINVAL;
1070         }
1071
1072         /*Get Counters from page_0*/
1073         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1074                                       page0, 0, &value);
1075         if (retcode)
1076                 goto err;
1077
1078         stats->ipackets = value.page_0.ingress_all_frames;
1079         stats->ibytes = value.page_0.ingress_all_bytes;
1080
1081         /*Get Counters from page_1*/
1082         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1083                                       page1, 0, &value);
1084         if (retcode)
1085                 goto err;
1086
1087         stats->opackets = value.page_1.egress_all_frames;
1088         stats->obytes = value.page_1.egress_all_bytes;
1089
1090         /*Get Counters from page_2*/
1091         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1092                                       page2, 0, &value);
1093         if (retcode)
1094                 goto err;
1095
1096         /* Ingress drop frame count due to configured rules */
1097         stats->ierrors = value.page_2.ingress_filtered_frames;
1098         /* Ingress drop frame count due to error */
1099         stats->ierrors += value.page_2.ingress_discarded_frames;
1100
1101         stats->oerrors = value.page_2.egress_discarded_frames;
1102         stats->imissed = value.page_2.ingress_nobuffer_discards;
1103
1104         return 0;
1105
1106 err:
1107         RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode);
1108         return retcode;
1109 };
1110
1111 static int
1112 dpaa2_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
1113                      unsigned int n)
1114 {
1115         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1116         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1117         int32_t  retcode;
1118         union dpni_statistics value[3] = {};
1119         unsigned int i = 0, num = RTE_DIM(dpaa2_xstats_strings);
1120
1121         if (xstats == NULL)
1122                 return 0;
1123
1124         if (n < num)
1125                 return num;
1126
1127         /* Get Counters from page_0*/
1128         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1129                                       0, 0, &value[0]);
1130         if (retcode)
1131                 goto err;
1132
1133         /* Get Counters from page_1*/
1134         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1135                                       1, 0, &value[1]);
1136         if (retcode)
1137                 goto err;
1138
1139         /* Get Counters from page_2*/
1140         retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1141                                       2, 0, &value[2]);
1142         if (retcode)
1143                 goto err;
1144
1145         for (i = 0; i < num; i++) {
1146                 xstats[i].id = i;
1147                 xstats[i].value = value[dpaa2_xstats_strings[i].page_id].
1148                         raw.counter[dpaa2_xstats_strings[i].stats_id];
1149         }
1150         return i;
1151 err:
1152         RTE_LOG(ERR, PMD, "Error in obtaining extended stats (%d)\n", retcode);
1153         return retcode;
1154 }
1155
1156 static int
1157 dpaa2_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
1158                        struct rte_eth_xstat_name *xstats_names,
1159                        __rte_unused unsigned int limit)
1160 {
1161         unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
1162
1163         if (xstats_names != NULL)
1164                 for (i = 0; i < stat_cnt; i++)
1165                         snprintf(xstats_names[i].name,
1166                                  sizeof(xstats_names[i].name),
1167                                  "%s",
1168                                  dpaa2_xstats_strings[i].name);
1169
1170         return stat_cnt;
1171 }
1172
1173 static int
1174 dpaa2_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
1175                        uint64_t *values, unsigned int n)
1176 {
1177         unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
1178         uint64_t values_copy[stat_cnt];
1179
1180         if (!ids) {
1181                 struct dpaa2_dev_priv *priv = dev->data->dev_private;
1182                 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1183                 int32_t  retcode;
1184                 union dpni_statistics value[3] = {};
1185
1186                 if (n < stat_cnt)
1187                         return stat_cnt;
1188
1189                 if (!values)
1190                         return 0;
1191
1192                 /* Get Counters from page_0*/
1193                 retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1194                                               0, 0, &value[0]);
1195                 if (retcode)
1196                         return 0;
1197
1198                 /* Get Counters from page_1*/
1199                 retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1200                                               1, 0, &value[1]);
1201                 if (retcode)
1202                         return 0;
1203
1204                 /* Get Counters from page_2*/
1205                 retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
1206                                               2, 0, &value[2]);
1207                 if (retcode)
1208                         return 0;
1209
1210                 for (i = 0; i < stat_cnt; i++) {
1211                         values[i] = value[dpaa2_xstats_strings[i].page_id].
1212                                 raw.counter[dpaa2_xstats_strings[i].stats_id];
1213                 }
1214                 return stat_cnt;
1215         }
1216
1217         dpaa2_xstats_get_by_id(dev, NULL, values_copy, stat_cnt);
1218
1219         for (i = 0; i < n; i++) {
1220                 if (ids[i] >= stat_cnt) {
1221                         PMD_INIT_LOG(ERR, "id value isn't valid");
1222                         return -1;
1223                 }
1224                 values[i] = values_copy[ids[i]];
1225         }
1226         return n;
1227 }
1228
1229 static int
1230 dpaa2_xstats_get_names_by_id(
1231         struct rte_eth_dev *dev,
1232         struct rte_eth_xstat_name *xstats_names,
1233         const uint64_t *ids,
1234         unsigned int limit)
1235 {
1236         unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
1237         struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
1238
1239         if (!ids)
1240                 return dpaa2_xstats_get_names(dev, xstats_names, limit);
1241
1242         dpaa2_xstats_get_names(dev, xstats_names_copy, limit);
1243
1244         for (i = 0; i < limit; i++) {
1245                 if (ids[i] >= stat_cnt) {
1246                         PMD_INIT_LOG(ERR, "id value isn't valid");
1247                         return -1;
1248                 }
1249                 strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
1250         }
1251         return limit;
1252 }
1253
1254 static void
1255 dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
1256 {
1257         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1258         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1259         int32_t  retcode;
1260
1261         PMD_INIT_FUNC_TRACE();
1262
1263         if (dpni == NULL) {
1264                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1265                 return;
1266         }
1267
1268         retcode =  dpni_reset_statistics(dpni, CMD_PRI_LOW, priv->token);
1269         if (retcode)
1270                 goto error;
1271
1272         return;
1273
1274 error:
1275         RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode);
1276         return;
1277 };
1278
1279 /* return 0 means link status changed, -1 means not changed */
1280 static int
1281 dpaa2_dev_link_update(struct rte_eth_dev *dev,
1282                         int wait_to_complete __rte_unused)
1283 {
1284         int ret;
1285         struct dpaa2_dev_priv *priv = dev->data->dev_private;
1286         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1287         struct rte_eth_link link, old;
1288         struct dpni_link_state state = {0};
1289
1290         if (dpni == NULL) {
1291                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1292                 return 0;
1293         }
1294         memset(&old, 0, sizeof(old));
1295         dpaa2_dev_atomic_read_link_status(dev, &old);
1296
1297         ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
1298         if (ret < 0) {
1299                 RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret);
1300                 return -1;
1301         }
1302
1303         if ((old.link_status == state.up) && (old.link_speed == state.rate)) {
1304                 RTE_LOG(DEBUG, PMD, "No change in status\n");
1305                 return -1;
1306         }
1307
1308         memset(&link, 0, sizeof(struct rte_eth_link));
1309         link.link_status = state.up;
1310         link.link_speed = state.rate;
1311
1312         if (state.options & DPNI_LINK_OPT_HALF_DUPLEX)
1313                 link.link_duplex = ETH_LINK_HALF_DUPLEX;
1314         else
1315                 link.link_duplex = ETH_LINK_FULL_DUPLEX;
1316
1317         dpaa2_dev_atomic_write_link_status(dev, &link);
1318
1319         if (link.link_status)
1320                 PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id);
1321         else
1322                 PMD_DRV_LOG(INFO, "Port %d Link is Down", dev->data->port_id);
1323         return 0;
1324 }
1325
1326 /**
1327  * Toggle the DPNI to enable, if not already enabled.
1328  * This is not strictly PHY up/down - it is more of logical toggling.
1329  */
1330 static int
1331 dpaa2_dev_set_link_up(struct rte_eth_dev *dev)
1332 {
1333         int ret = -EINVAL;
1334         struct dpaa2_dev_priv *priv;
1335         struct fsl_mc_io *dpni;
1336         int en = 0;
1337         struct dpni_link_state state = {0};
1338
1339         priv = dev->data->dev_private;
1340         dpni = (struct fsl_mc_io *)priv->hw;
1341
1342         if (dpni == NULL) {
1343                 RTE_LOG(ERR, PMD, "DPNI is NULL\n");
1344                 return ret;
1345         }
1346
1347         /* Check if DPNI is currently enabled */
1348         ret = dpni_is_enabled(dpni, CMD_PRI_LOW, priv->token, &en);
1349         if (ret) {
1350                 /* Unable to obtain dpni status; Not continuing */
1351                 PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret);
1352                 return -EINVAL;
1353         }
1354
1355         /* Enable link if not already enabled */
1356         if (!en) {
1357                 ret = dpni_enable(dpni, CMD_PRI_LOW, priv->token);
1358                 if (ret) {
1359                         PMD_DRV_LOG(ERR, "Interface Link UP failed (%d)", ret);
1360                         return -EINVAL;
1361                 }
1362         }
1363         ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
1364         if (ret < 0) {
1365                 RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret);
1366                 return -1;
1367         }
1368
1369         /* changing tx burst function to start enqueues */
1370         dev->tx_pkt_burst = dpaa2_dev_tx;
1371         dev->data->dev_link.link_status = state.up;
1372
1373         if (state.up)
1374                 PMD_DRV_LOG(INFO, "Port %d Link is set as UP",
1375                             dev->data->port_id);
1376         else
1377                 PMD_DRV_LOG(INFO, "Port %d Link is DOWN", dev->data->port_id);
1378         return ret;
1379 }
1380
1381 /**
1382  * Toggle the DPNI to disable, if not already disabled.
1383  * This is not strictly PHY up/down - it is more of logical toggling.
1384  */
1385 static int
1386 dpaa2_dev_set_link_down(struct rte_eth_dev *dev)
1387 {
1388         int ret = -EINVAL;
1389         struct dpaa2_dev_priv *priv;
1390         struct fsl_mc_io *dpni;
1391         int dpni_enabled = 0;
1392         int retries = 10;
1393
1394         PMD_INIT_FUNC_TRACE();
1395
1396         priv = dev->data->dev_private;
1397         dpni = (struct fsl_mc_io *)priv->hw;
1398
1399         if (dpni == NULL) {
1400                 RTE_LOG(ERR, PMD, "Device has not yet been configured\n");
1401                 return ret;
1402         }
1403
1404         /*changing  tx burst function to avoid any more enqueues */
1405         dev->tx_pkt_burst = dummy_dev_tx;
1406
1407         /* Loop while dpni_disable() attempts to drain the egress FQs
1408          * and confirm them back to us.
1409          */
1410         do {
1411                 ret = dpni_disable(dpni, 0, priv->token);
1412                 if (ret) {
1413                         PMD_DRV_LOG(ERR, "dpni disable failed (%d)", ret);
1414                         return ret;
1415                 }
1416                 ret = dpni_is_enabled(dpni, 0, priv->token, &dpni_enabled);
1417                 if (ret) {
1418                         PMD_DRV_LOG(ERR, "dpni_is_enabled failed (%d)", ret);
1419                         return ret;
1420                 }
1421                 if (dpni_enabled)
1422                         /* Allow the MC some slack */
1423                         rte_delay_us(100 * 1000);
1424         } while (dpni_enabled && --retries);
1425
1426         if (!retries) {
1427                 PMD_DRV_LOG(WARNING, "Retry count exceeded disabling DPNI\n");
1428                 /* todo- we may have to manually cleanup queues.
1429                  */
1430         } else {
1431                 PMD_DRV_LOG(INFO, "Port %d Link DOWN successful",
1432                             dev->data->port_id);
1433         }
1434
1435         dev->data->dev_link.link_status = 0;
1436
1437         return ret;
1438 }
1439
1440 static int
1441 dpaa2_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1442 {
1443         int ret = -EINVAL;
1444         struct dpaa2_dev_priv *priv;
1445         struct fsl_mc_io *dpni;
1446         struct dpni_link_state state = {0};
1447
1448         PMD_INIT_FUNC_TRACE();
1449
1450         priv = dev->data->dev_private;
1451         dpni = (struct fsl_mc_io *)priv->hw;
1452
1453         if (dpni == NULL || fc_conf == NULL) {
1454                 RTE_LOG(ERR, PMD, "device not configured\n");
1455                 return ret;
1456         }
1457
1458         ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
1459         if (ret) {
1460                 RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret);
1461                 return ret;
1462         }
1463
1464         memset(fc_conf, 0, sizeof(struct rte_eth_fc_conf));
1465         if (state.options & DPNI_LINK_OPT_PAUSE) {
1466                 /* DPNI_LINK_OPT_PAUSE set
1467                  *  if ASYM_PAUSE not set,
1468                  *      RX Side flow control (handle received Pause frame)
1469                  *      TX side flow control (send Pause frame)
1470                  *  if ASYM_PAUSE set,
1471                  *      RX Side flow control (handle received Pause frame)
1472                  *      No TX side flow control (send Pause frame disabled)
1473                  */
1474                 if (!(state.options & DPNI_LINK_OPT_ASYM_PAUSE))
1475                         fc_conf->mode = RTE_FC_FULL;
1476                 else
1477                         fc_conf->mode = RTE_FC_RX_PAUSE;
1478         } else {
1479                 /* DPNI_LINK_OPT_PAUSE not set
1480                  *  if ASYM_PAUSE set,
1481                  *      TX side flow control (send Pause frame)
1482                  *      No RX side flow control (No action on pause frame rx)
1483                  *  if ASYM_PAUSE not set,
1484                  *      Flow control disabled
1485                  */
1486                 if (state.options & DPNI_LINK_OPT_ASYM_PAUSE)
1487                         fc_conf->mode = RTE_FC_TX_PAUSE;
1488                 else
1489                         fc_conf->mode = RTE_FC_NONE;
1490         }
1491
1492         return ret;
1493 }
1494
1495 static int
1496 dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1497 {
1498         int ret = -EINVAL;
1499         struct dpaa2_dev_priv *priv;
1500         struct fsl_mc_io *dpni;
1501         struct dpni_link_state state = {0};
1502         struct dpni_link_cfg cfg = {0};
1503
1504         PMD_INIT_FUNC_TRACE();
1505
1506         priv = dev->data->dev_private;
1507         dpni = (struct fsl_mc_io *)priv->hw;
1508
1509         if (dpni == NULL) {
1510                 RTE_LOG(ERR, PMD, "dpni is NULL\n");
1511                 return ret;
1512         }
1513
1514         /* It is necessary to obtain the current state before setting fc_conf
1515          * as MC would return error in case rate, autoneg or duplex values are
1516          * different.
1517          */
1518         ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
1519         if (ret) {
1520                 RTE_LOG(ERR, PMD, "Unable to get link state (err=%d)\n", ret);
1521                 return -1;
1522         }
1523
1524         /* Disable link before setting configuration */
1525         dpaa2_dev_set_link_down(dev);
1526
1527         /* Based on fc_conf, update cfg */
1528         cfg.rate = state.rate;
1529         cfg.options = state.options;
1530
1531         /* update cfg with fc_conf */
1532         switch (fc_conf->mode) {
1533         case RTE_FC_FULL:
1534                 /* Full flow control;
1535                  * OPT_PAUSE set, ASYM_PAUSE not set
1536                  */
1537                 cfg.options |= DPNI_LINK_OPT_PAUSE;
1538                 cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
1539                 break;
1540         case RTE_FC_TX_PAUSE:
1541                 /* Enable RX flow control
1542                  * OPT_PAUSE not set;
1543                  * ASYM_PAUSE set;
1544                  */
1545                 cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE;
1546                 cfg.options &= ~DPNI_LINK_OPT_PAUSE;
1547                 break;
1548         case RTE_FC_RX_PAUSE:
1549                 /* Enable TX Flow control
1550                  * OPT_PAUSE set
1551                  * ASYM_PAUSE set
1552                  */
1553                 cfg.options |= DPNI_LINK_OPT_PAUSE;
1554                 cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE;
1555                 break;
1556         case RTE_FC_NONE:
1557                 /* Disable Flow control
1558                  * OPT_PAUSE not set
1559                  * ASYM_PAUSE not set
1560                  */
1561                 cfg.options &= ~DPNI_LINK_OPT_PAUSE;
1562                 cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
1563                 break;
1564         default:
1565                 RTE_LOG(ERR, PMD, "Incorrect Flow control flag (%d)\n",
1566                         fc_conf->mode);
1567                 return -1;
1568         }
1569
1570         ret = dpni_set_link_cfg(dpni, CMD_PRI_LOW, priv->token, &cfg);
1571         if (ret)
1572                 RTE_LOG(ERR, PMD,
1573                         "Unable to set Link configuration (err=%d)\n",
1574                         ret);
1575
1576         /* Enable link */
1577         dpaa2_dev_set_link_up(dev);
1578
1579         return ret;
1580 }
1581
1582 static int
1583 dpaa2_dev_rss_hash_update(struct rte_eth_dev *dev,
1584                           struct rte_eth_rss_conf *rss_conf)
1585 {
1586         struct rte_eth_dev_data *data = dev->data;
1587         struct rte_eth_conf *eth_conf = &data->dev_conf;
1588         int ret;
1589
1590         PMD_INIT_FUNC_TRACE();
1591
1592         if (rss_conf->rss_hf) {
1593                 ret = dpaa2_setup_flow_dist(dev, rss_conf->rss_hf);
1594                 if (ret) {
1595                         PMD_INIT_LOG(ERR, "unable to set flow dist");
1596                         return ret;
1597                 }
1598         } else {
1599                 ret = dpaa2_remove_flow_dist(dev, 0);
1600                 if (ret) {
1601                         PMD_INIT_LOG(ERR, "unable to remove flow dist");
1602                         return ret;
1603                 }
1604         }
1605         eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_conf->rss_hf;
1606         return 0;
1607 }
1608
1609 static int
1610 dpaa2_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
1611                             struct rte_eth_rss_conf *rss_conf)
1612 {
1613         struct rte_eth_dev_data *data = dev->data;
1614         struct rte_eth_conf *eth_conf = &data->dev_conf;
1615
1616         /* dpaa2 does not support rss_key, so length should be 0*/
1617         rss_conf->rss_key_len = 0;
1618         rss_conf->rss_hf = eth_conf->rx_adv_conf.rss_conf.rss_hf;
1619         return 0;
1620 }
1621
1622 int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev,
1623                 int eth_rx_queue_id,
1624                 uint16_t dpcon_id,
1625                 const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
1626 {
1627         struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
1628         struct fsl_mc_io *dpni = (struct fsl_mc_io *)eth_priv->hw;
1629         struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
1630         uint8_t flow_id = dpaa2_ethq->flow_id;
1631         struct dpni_queue cfg;
1632         uint8_t options;
1633         int ret;
1634
1635         if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL)
1636                 dpaa2_ethq->cb = dpaa2_dev_process_parallel_event;
1637         else
1638                 return -EINVAL;
1639
1640         memset(&cfg, 0, sizeof(struct dpni_queue));
1641         options = DPNI_QUEUE_OPT_DEST;
1642         cfg.destination.type = DPNI_DEST_DPCON;
1643         cfg.destination.id = dpcon_id;
1644         cfg.destination.priority = queue_conf->ev.priority;
1645
1646         options |= DPNI_QUEUE_OPT_USER_CTX;
1647         cfg.user_context = (uint64_t)(dpaa2_ethq);
1648
1649         ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
1650                              dpaa2_ethq->tc_index, flow_id, options, &cfg);
1651         if (ret) {
1652                 RTE_LOG(ERR, PMD, "Error in dpni_set_queue: ret: %d\n", ret);
1653                 return ret;
1654         }
1655
1656         memcpy(&dpaa2_ethq->ev, &queue_conf->ev, sizeof(struct rte_event));
1657
1658         return 0;
1659 }
1660
1661 int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev,
1662                 int eth_rx_queue_id)
1663 {
1664         struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
1665         struct fsl_mc_io *dpni = (struct fsl_mc_io *)eth_priv->hw;
1666         struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
1667         uint8_t flow_id = dpaa2_ethq->flow_id;
1668         struct dpni_queue cfg;
1669         uint8_t options;
1670         int ret;
1671
1672         memset(&cfg, 0, sizeof(struct dpni_queue));
1673         options = DPNI_QUEUE_OPT_DEST;
1674         cfg.destination.type = DPNI_DEST_NONE;
1675
1676         ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
1677                              dpaa2_ethq->tc_index, flow_id, options, &cfg);
1678         if (ret)
1679                 RTE_LOG(ERR, PMD, "Error in dpni_set_queue: ret: %d\n", ret);
1680
1681         return ret;
1682 }
1683
1684 static struct eth_dev_ops dpaa2_ethdev_ops = {
1685         .dev_configure    = dpaa2_eth_dev_configure,
1686         .dev_start            = dpaa2_dev_start,
1687         .dev_stop             = dpaa2_dev_stop,
1688         .dev_close            = dpaa2_dev_close,
1689         .promiscuous_enable   = dpaa2_dev_promiscuous_enable,
1690         .promiscuous_disable  = dpaa2_dev_promiscuous_disable,
1691         .allmulticast_enable  = dpaa2_dev_allmulticast_enable,
1692         .allmulticast_disable = dpaa2_dev_allmulticast_disable,
1693         .dev_set_link_up      = dpaa2_dev_set_link_up,
1694         .dev_set_link_down    = dpaa2_dev_set_link_down,
1695         .link_update       = dpaa2_dev_link_update,
1696         .stats_get             = dpaa2_dev_stats_get,
1697         .xstats_get            = dpaa2_dev_xstats_get,
1698         .xstats_get_by_id     = dpaa2_xstats_get_by_id,
1699         .xstats_get_names_by_id = dpaa2_xstats_get_names_by_id,
1700         .xstats_get_names      = dpaa2_xstats_get_names,
1701         .stats_reset       = dpaa2_dev_stats_reset,
1702         .xstats_reset         = dpaa2_dev_stats_reset,
1703         .fw_version_get    = dpaa2_fw_version_get,
1704         .dev_infos_get     = dpaa2_dev_info_get,
1705         .dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
1706         .mtu_set           = dpaa2_dev_mtu_set,
1707         .vlan_filter_set      = dpaa2_vlan_filter_set,
1708         .vlan_offload_set     = dpaa2_vlan_offload_set,
1709         .rx_queue_setup    = dpaa2_dev_rx_queue_setup,
1710         .rx_queue_release  = dpaa2_dev_rx_queue_release,
1711         .tx_queue_setup    = dpaa2_dev_tx_queue_setup,
1712         .tx_queue_release  = dpaa2_dev_tx_queue_release,
1713         .flow_ctrl_get        = dpaa2_flow_ctrl_get,
1714         .flow_ctrl_set        = dpaa2_flow_ctrl_set,
1715         .mac_addr_add         = dpaa2_dev_add_mac_addr,
1716         .mac_addr_remove      = dpaa2_dev_remove_mac_addr,
1717         .mac_addr_set         = dpaa2_dev_set_mac_addr,
1718         .rss_hash_update      = dpaa2_dev_rss_hash_update,
1719         .rss_hash_conf_get    = dpaa2_dev_rss_hash_conf_get,
1720 };
1721
1722 static int
1723 dpaa2_dev_init(struct rte_eth_dev *eth_dev)
1724 {
1725         struct rte_device *dev = eth_dev->device;
1726         struct rte_dpaa2_device *dpaa2_dev;
1727         struct fsl_mc_io *dpni_dev;
1728         struct dpni_attr attr;
1729         struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
1730         struct dpni_buffer_layout layout;
1731         int ret, hw_id;
1732
1733         PMD_INIT_FUNC_TRACE();
1734
1735         /* For secondary processes, the primary has done all the work */
1736         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1737                 return 0;
1738
1739         dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
1740
1741         hw_id = dpaa2_dev->object_id;
1742
1743         dpni_dev = rte_malloc(NULL, sizeof(struct fsl_mc_io), 0);
1744         if (!dpni_dev) {
1745                 PMD_INIT_LOG(ERR, "malloc failed for dpni device\n");
1746                 return -1;
1747         }
1748
1749         dpni_dev->regs = rte_mcp_ptr_list[0];
1750         ret = dpni_open(dpni_dev, CMD_PRI_LOW, hw_id, &priv->token);
1751         if (ret) {
1752                 PMD_INIT_LOG(ERR,
1753                              "Failure in opening dpni@%d with err code %d\n",
1754                              hw_id, ret);
1755                 rte_free(dpni_dev);
1756                 return -1;
1757         }
1758
1759         /* Clean the device first */
1760         ret = dpni_reset(dpni_dev, CMD_PRI_LOW, priv->token);
1761         if (ret) {
1762                 PMD_INIT_LOG(ERR,
1763                              "Failure cleaning dpni@%d with err code %d\n",
1764                              hw_id, ret);
1765                 goto init_err;
1766         }
1767
1768         ret = dpni_get_attributes(dpni_dev, CMD_PRI_LOW, priv->token, &attr);
1769         if (ret) {
1770                 PMD_INIT_LOG(ERR,
1771                              "Failure in get dpni@%d attribute, err code %d\n",
1772                              hw_id, ret);
1773                 goto init_err;
1774         }
1775
1776         priv->num_rx_tc = attr.num_rx_tcs;
1777
1778         /* Resetting the "num_rx_queues" to equal number of queues in first TC
1779          * as only one TC is supported on Rx Side. Once Multiple TCs will be
1780          * in use for Rx processing then this will be changed or removed.
1781          */
1782         priv->nb_rx_queues = attr.num_queues;
1783
1784         /* Using number of TX queues as number of TX TCs */
1785         priv->nb_tx_queues = attr.num_tx_tcs;
1786
1787         PMD_DRV_LOG(DEBUG, "RX-TC= %d, nb_rx_queues= %d, nb_tx_queues=%d",
1788                     priv->num_rx_tc, priv->nb_rx_queues, priv->nb_tx_queues);
1789
1790         priv->hw = dpni_dev;
1791         priv->hw_id = hw_id;
1792         priv->options = attr.options;
1793         priv->max_mac_filters = attr.mac_filter_entries;
1794         priv->max_vlan_filters = attr.vlan_filter_entries;
1795         priv->flags = 0;
1796
1797         /* Allocate memory for hardware structure for queues */
1798         ret = dpaa2_alloc_rx_tx_queues(eth_dev);
1799         if (ret) {
1800                 PMD_INIT_LOG(ERR, "dpaa2_alloc_rx_tx_queuesFailed\n");
1801                 goto init_err;
1802         }
1803
1804         /* Allocate memory for storing MAC addresses */
1805         eth_dev->data->mac_addrs = rte_zmalloc("dpni",
1806                 ETHER_ADDR_LEN * attr.mac_filter_entries, 0);
1807         if (eth_dev->data->mac_addrs == NULL) {
1808                 PMD_INIT_LOG(ERR,
1809                    "Failed to allocate %d bytes needed to store MAC addresses",
1810                              ETHER_ADDR_LEN * attr.mac_filter_entries);
1811                 ret = -ENOMEM;
1812                 goto init_err;
1813         }
1814
1815         ret = dpni_get_primary_mac_addr(dpni_dev, CMD_PRI_LOW,
1816                                         priv->token,
1817                         (uint8_t *)(eth_dev->data->mac_addrs[0].addr_bytes));
1818         if (ret) {
1819                 PMD_INIT_LOG(ERR, "DPNI get mac address failed:Err Code = %d\n",
1820                              ret);
1821                 goto init_err;
1822         }
1823
1824         /* ... tx buffer layout ... */
1825         memset(&layout, 0, sizeof(struct dpni_buffer_layout));
1826         layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
1827         layout.pass_frame_status = 1;
1828         ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
1829                                      DPNI_QUEUE_TX, &layout);
1830         if (ret) {
1831                 PMD_INIT_LOG(ERR, "Error (%d) in setting tx buffer layout",
1832                              ret);
1833                 goto init_err;
1834         }
1835
1836         /* ... tx-conf and error buffer layout ... */
1837         memset(&layout, 0, sizeof(struct dpni_buffer_layout));
1838         layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
1839         layout.pass_frame_status = 1;
1840         ret = dpni_set_buffer_layout(dpni_dev, CMD_PRI_LOW, priv->token,
1841                                      DPNI_QUEUE_TX_CONFIRM, &layout);
1842         if (ret) {
1843                 PMD_INIT_LOG(ERR, "Error (%d) in setting tx-conf buffer layout",
1844                              ret);
1845                 goto init_err;
1846         }
1847
1848         eth_dev->dev_ops = &dpaa2_ethdev_ops;
1849         eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
1850
1851         eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx;
1852         eth_dev->tx_pkt_burst = dpaa2_dev_tx;
1853         rte_fslmc_vfio_dmamap();
1854
1855         RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name);
1856         return 0;
1857 init_err:
1858         dpaa2_dev_uninit(eth_dev);
1859         return ret;
1860 }
1861
1862 static int
1863 dpaa2_dev_uninit(struct rte_eth_dev *eth_dev)
1864 {
1865         struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
1866         struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
1867         int i, ret;
1868         struct dpaa2_queue *dpaa2_q;
1869
1870         PMD_INIT_FUNC_TRACE();
1871
1872         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1873                 return 0;
1874
1875         if (!dpni) {
1876                 PMD_INIT_LOG(WARNING, "Already closed or not started");
1877                 return -1;
1878         }
1879
1880         dpaa2_dev_close(eth_dev);
1881
1882         if (priv->rx_vq[0]) {
1883                 /* cleaning up queue storage */
1884                 for (i = 0; i < priv->nb_rx_queues; i++) {
1885                         dpaa2_q = (struct dpaa2_queue *)priv->rx_vq[i];
1886                         if (dpaa2_q->q_storage)
1887                                 rte_free(dpaa2_q->q_storage);
1888                 }
1889                 /*free the all queue memory */
1890                 rte_free(priv->rx_vq[0]);
1891                 priv->rx_vq[0] = NULL;
1892         }
1893
1894         /* free memory for storing MAC addresses */
1895         if (eth_dev->data->mac_addrs) {
1896                 rte_free(eth_dev->data->mac_addrs);
1897                 eth_dev->data->mac_addrs = NULL;
1898         }
1899
1900         /* Close the device at underlying layer*/
1901         ret = dpni_close(dpni, CMD_PRI_LOW, priv->token);
1902         if (ret) {
1903                 PMD_INIT_LOG(ERR,
1904                              "Failure closing dpni device with err code %d\n",
1905                              ret);
1906         }
1907
1908         /* Free the allocated memory for ethernet private data and dpni*/
1909         priv->hw = NULL;
1910         rte_free(dpni);
1911
1912         eth_dev->dev_ops = NULL;
1913         eth_dev->rx_pkt_burst = NULL;
1914         eth_dev->tx_pkt_burst = NULL;
1915
1916         RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name);
1917         return 0;
1918 }
1919
1920 static int
1921 rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv,
1922                 struct rte_dpaa2_device *dpaa2_dev)
1923 {
1924         struct rte_eth_dev *eth_dev;
1925         int diag;
1926
1927         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1928                 eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name);
1929                 if (!eth_dev)
1930                         return -ENODEV;
1931                 eth_dev->data->dev_private = rte_zmalloc(
1932                                                 "ethdev private structure",
1933                                                 sizeof(struct dpaa2_dev_priv),
1934                                                 RTE_CACHE_LINE_SIZE);
1935                 if (eth_dev->data->dev_private == NULL) {
1936                         PMD_INIT_LOG(CRIT, "Cannot allocate memzone for"
1937                                      " private port data\n");
1938                         rte_eth_dev_release_port(eth_dev);
1939                         return -ENOMEM;
1940                 }
1941         } else {
1942                 eth_dev = rte_eth_dev_attach_secondary(dpaa2_dev->device.name);
1943                 if (!eth_dev)
1944                         return -ENODEV;
1945         }
1946
1947         eth_dev->device = &dpaa2_dev->device;
1948         eth_dev->device->driver = &dpaa2_drv->driver;
1949
1950         dpaa2_dev->eth_dev = eth_dev;
1951         eth_dev->data->rx_mbuf_alloc_failed = 0;
1952
1953         /* Invoke PMD device initialization function */
1954         diag = dpaa2_dev_init(eth_dev);
1955         if (diag == 0)
1956                 return 0;
1957
1958         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
1959                 rte_free(eth_dev->data->dev_private);
1960         rte_eth_dev_release_port(eth_dev);
1961         return diag;
1962 }
1963
1964 static int
1965 rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev)
1966 {
1967         struct rte_eth_dev *eth_dev;
1968
1969         eth_dev = dpaa2_dev->eth_dev;
1970         dpaa2_dev_uninit(eth_dev);
1971
1972         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
1973                 rte_free(eth_dev->data->dev_private);
1974         rte_eth_dev_release_port(eth_dev);
1975
1976         return 0;
1977 }
1978
1979 static struct rte_dpaa2_driver rte_dpaa2_pmd = {
1980         .drv_type = DPAA2_ETH,
1981         .probe = rte_dpaa2_probe,
1982         .remove = rte_dpaa2_remove,
1983 };
1984
1985 RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd);