LCOV - code coverage report
Current view: top level - drivers/net/enetc - enetc4_ethdev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 440 0.5 %
Date: 2025-11-01 17:50:34 Functions: 2 33 6.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 127 0.8 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2024 NXP
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdbool.h>
       6                 :            : #include <rte_random.h>
       7                 :            : #include <dpaax_iova_table.h>
       8                 :            : 
       9                 :            : #include "base/enetc4_hw.h"
      10                 :            : #include "enetc_logs.h"
      11                 :            : #include "enetc.h"
      12                 :            : 
      13                 :            : /* Supported Rx offloads */
      14                 :            : static uint64_t dev_rx_offloads_sup =
      15                 :            :         RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
      16                 :            :         RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
      17                 :            :         RTE_ETH_RX_OFFLOAD_TCP_CKSUM;
      18                 :            : 
      19                 :            : /* Supported Tx offloads */
      20                 :            : static uint64_t dev_tx_offloads_sup =
      21                 :            :         RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
      22                 :            :         RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
      23                 :            :         RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
      24                 :            : 
      25                 :            : static int
      26                 :          0 : enetc4_dev_start(struct rte_eth_dev *dev)
      27                 :            : {
      28                 :            :         struct enetc_eth_hw *hw =
      29                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
      30                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
      31                 :            :         struct enetc_bdr *txq, *rxq;
      32                 :            :         uint32_t val;
      33                 :            :         int i, ret;
      34                 :            : 
      35                 :          0 :         PMD_INIT_FUNC_TRACE();
      36                 :            : 
      37                 :            :         /* Start TX queues that are not deferred */
      38         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
      39                 :          0 :                 txq = dev->data->tx_queues[i];
      40   [ #  #  #  # ]:          0 :                 if (txq && !txq->tx_deferred_start) {
      41                 :          0 :                         ret = enetc4_tx_queue_start(dev, i);
      42         [ #  # ]:          0 :                         if (ret < 0)
      43                 :          0 :                                 return ret;
      44                 :            :                 }
      45                 :            :         }
      46                 :            : 
      47                 :            :         /* Start RX queues that are not deferred */
      48         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
      49                 :          0 :                 rxq = dev->data->rx_queues[i];
      50   [ #  #  #  # ]:          0 :                 if (rxq && !rxq->rx_deferred_start) {
      51                 :          0 :                         ret = enetc4_rx_queue_start(dev, i);
      52         [ #  # ]:          0 :                         if (ret < 0)
      53                 :          0 :                                 return ret;
      54                 :            :                 }
      55                 :            :         }
      56                 :            : 
      57                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PM_CMD_CFG(0));
      58                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM_CMD_CFG(0),
      59                 :            :                        val | PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN);
      60                 :            : 
      61                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PM_CMD_CFG(1));
      62                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM_CMD_CFG(1),
      63                 :            :                        val | PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN);
      64                 :            : 
      65                 :            :         /* Enable port */
      66                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PMR);
      67                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PMR, val | ENETC4_PMR_EN);
      68                 :            : 
      69                 :            :         /* Enable port transmit/receive */
      70                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_POR, 0);
      71                 :            : 
      72                 :          0 :         return 0;
      73                 :            : }
      74                 :            : 
      75                 :            : static int
      76                 :          0 : enetc4_dev_stop(struct rte_eth_dev *dev)
      77                 :            : {
      78                 :            :         struct enetc_eth_hw *hw =
      79                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
      80                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
      81                 :            :         uint32_t val;
      82                 :            : 
      83                 :          0 :         PMD_INIT_FUNC_TRACE();
      84                 :            : 
      85                 :            :         /* Disable port */
      86                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PMR);
      87                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PMR, val & (~ENETC4_PMR_EN));
      88                 :            : 
      89                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PM_CMD_CFG(0));
      90                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM_CMD_CFG(0),
      91                 :            :                       val & (~(PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN)));
      92                 :            : 
      93                 :          0 :         val = enetc4_port_rd(enetc_hw, ENETC4_PM_CMD_CFG(1));
      94                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM_CMD_CFG(1),
      95                 :            :                       val & (~(PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN)));
      96                 :            : 
      97                 :          0 :         return 0;
      98                 :            : }
      99                 :            : 
     100                 :            : /* return 0 means link status changed, -1 means not changed */
     101                 :            : static int
     102                 :          0 : enetc4_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
     103                 :            : {
     104                 :            :         struct enetc_eth_hw *hw =
     105                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     106                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     107                 :            :         struct rte_eth_link link;
     108                 :            :         uint32_t status;
     109                 :            : 
     110                 :          0 :         PMD_INIT_FUNC_TRACE();
     111                 :            : 
     112                 :            :         memset(&link, 0, sizeof(link));
     113                 :            : 
     114                 :          0 :         status = enetc4_port_rd(enetc_hw, ENETC4_PM_IF_STATUS(0));
     115                 :            : 
     116         [ #  # ]:          0 :         if (status & ENETC4_LINK_MODE)
     117                 :          0 :                 link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     118                 :            :         else
     119                 :          0 :                 link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
     120                 :            : 
     121         [ #  # ]:          0 :         if (status & ENETC4_LINK_STATUS)
     122                 :          0 :                 link.link_status = RTE_ETH_LINK_UP;
     123                 :            :         else
     124                 :          0 :                 link.link_status = RTE_ETH_LINK_DOWN;
     125                 :            : 
     126      [ #  #  # ]:          0 :         switch (status & ENETC4_LINK_SPEED_MASK) {
     127                 :          0 :         case ENETC4_LINK_SPEED_1G:
     128                 :          0 :                 link.link_speed = RTE_ETH_SPEED_NUM_1G;
     129                 :          0 :                 break;
     130                 :            : 
     131                 :          0 :         case ENETC4_LINK_SPEED_100M:
     132                 :          0 :                 link.link_speed = RTE_ETH_SPEED_NUM_100M;
     133                 :          0 :                 break;
     134                 :            : 
     135                 :          0 :         default:
     136                 :            :         case ENETC4_LINK_SPEED_10M:
     137                 :          0 :                 link.link_speed = RTE_ETH_SPEED_NUM_10M;
     138                 :            :         }
     139                 :            : 
     140                 :          0 :         return rte_eth_linkstatus_set(dev, &link);
     141                 :            : }
     142                 :            : 
     143                 :            : static int
     144                 :          0 : enetc4_mac_init(struct enetc_eth_hw *hw, struct rte_eth_dev *eth_dev)
     145                 :            : {
     146                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     147                 :            :         uint32_t high_mac = 0;
     148                 :            :         uint16_t low_mac = 0;
     149                 :            :         char eth_name[ENETC_ETH_NAMESIZE];
     150                 :            : 
     151                 :          0 :         PMD_INIT_FUNC_TRACE();
     152                 :            : 
     153                 :            :         /* Enabling Station Interface */
     154                 :          0 :         enetc4_wr(enetc_hw, ENETC_SIMR, ENETC_SIMR_EN);
     155                 :            : 
     156                 :          0 :         high_mac = (uint32_t)enetc4_port_rd(enetc_hw, ENETC4_PSIPMAR0(0));
     157                 :          0 :         low_mac = (uint16_t)enetc4_port_rd(enetc_hw, ENETC4_PSIPMAR1(0));
     158                 :            : 
     159         [ #  # ]:          0 :         if ((high_mac | low_mac) == 0) {
     160                 :          0 :                 ENETC_PMD_NOTICE("MAC is not available for this SI, "
     161                 :            :                                 "set random MAC");
     162                 :          0 :                 rte_eth_random_addr(hw->mac.addr);
     163                 :          0 :                 high_mac = *(uint32_t *)hw->mac.addr;
     164                 :          0 :                 enetc4_port_wr(enetc_hw, ENETC4_PMAR0, high_mac);
     165                 :          0 :                 low_mac = *(uint16_t *)(hw->mac.addr + 4);
     166                 :          0 :                 enetc4_port_wr(enetc_hw, ENETC4_PMAR1, low_mac);
     167                 :          0 :                 enetc_print_ethaddr("New address: ",
     168                 :            :                               (const struct rte_ether_addr *)hw->mac.addr);
     169                 :            :         }
     170                 :            : 
     171                 :            :         /* Allocate memory for storing MAC addresses */
     172                 :          0 :         snprintf(eth_name, sizeof(eth_name), "enetc4_eth_%d", eth_dev->data->port_id);
     173                 :          0 :         eth_dev->data->mac_addrs = rte_zmalloc(eth_name,
     174                 :            :                                         RTE_ETHER_ADDR_LEN, 0);
     175         [ #  # ]:          0 :         if (!eth_dev->data->mac_addrs) {
     176                 :          0 :                 ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
     177                 :            :                               "store MAC addresses",
     178                 :            :                               RTE_ETHER_ADDR_LEN * 1);
     179                 :          0 :                 return -ENOMEM;
     180                 :            :         }
     181                 :            : 
     182                 :            :         /* Copy the permanent MAC address */
     183                 :            :         rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
     184                 :            :                         &eth_dev->data->mac_addrs[0]);
     185                 :            : 
     186                 :          0 :         return 0;
     187                 :            : }
     188                 :            : 
     189                 :            : int
     190                 :          0 : enetc4_dev_infos_get(struct rte_eth_dev *dev,
     191                 :            :                     struct rte_eth_dev_info *dev_info)
     192                 :            : {
     193                 :            :         struct enetc_eth_hw *hw =
     194                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     195                 :            : 
     196                 :          0 :         PMD_INIT_FUNC_TRACE();
     197                 :            : 
     198                 :          0 :         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
     199                 :            :                 .nb_max = MAX_BD_COUNT,
     200                 :            :                 .nb_min = MIN_BD_COUNT,
     201                 :            :                 .nb_align = BD_ALIGN,
     202                 :            :         };
     203                 :          0 :         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
     204                 :            :                 .nb_max = MAX_BD_COUNT,
     205                 :            :                 .nb_min = MIN_BD_COUNT,
     206                 :            :                 .nb_align = BD_ALIGN,
     207                 :            :         };
     208                 :          0 :         dev_info->max_rx_queues = hw->max_rx_queues;
     209                 :          0 :         dev_info->max_tx_queues = hw->max_tx_queues;
     210                 :          0 :         dev_info->max_rx_pktlen = ENETC4_MAC_MAXFRM_SIZE;
     211                 :          0 :         dev_info->rx_offload_capa = dev_rx_offloads_sup;
     212                 :          0 :         dev_info->tx_offload_capa = dev_tx_offloads_sup;
     213                 :          0 :         dev_info->flow_type_rss_offloads = ENETC_RSS_OFFLOAD_ALL;
     214                 :            : 
     215                 :          0 :         return 0;
     216                 :            : }
     217                 :            : 
     218                 :            : static int
     219                 :          0 : enetc4_alloc_txbdr(struct enetc_bdr *txr, uint16_t nb_desc)
     220                 :            : {
     221                 :            :         int size;
     222                 :            : 
     223                 :          0 :         size = nb_desc * sizeof(struct enetc_swbd);
     224                 :          0 :         txr->q_swbd = rte_malloc(NULL, size, ENETC_BD_RING_ALIGN);
     225         [ #  # ]:          0 :         if (txr->q_swbd == NULL)
     226                 :            :                 return -ENOMEM;
     227                 :            : 
     228                 :          0 :         size = nb_desc * sizeof(struct enetc_bdr);
     229                 :          0 :         txr->bd_base = rte_malloc(NULL, size, ENETC_BD_RING_ALIGN);
     230         [ #  # ]:          0 :         if (txr->bd_base == NULL) {
     231                 :          0 :                 rte_free(txr->q_swbd);
     232                 :          0 :                 txr->q_swbd = NULL;
     233                 :          0 :                 return -ENOMEM;
     234                 :            :         }
     235                 :          0 :         txr->bd_count = nb_desc;
     236                 :          0 :         txr->next_to_clean = 0;
     237                 :          0 :         txr->next_to_use = 0;
     238                 :            : 
     239                 :          0 :         return 0;
     240                 :            : }
     241                 :            : 
     242                 :            : static void
     243                 :            : enetc4_free_bdr(struct enetc_bdr *rxr)
     244                 :            : {
     245                 :          0 :         rte_free(rxr->bd_base);
     246                 :          0 :         rte_free(rxr->q_swbd);
     247                 :          0 :         rxr->q_swbd = NULL;
     248                 :          0 :         rxr->bd_base = NULL;
     249                 :            : }
     250                 :            : 
     251                 :            : static void
     252                 :          0 : enetc4_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
     253                 :            : {
     254                 :          0 :         int idx = tx_ring->index;
     255                 :            :         phys_addr_t bd_address;
     256                 :            : 
     257                 :            :         bd_address = (phys_addr_t)
     258                 :          0 :                      rte_mem_virt2iova((const void *)tx_ring->bd_base);
     259                 :          0 :         enetc4_txbdr_wr(hw, idx, ENETC_TBBAR0,
     260                 :            :                        lower_32_bits((uint64_t)bd_address));
     261                 :          0 :         enetc4_txbdr_wr(hw, idx, ENETC_TBBAR1,
     262                 :            :                        upper_32_bits((uint64_t)bd_address));
     263                 :          0 :         enetc4_txbdr_wr(hw, idx, ENETC_TBLENR,
     264                 :            :                        ENETC_RTBLENR_LEN(tx_ring->bd_count));
     265                 :            : 
     266                 :          0 :         enetc4_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
     267                 :          0 :         enetc4_txbdr_wr(hw, idx, ENETC_TBCISR, 0);
     268                 :          0 :         tx_ring->tcir = (void *)((size_t)hw->reg +
     269                 :            :                         ENETC_BDR(TX, idx, ENETC_TBCIR));
     270                 :          0 :         tx_ring->tcisr = (void *)((size_t)hw->reg +
     271                 :            :                          ENETC_BDR(TX, idx, ENETC_TBCISR));
     272                 :          0 : }
     273                 :            : 
     274                 :            : int
     275                 :          0 : enetc4_tx_queue_setup(struct rte_eth_dev *dev,
     276                 :            :                      uint16_t queue_idx,
     277                 :            :                      uint16_t nb_desc,
     278                 :            :                      unsigned int socket_id __rte_unused,
     279                 :            :                      const struct rte_eth_txconf *tx_conf)
     280                 :            : {
     281                 :            :         int err;
     282                 :            :         struct enetc_bdr *tx_ring;
     283                 :          0 :         struct rte_eth_dev_data *data = dev->data;
     284                 :          0 :         struct enetc_eth_adapter *priv =
     285                 :            :                         ENETC_DEV_PRIVATE(data->dev_private);
     286                 :            : 
     287                 :          0 :         PMD_INIT_FUNC_TRACE();
     288         [ #  # ]:          0 :         if (nb_desc > MAX_BD_COUNT)
     289                 :            :                 return -1;
     290                 :            : 
     291                 :          0 :         tx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
     292         [ #  # ]:          0 :         if (tx_ring == NULL) {
     293                 :          0 :                 ENETC_PMD_ERR("Failed to allocate TX ring memory");
     294                 :            :                 err = -ENOMEM;
     295                 :          0 :                 return err;
     296                 :            :         }
     297                 :            : 
     298                 :          0 :         tx_ring->index = queue_idx;
     299                 :          0 :         err = enetc4_alloc_txbdr(tx_ring, nb_desc);
     300         [ #  # ]:          0 :         if (err)
     301                 :          0 :                 goto fail;
     302                 :            : 
     303                 :          0 :         tx_ring->ndev = dev;
     304                 :          0 :         enetc4_setup_txbdr(&priv->hw.hw, tx_ring);
     305                 :          0 :         data->tx_queues[queue_idx] = tx_ring;
     306                 :          0 :         tx_ring->tx_deferred_start = tx_conf->tx_deferred_start;
     307         [ #  # ]:          0 :         if (!tx_conf->tx_deferred_start) {
     308                 :            :                 /* enable ring */
     309                 :          0 :                 enetc4_txbdr_wr(&priv->hw.hw, tx_ring->index,
     310                 :            :                                ENETC_TBMR, ENETC_TBMR_EN);
     311                 :          0 :                 dev->data->tx_queue_state[tx_ring->index] =
     312                 :            :                                RTE_ETH_QUEUE_STATE_STARTED;
     313                 :            :         } else {
     314                 :          0 :                 dev->data->tx_queue_state[tx_ring->index] =
     315                 :            :                                RTE_ETH_QUEUE_STATE_STOPPED;
     316                 :            :         }
     317                 :            : 
     318                 :            :         return 0;
     319                 :            : fail:
     320                 :          0 :         rte_free(tx_ring);
     321                 :            : 
     322                 :          0 :         return err;
     323                 :            : }
     324                 :            : 
     325                 :            : void
     326                 :          0 : enetc4_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
     327                 :            : {
     328                 :          0 :         void *txq = dev->data->tx_queues[qid];
     329                 :            :         struct enetc_hw *hw;
     330                 :            :         struct enetc_swbd *tx_swbd;
     331                 :            :         int i;
     332                 :            :         uint32_t val;
     333                 :            :         struct enetc_bdr *tx_ring;
     334                 :            :         struct enetc_eth_hw *eth_hw;
     335                 :            : 
     336                 :          0 :         PMD_INIT_FUNC_TRACE();
     337         [ #  # ]:          0 :         if (txq == NULL)
     338                 :            :                 return;
     339                 :            : 
     340                 :            :         tx_ring = (struct enetc_bdr *)txq;
     341                 :            :         eth_hw =
     342                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(tx_ring->ndev->data->dev_private);
     343                 :            : 
     344                 :            :         /* Disable the ring */
     345                 :            :         hw = &eth_hw->hw;
     346                 :          0 :         val = enetc4_txbdr_rd(hw, tx_ring->index, ENETC_TBMR);
     347                 :          0 :         val &= (~ENETC_TBMR_EN);
     348                 :          0 :         enetc4_txbdr_wr(hw, tx_ring->index, ENETC_TBMR, val);
     349                 :            : 
     350                 :            :         /* clean the ring*/
     351                 :          0 :         i = tx_ring->next_to_clean;
     352                 :          0 :         tx_swbd = &tx_ring->q_swbd[i];
     353         [ #  # ]:          0 :         while (tx_swbd->buffer_addr != NULL) {
     354                 :          0 :                 rte_pktmbuf_free(tx_swbd->buffer_addr);
     355                 :          0 :                 tx_swbd->buffer_addr = NULL;
     356                 :          0 :                 tx_swbd++;
     357                 :          0 :                 i++;
     358         [ #  # ]:          0 :                 if (unlikely(i == tx_ring->bd_count)) {
     359                 :            :                         i = 0;
     360                 :          0 :                         tx_swbd = &tx_ring->q_swbd[i];
     361                 :            :                 }
     362                 :            :         }
     363                 :            : 
     364                 :            :         enetc4_free_bdr(tx_ring);
     365                 :          0 :         rte_free(tx_ring);
     366                 :            : }
     367                 :            : 
     368                 :            : static int
     369                 :          0 : enetc4_alloc_rxbdr(struct enetc_bdr *rxr, uint16_t nb_desc)
     370                 :            : {
     371                 :            :         int size;
     372                 :            : 
     373                 :          0 :         size = nb_desc * sizeof(struct enetc_swbd);
     374                 :          0 :         rxr->q_swbd = rte_malloc(NULL, size, ENETC_BD_RING_ALIGN);
     375         [ #  # ]:          0 :         if (rxr->q_swbd == NULL)
     376                 :            :                 return -ENOMEM;
     377                 :            : 
     378                 :          0 :         size = nb_desc * sizeof(struct enetc_bdr);
     379                 :          0 :         rxr->bd_base = rte_malloc(NULL, size, ENETC_BD_RING_ALIGN);
     380         [ #  # ]:          0 :         if (rxr->bd_base == NULL) {
     381                 :          0 :                 rte_free(rxr->q_swbd);
     382                 :          0 :                 rxr->q_swbd = NULL;
     383                 :          0 :                 return -ENOMEM;
     384                 :            :         }
     385                 :          0 :         rxr->bd_count = nb_desc;
     386                 :          0 :         rxr->next_to_clean = 0;
     387                 :          0 :         rxr->next_to_use = 0;
     388                 :          0 :         rxr->next_to_alloc = 0;
     389                 :            : 
     390                 :          0 :         return 0;
     391                 :            : }
     392                 :            : 
     393                 :            : static void
     394                 :          0 : enetc4_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring,
     395                 :            :                   struct rte_mempool *mb_pool)
     396                 :            : {
     397                 :          0 :         int idx = rx_ring->index;
     398                 :            :         uint16_t buf_size;
     399                 :            :         phys_addr_t bd_address;
     400                 :            : 
     401                 :            :         bd_address = (phys_addr_t)
     402                 :          0 :                      rte_mem_virt2iova((const void *)rx_ring->bd_base);
     403                 :            : 
     404                 :          0 :         enetc4_rxbdr_wr(hw, idx, ENETC_RBBAR0,
     405                 :            :                        lower_32_bits((uint64_t)bd_address));
     406                 :          0 :         enetc4_rxbdr_wr(hw, idx, ENETC_RBBAR1,
     407                 :            :                        upper_32_bits((uint64_t)bd_address));
     408                 :          0 :         enetc4_rxbdr_wr(hw, idx, ENETC_RBLENR,
     409                 :            :                        ENETC_RTBLENR_LEN(rx_ring->bd_count));
     410                 :            : 
     411                 :          0 :         rx_ring->mb_pool = mb_pool;
     412                 :          0 :         rx_ring->rcir = (void *)((size_t)hw->reg +
     413         [ #  # ]:          0 :                         ENETC_BDR(RX, idx, ENETC_RBCIR));
     414                 :          0 :         enetc_refill_rx_ring(rx_ring, (enetc_bd_unused(rx_ring)));
     415         [ #  # ]:          0 :         buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rx_ring->mb_pool) -
     416                 :            :                    RTE_PKTMBUF_HEADROOM);
     417                 :          0 :         enetc4_rxbdr_wr(hw, idx, ENETC_RBBSR, buf_size);
     418                 :          0 :         enetc4_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
     419                 :          0 : }
     420                 :            : 
     421                 :            : int
     422                 :          0 : enetc4_rx_queue_setup(struct rte_eth_dev *dev,
     423                 :            :                      uint16_t rx_queue_id,
     424                 :            :                      uint16_t nb_rx_desc,
     425                 :            :                      unsigned int socket_id __rte_unused,
     426                 :            :                      const struct rte_eth_rxconf *rx_conf,
     427                 :            :                      struct rte_mempool *mb_pool)
     428                 :            : {
     429                 :            :         int err = 0;
     430                 :            :         struct enetc_bdr *rx_ring;
     431                 :          0 :         struct rte_eth_dev_data *data =  dev->data;
     432                 :          0 :         struct enetc_eth_adapter *adapter =
     433                 :            :                         ENETC_DEV_PRIVATE(data->dev_private);
     434                 :          0 :         uint64_t rx_offloads = data->dev_conf.rxmode.offloads;
     435                 :            : 
     436                 :          0 :         PMD_INIT_FUNC_TRACE();
     437         [ #  # ]:          0 :         if (nb_rx_desc > MAX_BD_COUNT)
     438                 :            :                 return -1;
     439                 :            : 
     440                 :          0 :         rx_ring = rte_zmalloc(NULL, sizeof(struct enetc_bdr), 0);
     441         [ #  # ]:          0 :         if (rx_ring == NULL) {
     442                 :          0 :                 ENETC_PMD_ERR("Failed to allocate RX ring memory");
     443                 :            :                 err = -ENOMEM;
     444                 :          0 :                 return err;
     445                 :            :         }
     446                 :            : 
     447                 :          0 :         rx_ring->index = rx_queue_id;
     448                 :          0 :         err = enetc4_alloc_rxbdr(rx_ring, nb_rx_desc);
     449         [ #  # ]:          0 :         if (err)
     450                 :          0 :                 goto fail;
     451                 :            : 
     452                 :          0 :         rx_ring->ndev = dev;
     453                 :          0 :         enetc4_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
     454                 :          0 :         data->rx_queues[rx_queue_id] = rx_ring;
     455                 :          0 :         rx_ring->rx_deferred_start = rx_conf->rx_deferred_start;
     456                 :            : 
     457         [ #  # ]:          0 :         if (!rx_conf->rx_deferred_start) {
     458                 :            :                 /* enable ring */
     459                 :          0 :                 enetc4_rxbdr_wr(&adapter->hw.hw, rx_ring->index, ENETC_RBMR,
     460                 :            :                                ENETC_RBMR_EN);
     461                 :          0 :                 dev->data->rx_queue_state[rx_ring->index] =
     462                 :            :                                RTE_ETH_QUEUE_STATE_STARTED;
     463                 :            :         } else {
     464                 :          0 :                 dev->data->rx_queue_state[rx_ring->index] =
     465                 :            :                                RTE_ETH_QUEUE_STATE_STOPPED;
     466                 :            :         }
     467                 :            : 
     468                 :          0 :         rx_ring->crc_len = (uint8_t)((rx_offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) ?
     469                 :            :                                      RTE_ETHER_CRC_LEN : 0);
     470                 :          0 :         return 0;
     471                 :            : fail:
     472                 :          0 :         rte_free(rx_ring);
     473                 :            : 
     474                 :          0 :         return err;
     475                 :            : }
     476                 :            : 
     477                 :            : void
     478                 :          0 : enetc4_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
     479                 :            : {
     480                 :          0 :         void *rxq = dev->data->rx_queues[qid];
     481                 :            :         struct enetc_swbd *q_swbd;
     482                 :            :         struct enetc_hw *hw;
     483                 :            :         uint32_t val;
     484                 :            :         int i;
     485                 :            :         struct enetc_bdr *rx_ring;
     486                 :            :         struct enetc_eth_hw *eth_hw;
     487                 :            : 
     488                 :          0 :         PMD_INIT_FUNC_TRACE();
     489         [ #  # ]:          0 :         if (rxq == NULL)
     490                 :            :                 return;
     491                 :            : 
     492                 :            :         rx_ring = (struct enetc_bdr *)rxq;
     493                 :            :         eth_hw =
     494                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(rx_ring->ndev->data->dev_private);
     495                 :            : 
     496                 :            :         /* Disable the ring */
     497                 :            :         hw = &eth_hw->hw;
     498                 :          0 :         val = enetc4_rxbdr_rd(hw, rx_ring->index, ENETC_RBMR);
     499                 :          0 :         val &= (~ENETC_RBMR_EN);
     500                 :          0 :         enetc4_rxbdr_wr(hw, rx_ring->index, ENETC_RBMR, val);
     501                 :            : 
     502                 :            :         /* Clean the ring */
     503                 :          0 :         i = rx_ring->next_to_clean;
     504                 :          0 :         q_swbd = &rx_ring->q_swbd[i];
     505         [ #  # ]:          0 :         while (i != rx_ring->next_to_use) {
     506                 :          0 :                 rte_pktmbuf_free(q_swbd->buffer_addr);
     507                 :          0 :                 q_swbd->buffer_addr = NULL;
     508                 :          0 :                 q_swbd++;
     509                 :          0 :                 i++;
     510         [ #  # ]:          0 :                 if (unlikely(i == rx_ring->bd_count)) {
     511                 :            :                         i = 0;
     512                 :          0 :                         q_swbd = &rx_ring->q_swbd[i];
     513                 :            :                 }
     514                 :            :         }
     515                 :            : 
     516                 :            :         enetc4_free_bdr(rx_ring);
     517                 :          0 :         rte_free(rx_ring);
     518                 :            : }
     519                 :            : 
     520                 :            : static
     521                 :          0 : int enetc4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
     522                 :            :                      struct eth_queue_stats *qstats __rte_unused)
     523                 :            : {
     524                 :            :         struct enetc_eth_hw *hw =
     525                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     526                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     527                 :            : 
     528                 :            :         /*
     529                 :            :          * Total received packets, bad + good, if we want to get counters
     530                 :            :          * of only good received packets then use ENETC4_PM_RFRM,
     531                 :            :          * ENETC4_PM_TFRM registers.
     532                 :            :          */
     533                 :          0 :         stats->ipackets = enetc4_port_rd(enetc_hw, ENETC4_PM_RPKT(0));
     534                 :          0 :         stats->opackets = enetc4_port_rd(enetc_hw, ENETC4_PM_TPKT(0));
     535                 :          0 :         stats->ibytes =  enetc4_port_rd(enetc_hw, ENETC4_PM_REOCT(0));
     536                 :          0 :         stats->obytes = enetc4_port_rd(enetc_hw, ENETC4_PM_TEOCT(0));
     537                 :            :         /*
     538                 :            :          * Dropped + Truncated packets, use ENETC4_PM_RDRNTP(0) for without
     539                 :            :          * truncated packets
     540                 :            :          */
     541                 :          0 :         stats->imissed = enetc4_port_rd(enetc_hw, ENETC4_PM_RDRP(0));
     542                 :          0 :         stats->ierrors = enetc4_port_rd(enetc_hw, ENETC4_PM_RERR(0));
     543                 :          0 :         stats->oerrors = enetc4_port_rd(enetc_hw, ENETC4_PM_TERR(0));
     544                 :            : 
     545                 :          0 :         return 0;
     546                 :            : }
     547                 :            : 
     548                 :            : static int
     549                 :          0 : enetc4_stats_reset(struct rte_eth_dev *dev)
     550                 :            : {
     551                 :            :         struct enetc_eth_hw *hw =
     552                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     553                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     554                 :            : 
     555                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM0_STAT_CONFIG, ENETC4_CLEAR_STATS);
     556                 :            : 
     557                 :          0 :         return 0;
     558                 :            : }
     559                 :            : 
     560                 :            : static void
     561                 :            : enetc4_rss_configure(struct enetc_hw *hw, int enable)
     562                 :            : {
     563                 :            :         uint32_t reg;
     564                 :            : 
     565                 :          0 :         reg = enetc4_rd(hw, ENETC_SIMR);
     566                 :          0 :         reg &= ~ENETC_SIMR_RSSE;
     567                 :          0 :         reg |= (enable) ? ENETC_SIMR_RSSE : 0;
     568                 :          0 :         enetc4_wr(hw, ENETC_SIMR, reg);
     569                 :          0 : }
     570                 :            : 
     571                 :            : int
     572                 :          0 : enetc4_dev_close(struct rte_eth_dev *dev)
     573                 :            : {
     574                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     575                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     576                 :            :         uint16_t i;
     577                 :            :         int ret;
     578                 :            : 
     579                 :          0 :         PMD_INIT_FUNC_TRACE();
     580         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     581                 :            :                 return 0;
     582                 :            : 
     583         [ #  # ]:          0 :         if (hw->device_id == ENETC4_DEV_ID_VF) {
     584         [ #  # ]:          0 :                 if (dev->data->dev_conf.intr_conf.lsc != 0)
     585                 :          0 :                         enetc4_vf_dev_intr(dev, false);
     586                 :          0 :                 ret = enetc4_vf_dev_stop(dev);
     587                 :            :         } else {
     588                 :          0 :                 ret = enetc4_dev_stop(dev);
     589                 :            :         }
     590                 :            : 
     591         [ #  # ]:          0 :         if (dev->data->nb_rx_queues > 1) {
     592                 :            :                 /* Disable RSS */
     593                 :            :                 enetc4_rss_configure(enetc_hw, false);
     594                 :            :                 /* Free CBDR */
     595                 :          0 :                 enetc_free_cbdr(&hw->cbdr);
     596                 :            :         }
     597                 :            : 
     598         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     599                 :          0 :                 enetc4_rx_queue_release(dev, i);
     600                 :          0 :                 dev->data->rx_queues[i] = NULL;
     601                 :            :         }
     602                 :          0 :         dev->data->nb_rx_queues = 0;
     603                 :            : 
     604         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++) {
     605                 :          0 :                 enetc4_tx_queue_release(dev, i);
     606                 :          0 :                 dev->data->tx_queues[i] = NULL;
     607                 :            :         }
     608                 :          0 :         dev->data->nb_tx_queues = 0;
     609                 :            : 
     610         [ #  # ]:          0 :         if (rte_eal_iova_mode() == RTE_IOVA_PA)
     611                 :          0 :                 dpaax_iova_table_depopulate();
     612                 :            : 
     613                 :            :         return ret;
     614                 :            : }
     615                 :            : 
     616                 :            : static int
     617                 :          0 : enetc4_promiscuous_enable(struct rte_eth_dev *dev)
     618                 :            : {
     619                 :            :         struct enetc_eth_hw *hw =
     620                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     621                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     622                 :            :         uint32_t psipmr = 0;
     623                 :            : 
     624                 :          0 :         psipmr = enetc4_port_rd(enetc_hw, ENETC4_PSIPMMR);
     625                 :            : 
     626                 :            :         /* Setting to enable promiscuous mode for all ports*/
     627                 :          0 :         psipmr |= PSIPMMR_SI_MAC_UP | PSIPMMR_SI_MAC_MP;
     628                 :            : 
     629                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PSIPMMR, psipmr);
     630                 :            : 
     631                 :          0 :         return 0;
     632                 :            : }
     633                 :            : 
     634                 :            : static int
     635                 :          0 : enetc4_promiscuous_disable(struct rte_eth_dev *dev)
     636                 :            : {
     637                 :            :         struct enetc_eth_hw *hw =
     638                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     639                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     640                 :            :         uint32_t psipmr = 0;
     641                 :            : 
     642                 :            :         /* Setting to disable promiscuous mode for SI0*/
     643                 :          0 :         psipmr = enetc4_port_rd(enetc_hw, ENETC4_PSIPMMR);
     644                 :          0 :         psipmr &= (~PSIPMMR_SI_MAC_UP);
     645                 :            : 
     646         [ #  # ]:          0 :         if (dev->data->all_multicast == 0)
     647                 :          0 :                 psipmr &= (~PSIPMMR_SI_MAC_MP);
     648                 :            : 
     649                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PSIPMMR, psipmr);
     650                 :            : 
     651                 :          0 :         return 0;
     652                 :            : }
     653                 :            : 
     654                 :            : int
     655                 :          0 : enetc4_dev_configure(struct rte_eth_dev *dev)
     656                 :            : {
     657                 :            :         struct enetc_eth_hw *hw =
     658                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     659                 :            :         struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
     660                 :          0 :         uint64_t rx_offloads = eth_conf->rxmode.offloads;
     661                 :          0 :         uint64_t tx_offloads = eth_conf->txmode.offloads;
     662                 :            :         uint32_t checksum = L3_CKSUM | L4_CKSUM;
     663                 :          0 :         struct enetc_hw *enetc_hw = &hw->hw;
     664                 :            :         uint32_t max_len;
     665                 :            :         uint32_t val, num_rss;
     666                 :            :         uint32_t ret = 0, i;
     667                 :            :         uint32_t *rss_table;
     668                 :            : 
     669                 :          0 :         PMD_INIT_FUNC_TRACE();
     670                 :            : 
     671                 :          0 :         max_len = dev->data->dev_conf.rxmode.mtu + RTE_ETHER_HDR_LEN +
     672                 :            :                   RTE_ETHER_CRC_LEN;
     673                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PM_MAXFRM(0), ENETC_SET_MAXFRM(max_len));
     674                 :            : 
     675                 :            :         val = ENETC4_MAC_MAXFRM_SIZE | SDU_TYPE_MPDU;
     676                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PTCTMSDUR(0), val | SDU_TYPE_MPDU);
     677                 :            : 
     678                 :            :         /* Rx offloads which are enabled by default */
     679         [ #  # ]:          0 :         if (dev_rx_offloads_sup & ~rx_offloads) {
     680                 :          0 :                 ENETC_PMD_INFO("Some of rx offloads enabled by default"
     681                 :            :                                 " - requested 0x%" PRIx64 " fixed are 0x%" PRIx64,
     682                 :            :                                 rx_offloads, dev_rx_offloads_sup);
     683                 :            :         }
     684                 :            : 
     685                 :            :         /* Tx offloads which are enabled by default */
     686         [ #  # ]:          0 :         if (dev_tx_offloads_sup & ~tx_offloads) {
     687                 :          0 :                 ENETC_PMD_INFO("Some of tx offloads enabled by default"
     688                 :            :                                " - requested 0x%" PRIx64 " fixed are 0x%" PRIx64,
     689                 :            :                                tx_offloads, dev_tx_offloads_sup);
     690                 :            :         }
     691                 :            : 
     692         [ #  # ]:          0 :         if (rx_offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)
     693                 :            :                 checksum &= ~L3_CKSUM;
     694                 :            : 
     695         [ #  # ]:          0 :         if (rx_offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
     696                 :          0 :                 checksum &= ~L4_CKSUM;
     697                 :            : 
     698                 :          0 :         enetc4_port_wr(enetc_hw, ENETC4_PARCSCR, checksum);
     699                 :            : 
     700                 :            :         /* Enable interrupts */
     701         [ #  # ]:          0 :         if (hw->device_id == ENETC4_DEV_ID_VF) {
     702         [ #  # ]:          0 :                 if (dev->data->dev_conf.intr_conf.lsc != 0) {
     703                 :          0 :                         ret = enetc4_vf_dev_intr(dev, true);
     704         [ #  # ]:          0 :                         if (ret)
     705                 :          0 :                                 ENETC_PMD_WARN("Failed to setup link interrupts");
     706                 :            :                 }
     707                 :            :         }
     708                 :            : 
     709                 :            :         /* Disable and reset RX and TX rings */
     710         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++)
     711                 :          0 :                 enetc4_rxbdr_wr(enetc_hw, i, ENETC_RBMR, ENETC_BMR_RESET);
     712                 :            : 
     713         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; i++)
     714                 :          0 :                 enetc4_rxbdr_wr(enetc_hw, i, ENETC_TBMR, ENETC_BMR_RESET);
     715                 :            : 
     716         [ #  # ]:          0 :         if (dev->data->nb_rx_queues <= 1)
     717                 :            :                 return 0;
     718                 :            : 
     719                 :            :         /* Setup RSS */
     720                 :            :         /* Setup control BDR */
     721                 :          0 :         ret = enetc4_setup_cbdr(dev, enetc_hw, ENETC_CBDR_SIZE, &hw->cbdr);
     722         [ #  # ]:          0 :         if (ret) {
     723                 :            :                 /* Disable RSS */
     724                 :            :                 enetc4_rss_configure(enetc_hw, false);
     725                 :          0 :                 return ret;
     726                 :            :         }
     727                 :            : 
     728                 :            :         /* Reset CIR again after enable CBDR*/
     729                 :          0 :         rte_delay_us(ENETC_CBDR_DELAY);
     730                 :          0 :         ENETC_PMD_DEBUG("CIR %x after CBDR enable", rte_read32(hw->cbdr.regs.cir));
     731                 :          0 :         rte_write32(0, hw->cbdr.regs.cir);
     732                 :          0 :         ENETC_PMD_DEBUG("CIR %x after reset", rte_read32(hw->cbdr.regs.cir));
     733                 :            : 
     734                 :          0 :         val = enetc_rd(enetc_hw, ENETC_SIPCAPR0);
     735         [ #  # ]:          0 :         if (val & ENETC_SIPCAPR0_RSS) {
     736                 :          0 :                 num_rss = enetc_rd(enetc_hw, ENETC_SIRSSCAPR);
     737                 :          0 :                 hw->num_rss = ENETC_SIRSSCAPR_GET_NUM_RSS(num_rss);
     738                 :          0 :                 ENETC_PMD_DEBUG("num_rss = %d", hw->num_rss);
     739                 :            : 
     740                 :            :                 /* Add number of BDR groups */
     741                 :          0 :                 enetc4_wr(enetc_hw, ENETC_SIRBGCR, dev->data->nb_rx_queues);
     742                 :            : 
     743                 :            : 
     744                 :            :                 /* Configuring indirecton table with default values
     745                 :            :                  * Hash algorithm and RSS secret key to be filled by PF
     746                 :            :                  */
     747                 :          0 :                 rss_table = rte_malloc(NULL, hw->num_rss * sizeof(*rss_table), ENETC_CBDR_ALIGN);
     748         [ #  # ]:          0 :                 if (!rss_table) {
     749                 :            :                         enetc4_rss_configure(enetc_hw, false);
     750                 :          0 :                         enetc_free_cbdr(&hw->cbdr);
     751                 :          0 :                         return -ENOMEM;
     752                 :            :                 }
     753                 :            : 
     754                 :          0 :                 ENETC_PMD_DEBUG("Enabling RSS for port %s with queues = %d", dev->device->name,
     755                 :            :                                                         dev->data->nb_rx_queues);
     756         [ #  # ]:          0 :                 for (i = 0; i < hw->num_rss; i++)
     757                 :          0 :                         rss_table[i] = i % dev->data->nb_rx_queues;
     758                 :            : 
     759                 :          0 :                 ret = enetc_ntmp_rsst_query_or_update_entry(&hw->cbdr,
     760                 :            :                                         rss_table, hw->num_rss, false);
     761         [ #  # ]:          0 :                 if (ret) {
     762                 :          0 :                         ENETC_PMD_WARN("RSS indirection table update fails,"
     763                 :            :                                         "Scaling behaviour is undefined");
     764                 :            :                         enetc4_rss_configure(enetc_hw, false);
     765                 :          0 :                         enetc_free_cbdr(&hw->cbdr);
     766                 :            :                 }
     767                 :          0 :                 rte_free(rss_table);
     768                 :            : 
     769                 :            :                 /* Enable RSS */
     770                 :            :                 enetc4_rss_configure(enetc_hw, true);
     771                 :            :         }
     772                 :            : 
     773                 :            :         return 0;
     774                 :            : }
     775                 :            : 
     776                 :            : int
     777                 :          0 : enetc4_rx_queue_start(struct rte_eth_dev *dev, uint16_t qidx)
     778                 :            : {
     779                 :          0 :         struct enetc_eth_adapter *priv =
     780                 :          0 :                         ENETC_DEV_PRIVATE(dev->data->dev_private);
     781                 :            :         struct enetc_bdr *rx_ring;
     782                 :            :         uint32_t rx_data;
     783                 :            : 
     784                 :          0 :         PMD_INIT_FUNC_TRACE();
     785                 :          0 :         rx_ring = dev->data->rx_queues[qidx];
     786         [ #  # ]:          0 :         if (dev->data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
     787                 :          0 :                 rx_data = enetc4_rxbdr_rd(&priv->hw.hw, rx_ring->index,
     788                 :            :                                          ENETC_RBMR);
     789                 :          0 :                 rx_data = rx_data | ENETC_RBMR_EN;
     790                 :          0 :                 enetc4_rxbdr_wr(&priv->hw.hw, rx_ring->index, ENETC_RBMR,
     791                 :            :                                rx_data);
     792                 :          0 :                 dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
     793                 :            :         }
     794                 :            : 
     795                 :          0 :         return 0;
     796                 :            : }
     797                 :            : 
     798                 :            : int
     799                 :          0 : enetc4_rx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx)
     800                 :            : {
     801                 :          0 :         struct enetc_eth_adapter *priv =
     802                 :          0 :                         ENETC_DEV_PRIVATE(dev->data->dev_private);
     803                 :            :         struct enetc_bdr *rx_ring;
     804                 :            :         uint32_t rx_data;
     805                 :            : 
     806                 :          0 :         PMD_INIT_FUNC_TRACE();
     807                 :          0 :         rx_ring = dev->data->rx_queues[qidx];
     808         [ #  # ]:          0 :         if (dev->data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
     809                 :          0 :                 rx_data = enetc4_rxbdr_rd(&priv->hw.hw, rx_ring->index,
     810                 :            :                                          ENETC_RBMR);
     811                 :          0 :                 rx_data = rx_data & (~ENETC_RBMR_EN);
     812                 :          0 :                 enetc4_rxbdr_wr(&priv->hw.hw, rx_ring->index, ENETC_RBMR,
     813                 :            :                                rx_data);
     814                 :          0 :                 dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
     815                 :            :         }
     816                 :            : 
     817                 :          0 :         return 0;
     818                 :            : }
     819                 :            : 
     820                 :            : int
     821                 :          0 : enetc4_tx_queue_start(struct rte_eth_dev *dev, uint16_t qidx)
     822                 :            : {
     823                 :          0 :         struct enetc_eth_adapter *priv =
     824                 :          0 :                         ENETC_DEV_PRIVATE(dev->data->dev_private);
     825                 :            :         struct enetc_bdr *tx_ring;
     826                 :            :         uint32_t tx_data;
     827                 :            : 
     828                 :          0 :         PMD_INIT_FUNC_TRACE();
     829                 :          0 :         tx_ring = dev->data->tx_queues[qidx];
     830         [ #  # ]:          0 :         if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
     831                 :          0 :                 tx_data = enetc4_txbdr_rd(&priv->hw.hw, tx_ring->index,
     832                 :            :                                          ENETC_TBMR);
     833                 :          0 :                 tx_data = tx_data | ENETC_TBMR_EN;
     834                 :          0 :                 enetc4_txbdr_wr(&priv->hw.hw, tx_ring->index, ENETC_TBMR,
     835                 :            :                                tx_data);
     836                 :          0 :                 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
     837                 :            :         }
     838                 :            : 
     839                 :          0 :         return 0;
     840                 :            : }
     841                 :            : 
     842                 :            : int
     843                 :          0 : enetc4_tx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx)
     844                 :            : {
     845                 :          0 :         struct enetc_eth_adapter *priv =
     846                 :          0 :                         ENETC_DEV_PRIVATE(dev->data->dev_private);
     847                 :            :         struct enetc_bdr *tx_ring;
     848                 :            :         uint32_t tx_data;
     849                 :            : 
     850                 :          0 :         PMD_INIT_FUNC_TRACE();
     851                 :          0 :         tx_ring = dev->data->tx_queues[qidx];
     852         [ #  # ]:          0 :         if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
     853                 :          0 :                 tx_data = enetc4_txbdr_rd(&priv->hw.hw, tx_ring->index,
     854                 :            :                                          ENETC_TBMR);
     855                 :          0 :                 tx_data = tx_data & (~ENETC_TBMR_EN);
     856                 :          0 :                 enetc4_txbdr_wr(&priv->hw.hw, tx_ring->index, ENETC_TBMR,
     857                 :            :                                tx_data);
     858                 :          0 :                 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
     859                 :            :         }
     860                 :            : 
     861                 :          0 :         return 0;
     862                 :            : }
     863                 :            : 
     864                 :            : static void
     865                 :          0 : enetc4_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
     866                 :            :                         struct rte_eth_rxq_info *qinfo)
     867                 :            : {
     868                 :          0 :         struct enetc_bdr *rxq = dev->data->rx_queues[queue_id];
     869                 :            : 
     870                 :          0 :         qinfo->mp = rxq->mb_pool;
     871                 :          0 :         qinfo->scattered_rx = dev->data->scattered_rx;
     872                 :          0 :         qinfo->nb_desc = rxq->bd_count;
     873                 :          0 :         qinfo->conf.rx_free_thresh = 0;
     874                 :          0 :         qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
     875                 :          0 :         qinfo->conf.rx_drop_en = 0;
     876                 :          0 : }
     877                 :            : 
     878                 :            : static void
     879                 :          0 : enetc4_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
     880                 :            :                         struct rte_eth_txq_info *qinfo)
     881                 :            : {
     882                 :          0 :         struct enetc_bdr *txq = dev->data->tx_queues[queue_id];
     883                 :            : 
     884                 :          0 :         qinfo->nb_desc = txq->bd_count;
     885                 :          0 :         qinfo->conf.tx_thresh.pthresh = 0;
     886                 :          0 :         qinfo->conf.tx_thresh.hthresh = 0;
     887                 :          0 :         qinfo->conf.tx_thresh.wthresh = 0;
     888                 :          0 :         qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
     889                 :          0 :         qinfo->conf.tx_free_thresh = 0;
     890                 :          0 :         qinfo->conf.tx_rs_thresh = 0;
     891                 :          0 : }
     892                 :            : 
     893                 :            : const uint32_t *
     894                 :          0 : enetc4_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
     895                 :            :                             size_t *no_of_elements)
     896                 :            : {
     897                 :          0 :         PMD_INIT_FUNC_TRACE();
     898                 :            :         static const uint32_t ptypes[] = {
     899                 :            :                 RTE_PTYPE_L2_ETHER,
     900                 :            :                 RTE_PTYPE_L3_IPV4,
     901                 :            :                 RTE_PTYPE_L3_IPV6,
     902                 :            :                 RTE_PTYPE_L4_TCP,
     903                 :            :                 RTE_PTYPE_L4_UDP,
     904                 :            :                 RTE_PTYPE_L4_SCTP,
     905                 :            :                 RTE_PTYPE_L4_ICMP,
     906                 :            :                 RTE_PTYPE_L4_FRAG,
     907                 :            :                 RTE_PTYPE_TUNNEL_ESP,
     908                 :            :                 RTE_PTYPE_UNKNOWN
     909                 :            :         };
     910                 :            : 
     911                 :          0 :         *no_of_elements = RTE_DIM(ptypes);
     912                 :          0 :         return ptypes;
     913                 :            : }
     914                 :            : 
     915                 :            : /*
     916                 :            :  * The set of PCI devices this driver supports
     917                 :            :  */
     918                 :            : static const struct rte_pci_id pci_id_enetc4_map[] = {
     919                 :            :         { RTE_PCI_DEVICE(PCI_VENDOR_ID_NXP, ENETC4_DEV_ID) },
     920                 :            :         { .vendor_id = 0, /* sentinel */ },
     921                 :            : };
     922                 :            : 
     923                 :            : /* Features supported by this driver */
     924                 :            : static const struct eth_dev_ops enetc4_ops = {
     925                 :            :         .dev_configure        = enetc4_dev_configure,
     926                 :            :         .dev_start            = enetc4_dev_start,
     927                 :            :         .dev_stop             = enetc4_dev_stop,
     928                 :            :         .dev_close            = enetc4_dev_close,
     929                 :            :         .dev_infos_get        = enetc4_dev_infos_get,
     930                 :            :         .link_update          = enetc4_link_update,
     931                 :            :         .stats_get            = enetc4_stats_get,
     932                 :            :         .stats_reset          = enetc4_stats_reset,
     933                 :            :         .promiscuous_enable   = enetc4_promiscuous_enable,
     934                 :            :         .promiscuous_disable  = enetc4_promiscuous_disable,
     935                 :            :         .rx_queue_setup       = enetc4_rx_queue_setup,
     936                 :            :         .rx_queue_start       = enetc4_rx_queue_start,
     937                 :            :         .rx_queue_stop        = enetc4_rx_queue_stop,
     938                 :            :         .rx_queue_release     = enetc4_rx_queue_release,
     939                 :            :         .rxq_info_get         = enetc4_rxq_info_get,
     940                 :            :         .tx_queue_setup       = enetc4_tx_queue_setup,
     941                 :            :         .tx_queue_start       = enetc4_tx_queue_start,
     942                 :            :         .tx_queue_stop        = enetc4_tx_queue_stop,
     943                 :            :         .tx_queue_release     = enetc4_tx_queue_release,
     944                 :            :         .txq_info_get         = enetc4_txq_info_get,
     945                 :            :         .dev_supported_ptypes_get = enetc4_supported_ptypes_get,
     946                 :            : };
     947                 :            : 
     948                 :            : /*
     949                 :            :  * Storing the HW base addresses
     950                 :            :  *
     951                 :            :  * @param eth_dev
     952                 :            :  *   - Pointer to the structure rte_eth_dev
     953                 :            :  */
     954                 :            : void
     955                 :          0 : enetc4_dev_hw_init(struct rte_eth_dev *eth_dev)
     956                 :            : {
     957                 :            :         struct enetc_eth_hw *hw =
     958                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
     959                 :          0 :         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
     960                 :            : 
     961                 :          0 :         eth_dev->rx_pkt_burst = &enetc_recv_pkts_nc;
     962                 :          0 :         eth_dev->tx_pkt_burst = &enetc_xmit_pkts_nc;
     963                 :            : 
     964                 :            :         /* Retrieving and storing the HW base address of device */
     965                 :          0 :         hw->hw.reg = (void *)pci_dev->mem_resource[0].addr;
     966                 :          0 :         hw->device_id = pci_dev->id.device_id;
     967                 :            : 
     968                 :            :         /* Calculating and storing the base HW addresses */
     969                 :          0 :         hw->hw.port = (void *)((size_t)hw->hw.reg + ENETC_PORT_BASE);
     970                 :          0 :         hw->hw.global = (void *)((size_t)hw->hw.reg + ENETC_GLOBAL_BASE);
     971                 :          0 : }
     972                 :            : 
     973                 :            : /**
     974                 :            :  * Initialisation of the enetc4 device
     975                 :            :  *
     976                 :            :  * @param eth_dev
     977                 :            :  *   - Pointer to the structure rte_eth_dev
     978                 :            :  *
     979                 :            :  * @return
     980                 :            :  *   - On success, zero.
     981                 :            :  *   - On failure, negative value.
     982                 :            :  */
     983                 :            : 
     984                 :            : static int
     985                 :          0 : enetc4_dev_init(struct rte_eth_dev *eth_dev)
     986                 :            : {
     987                 :          0 :         struct enetc_eth_hw *hw =
     988                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
     989                 :          0 :         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
     990                 :            :         int error = 0;
     991                 :            :         uint32_t si_cap;
     992                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     993                 :            : 
     994                 :          0 :         PMD_INIT_FUNC_TRACE();
     995                 :          0 :         eth_dev->dev_ops = &enetc4_ops;
     996                 :          0 :         enetc4_dev_hw_init(eth_dev);
     997                 :            : 
     998                 :          0 :         si_cap = enetc_rd(enetc_hw, ENETC_SICAPR0);
     999                 :          0 :         hw->max_tx_queues = si_cap & ENETC_SICAPR0_BDR_MASK;
    1000                 :          0 :         hw->max_rx_queues = (si_cap >> 16) & ENETC_SICAPR0_BDR_MASK;
    1001                 :            : 
    1002                 :          0 :         ENETC_PMD_DEBUG("Max RX queues = %d Max TX queues = %d",
    1003                 :            :                         hw->max_rx_queues, hw->max_tx_queues);
    1004                 :          0 :         error = enetc4_mac_init(hw, eth_dev);
    1005         [ #  # ]:          0 :         if (error != 0) {
    1006                 :          0 :                 ENETC_PMD_ERR("MAC initialization failed");
    1007                 :          0 :                 return -1;
    1008                 :            :         }
    1009                 :            : 
    1010                 :            :         /* Set MTU */
    1011                 :          0 :         enetc_port_wr(&hw->hw, ENETC4_PM_MAXFRM(0),
    1012                 :            :                       ENETC_SET_MAXFRM(RTE_ETHER_MAX_LEN));
    1013                 :          0 :         eth_dev->data->mtu = RTE_ETHER_MAX_LEN - RTE_ETHER_HDR_LEN -
    1014                 :            :                 RTE_ETHER_CRC_LEN;
    1015                 :            : 
    1016         [ #  # ]:          0 :         if (rte_eal_iova_mode() == RTE_IOVA_PA)
    1017                 :          0 :                 dpaax_iova_table_populate();
    1018                 :            : 
    1019                 :          0 :         ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
    1020                 :            :                         eth_dev->data->port_id, pci_dev->id.vendor_id,
    1021                 :            :                         pci_dev->id.device_id);
    1022                 :          0 :         return 0;
    1023                 :            : }
    1024                 :            : 
    1025                 :            : static int
    1026                 :          0 : enetc4_dev_uninit(struct rte_eth_dev *eth_dev)
    1027                 :            : {
    1028                 :          0 :         PMD_INIT_FUNC_TRACE();
    1029                 :            : 
    1030                 :          0 :         return enetc4_dev_close(eth_dev);
    1031                 :            : }
    1032                 :            : 
    1033                 :            : static int
    1034                 :          0 : enetc4_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
    1035                 :            :                            struct rte_pci_device *pci_dev)
    1036                 :            : {
    1037                 :          0 :         return rte_eth_dev_pci_generic_probe(pci_dev,
    1038                 :            :                                              sizeof(struct enetc_eth_adapter),
    1039                 :            :                                              enetc4_dev_init);
    1040                 :            : }
    1041                 :            : 
    1042                 :            : int
    1043                 :          0 : enetc4_pci_remove(struct rte_pci_device *pci_dev)
    1044                 :            : {
    1045                 :          0 :         return rte_eth_dev_pci_generic_remove(pci_dev, enetc4_dev_uninit);
    1046                 :            : }
    1047                 :            : 
    1048                 :            : static struct rte_pci_driver rte_enetc4_pmd = {
    1049                 :            :         .id_table = pci_id_enetc4_map,
    1050                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
    1051                 :            :         .probe = enetc4_pci_probe,
    1052                 :            :         .remove = enetc4_pci_remove,
    1053                 :            : };
    1054                 :            : 
    1055                 :        253 : RTE_PMD_REGISTER_PCI(net_enetc4, rte_enetc4_pmd);
    1056                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_enetc4, pci_id_enetc4_map);
    1057                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_enetc4, "* vfio-pci");
    1058         [ -  + ]:        253 : RTE_LOG_REGISTER_DEFAULT(enetc4_logtype_pmd, NOTICE);

Generated by: LCOV version 1.14