LCOV - code coverage report
Current view: top level - drivers/net/rnp - rnp_ethdev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 810 0.2 %
Date: 2025-07-01 21:32:37 Functions: 2 53 3.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 355 0.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2023 Mucse IC Design Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <ethdev_pci.h>
       6                 :            : #include <ethdev_driver.h>
       7                 :            : #include <rte_io.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : 
      10                 :            : #include "rnp.h"
      11                 :            : #include "rnp_logs.h"
      12                 :            : #include "base/rnp_mbx.h"
      13                 :            : #include "base/rnp_fw_cmd.h"
      14                 :            : #include "base/rnp_mbx_fw.h"
      15                 :            : #include "base/rnp_mac.h"
      16                 :            : #include "base/rnp_eth_regs.h"
      17                 :            : #include "base/rnp_common.h"
      18                 :            : #include "base/rnp_dma_regs.h"
      19                 :            : #include "base/rnp_mac_regs.h"
      20                 :            : #include "rnp_rxtx.h"
      21                 :            : #include "rnp_rss.h"
      22                 :            : #include "rnp_link.h"
      23                 :            : 
      24                 :            : static int rnp_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
      25                 :            : static struct rte_eth_dev *
      26                 :          0 : rnp_alloc_eth_port(struct rte_pci_device *pci, char *name)
      27                 :            : {
      28                 :            :         struct rte_eth_dev *eth_dev = NULL;
      29                 :            :         struct rnp_eth_port *port = NULL;
      30                 :            : 
      31                 :          0 :         eth_dev = rte_eth_dev_allocate(name);
      32         [ #  # ]:          0 :         if (!eth_dev) {
      33                 :          0 :                 RNP_PMD_ERR("Could not allocate eth_dev for %s", name);
      34                 :          0 :                 return NULL;
      35                 :            :         }
      36                 :          0 :         port = rte_zmalloc_socket(name,
      37                 :            :                         sizeof(*port),
      38                 :            :                         RTE_CACHE_LINE_SIZE,
      39                 :            :                         pci->device.numa_node);
      40         [ #  # ]:          0 :         if (!port) {
      41                 :          0 :                 RNP_PMD_ERR("Could not allocate rnp_eth_port for %s", name);
      42                 :          0 :                 goto fail_calloc;
      43                 :            :         }
      44                 :          0 :         rte_eth_copy_pci_info(eth_dev, pci);
      45                 :          0 :         eth_dev->data->dev_private = port;
      46                 :          0 :         eth_dev->device = &pci->device;
      47                 :            : 
      48                 :          0 :         return eth_dev;
      49                 :            : fail_calloc:
      50                 :          0 :         rte_free(port);
      51                 :          0 :         rte_eth_dev_release_port(eth_dev);
      52                 :            : 
      53                 :          0 :         return NULL;
      54                 :            : }
      55                 :            : 
      56                 :            : static int
      57                 :          0 : rnp_mbx_fw_reply_handler(struct rnp_eth_adapter *adapter,
      58                 :            :                          void *cmd)
      59                 :            : {
      60                 :            :         struct rnp_mbx_fw_cmd_reply *reply = cmd;
      61                 :            :         struct rnp_mbx_req_cookie *cookie;
      62                 :            : 
      63                 :            :         RTE_SET_USED(adapter);
      64                 :            :         /* dbg_here; */
      65                 :          0 :         cookie = reply->cookie;
      66   [ #  #  #  # ]:          0 :         if (!cookie || cookie->magic != RNP_COOKIE_MAGIC) {
      67                 :          0 :                 RNP_PMD_ERR("invalid cookie:%p opcode:0x%x v0:0x%x",
      68                 :            :                                 cookie, reply->opcode, *((int *)reply));
      69                 :          0 :                 return -EIO;
      70                 :            :         }
      71         [ #  # ]:          0 :         if (cookie->priv_len > 0)
      72                 :          0 :                 memcpy(cookie->priv, reply->data, RNP_FW_REP_DATA_NUM);
      73                 :            : 
      74                 :          0 :         cookie->done = 1;
      75         [ #  # ]:          0 :         if (reply->flags & RNP_FLAGS_ERR)
      76                 :          0 :                 cookie->errcode = reply->error_code;
      77                 :            :         else
      78                 :          0 :                 cookie->errcode = 0;
      79                 :            : 
      80                 :            :         return 0;
      81                 :            : }
      82                 :            : 
      83                 :            : static int rnp_mbx_fw_req_handler(struct rnp_eth_adapter *adapter,
      84                 :            :                                   void *cmd)
      85                 :            : {
      86                 :            :         struct rnp_mbx_fw_cmd_req *req = cmd;
      87                 :            : 
      88         [ #  # ]:          0 :         switch (req->opcode) {
      89                 :          0 :         case RNP_LINK_STATUS_EVENT:
      90                 :          0 :                 rnp_link_event(adapter, req);
      91                 :          0 :                 break;
      92                 :            :         default:
      93                 :            :                 break;
      94                 :            :         }
      95                 :            : 
      96                 :            :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :          0 : static int rnp_process_fw_msg(struct rnp_eth_adapter *adapter)
     100                 :            : {
     101                 :          0 :         const struct rnp_mbx_ops *ops = RNP_DEV_PP_TO_MBX_OPS(adapter->eth_dev);
     102                 :          0 :         struct rnp_hw *hw = &adapter->hw;
     103                 :            :         void *msg_cmd = NULL;
     104                 :            :         uint16_t msg_flag;
     105                 :            : 
     106                 :          0 :         msg_cmd = (void *)hw->msgbuf;
     107                 :            :         memset(msg_cmd, 0, sizeof(hw->msgbuf));
     108                 :            :         /* check fw req */
     109         [ #  # ]:          0 :         if (!ops->check_for_msg(hw, RNP_MBX_FW)) {
     110                 :          0 :                 rnp_rcv_msg_from_fw(adapter, msg_cmd);
     111                 :          0 :                 msg_flag = hw->msgbuf[2] | hw->msgbuf[3];
     112         [ #  # ]:          0 :                 if (msg_flag & RNP_FLAGS_DD)
     113                 :          0 :                         rnp_mbx_fw_reply_handler(adapter, msg_cmd);
     114                 :            :                 else
     115                 :            :                         rnp_mbx_fw_req_handler(adapter, msg_cmd);
     116                 :            :         }
     117                 :            : 
     118                 :          0 :         return 0;
     119                 :            : }
     120                 :            : 
     121                 :          0 : static void rnp_dev_interrupt_handler(void *param)
     122                 :            : {
     123                 :            :         struct rnp_eth_adapter *adapter = param;
     124                 :            :         uint16_t exp = RNP_PF_OP_DONE;
     125                 :            : 
     126         [ #  # ]:          0 :         if (!rte_atomic_compare_exchange_strong_explicit(&adapter->pf_op, &exp,
     127                 :            :                         RNP_PF_OP_PROCESS, rte_memory_order_acquire,
     128                 :            :                         rte_memory_order_acquire))
     129                 :            :                 return;
     130                 :          0 :         rnp_process_fw_msg(adapter);
     131                 :          0 :         rte_atomic_store_explicit(&adapter->pf_op, RNP_PF_OP_DONE,
     132                 :            :                         rte_memory_order_release);
     133                 :            : }
     134                 :            : 
     135                 :          0 : static void rnp_mac_rx_enable(struct rte_eth_dev *dev)
     136                 :            : {
     137                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     138                 :          0 :         uint16_t lane = port->attr.nr_lane;
     139                 :          0 :         struct rnp_hw *hw = port->hw;
     140                 :            :         uint32_t mac_cfg;
     141                 :            : 
     142                 :          0 :         rte_spinlock_lock(&port->rx_mac_lock);
     143                 :          0 :         mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
     144                 :            :         mac_cfg |= RNP_MAC_RE;
     145                 :            : 
     146         [ #  # ]:          0 :         if (port->jumbo_en) {
     147                 :            :                 mac_cfg |= RNP_MAC_JE;
     148                 :          0 :                 mac_cfg |= RNP_MAC_GPSLCE | RNP_MAC_WD;
     149                 :            :         } else {
     150                 :            :                 mac_cfg &= ~RNP_MAC_JE;
     151                 :          0 :                 mac_cfg &= ~RNP_MAC_WD;
     152                 :            :         }
     153                 :          0 :         mac_cfg &= ~RNP_MAC_GPSL_MASK;
     154                 :          0 :         mac_cfg |= (RNP_MAC_MAX_GPSL << RNP_MAC_CPSL_SHIFT);
     155                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, mac_cfg);
     156                 :            :         rte_spinlock_unlock(&port->rx_mac_lock);
     157                 :          0 : }
     158                 :            : 
     159                 :          0 : static void rnp_mac_rx_disable(struct rte_eth_dev *dev)
     160                 :            : {
     161                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     162                 :          0 :         uint16_t lane = port->attr.nr_lane;
     163                 :          0 :         struct rnp_hw *hw = port->hw;
     164                 :            :         uint32_t mac_cfg;
     165                 :            : 
     166                 :            :         /* to protect conflict hw resource */
     167                 :          0 :         rte_spinlock_lock(&port->rx_mac_lock);
     168                 :          0 :         mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
     169                 :          0 :         mac_cfg &= ~RNP_MAC_RE;
     170                 :            : 
     171                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, mac_cfg);
     172                 :            :         rte_spinlock_unlock(&port->rx_mac_lock);
     173                 :          0 : }
     174                 :            : 
     175                 :            : static void rnp_mac_tx_enable(struct rte_eth_dev *dev)
     176                 :            : {
     177                 :            :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     178                 :            :         uint16_t lane = port->attr.nr_lane;
     179                 :            :         struct rnp_hw *hw = port->hw;
     180                 :            :         uint32_t mac_cfg;
     181                 :            : 
     182                 :          0 :         mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_TX_CFG);
     183                 :          0 :         mac_cfg |= RNP_MAC_TE;
     184                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_TX_CFG, mac_cfg);
     185                 :            : }
     186                 :            : 
     187                 :            : static void rnp_mac_tx_disable(struct rte_eth_dev *dev)
     188                 :            : {
     189                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     190                 :          0 :         uint16_t lane = port->attr.nr_lane;
     191                 :          0 :         struct rnp_hw *hw = port->hw;
     192                 :            :         uint32_t ctrl;
     193                 :            : 
     194                 :            :         /* must wait for tx side has send finish
     195                 :            :          * before fisable tx side
     196                 :            :          */
     197                 :          0 :         ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_TX_CFG);
     198                 :          0 :         ctrl &= ~RNP_MAC_TE;
     199                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_TX_CFG, ctrl);
     200                 :            : }
     201                 :            : 
     202                 :          0 : static void rnp_mac_init(struct rte_eth_dev *dev)
     203                 :            : {
     204                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     205                 :          0 :         uint16_t lane = port->attr.nr_lane;
     206                 :          0 :         struct rnp_hw *hw = port->hw;
     207                 :            :         uint32_t mac_cfg;
     208                 :            : 
     209                 :            :         rnp_mac_tx_enable(dev);
     210                 :          0 :         rnp_mac_rx_enable(dev);
     211                 :            : 
     212                 :          0 :         mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_LPI_CTRL);
     213                 :          0 :         mac_cfg |= RNP_MAC_PLSDIS | RNP_MAC_PLS;
     214                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_LPI_CTRL, mac_cfg);
     215                 :          0 : }
     216                 :            : 
     217                 :            : static int
     218                 :          0 : rnp_rx_scattered_setup(struct rte_eth_dev *dev)
     219                 :            : {
     220                 :          0 :         uint16_t max_pkt_size =
     221                 :          0 :                 dev->data->dev_conf.rxmode.mtu + RNP_ETH_OVERHEAD;
     222                 :            :         struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
     223                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     224                 :          0 :         struct rnp_hw *hw = port->hw;
     225                 :            :         struct rnp_rx_queue *rxq;
     226                 :            :         uint16_t dma_buf_size;
     227                 :            :         uint16_t queue_id;
     228                 :            :         uint32_t dma_ctrl;
     229                 :            : 
     230         [ #  # ]:          0 :         if (dev->data->rx_queues == NULL)
     231                 :            :                 return -ENOMEM;
     232         [ #  # ]:          0 :         for (queue_id = 0; queue_id < dev->data->nb_rx_queues; queue_id++) {
     233                 :          0 :                 rxq = dev->data->rx_queues[queue_id];
     234         [ #  # ]:          0 :                 if (!rxq)
     235                 :          0 :                         continue;
     236         [ #  # ]:          0 :                 if (hw->min_dma_size == 0)
     237                 :          0 :                         hw->min_dma_size = rxq->rx_buf_len;
     238                 :            :                 else
     239                 :          0 :                         hw->min_dma_size = RTE_MIN(hw->min_dma_size,
     240                 :            :                                         rxq->rx_buf_len);
     241                 :            :         }
     242         [ #  # ]:          0 :         if (hw->min_dma_size < RNP_MIN_DMA_BUF_SIZE) {
     243                 :          0 :                 RNP_PMD_ERR("port[%d] scatter dma len is not support %d",
     244                 :            :                                 dev->data->port_id, hw->min_dma_size);
     245                 :          0 :                 return -ENOTSUP;
     246                 :            :         }
     247                 :            :         dma_buf_size = hw->min_dma_size;
     248   [ #  #  #  # ]:          0 :         if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER ||
     249                 :          0 :                         max_pkt_size > dma_buf_size ||
     250         [ #  # ]:          0 :                         dev->data->mtu + RNP_ETH_OVERHEAD > dma_buf_size)
     251                 :          0 :                 dev->data->scattered_rx = 1;
     252                 :            :         else
     253                 :          0 :                 dev->data->scattered_rx = 0;
     254                 :            :         /* Setup max dma scatter engine split size */
     255         [ #  # ]:          0 :         if (max_pkt_size == dma_buf_size)
     256                 :          0 :                 dma_buf_size += (dma_buf_size % 16);
     257                 :          0 :         RNP_PMD_INFO("PF[%d] MaxPktLen %d MbSize %d MbHeadRoom %d",
     258                 :            :                         hw->mbx.pf_num, max_pkt_size,
     259                 :            :                         dma_buf_size, RTE_PKTMBUF_HEADROOM);
     260                 :          0 :         dma_ctrl = RNP_E_REG_RD(hw,  RNP_DMA_CTRL);
     261                 :          0 :         dma_ctrl &= ~RNP_DMA_SCATTER_MEM_MASK;
     262                 :          0 :         dma_ctrl |= ((dma_buf_size / 16) << RNP_DMA_SCATTER_MEN_S);
     263                 :          0 :         RNP_E_REG_WR(hw, RNP_DMA_CTRL, dma_ctrl);
     264                 :            : 
     265                 :          0 :         return 0;
     266                 :            : }
     267                 :            : 
     268                 :          0 : static int rnp_enable_all_rx_queue(struct rte_eth_dev *dev)
     269                 :            : {
     270                 :            :         struct rnp_rx_queue *rxq;
     271                 :            :         uint16_t idx;
     272                 :            :         int ret = 0;
     273                 :            : 
     274         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
     275                 :          0 :                 rxq = dev->data->rx_queues[idx];
     276   [ #  #  #  # ]:          0 :                 if (!rxq || rxq->rx_deferred_start)
     277                 :          0 :                         continue;
     278         [ #  # ]:          0 :                 if (dev->data->rx_queue_state[idx] ==
     279                 :            :                                 RTE_ETH_QUEUE_STATE_STOPPED) {
     280                 :          0 :                         ret = rnp_rx_queue_start(dev, idx);
     281         [ #  # ]:          0 :                         if (ret < 0)
     282                 :          0 :                                 return ret;
     283                 :            :                 }
     284                 :            :         }
     285                 :            : 
     286                 :            :         return ret;
     287                 :            : }
     288                 :            : 
     289                 :          0 : static int rnp_enable_all_tx_queue(struct rte_eth_dev *dev)
     290                 :            : {
     291                 :            :         struct rnp_tx_queue *txq;
     292                 :            :         uint16_t idx;
     293                 :            :         int ret = 0;
     294                 :            : 
     295         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
     296                 :          0 :                 txq = dev->data->tx_queues[idx];
     297   [ #  #  #  # ]:          0 :                 if (!txq || txq->tx_deferred_start)
     298                 :          0 :                         continue;
     299         [ #  # ]:          0 :                 if (dev->data->tx_queue_state[idx] ==
     300                 :            :                                 RTE_ETH_QUEUE_STATE_STOPPED) {
     301                 :          0 :                         ret = rnp_tx_queue_start(dev, idx);
     302         [ #  # ]:          0 :                         if (ret < 0)
     303                 :          0 :                                 return ret;
     304                 :            :                 }
     305                 :            :         }
     306                 :            : 
     307                 :            :         return ret;
     308                 :            : }
     309                 :            : 
     310                 :            : static void
     311                 :          0 : rnp_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
     312                 :            :                          int on)
     313                 :            : {
     314                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     315                 :            :         struct rnp_rx_queue *rxq = NULL;
     316                 :          0 :         struct rnp_hw *hw = port->hw;
     317                 :            :         uint16_t index;
     318                 :            :         uint32_t reg;
     319                 :            : 
     320                 :          0 :         rxq = dev->data->rx_queues[queue];
     321         [ #  # ]:          0 :         if (rxq) {
     322                 :          0 :                 index = rxq->attr.index;
     323                 :          0 :                 reg = RNP_E_REG_RD(hw, RNP_VLAN_Q_STRIP_CTRL(index));
     324         [ #  # ]:          0 :                 if (on) {
     325                 :          0 :                         reg |= 1 << (index % 32);
     326                 :          0 :                         rxq->rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
     327                 :            :                 } else {
     328                 :          0 :                         reg &= ~(1 << (index % 32));
     329                 :          0 :                         rxq->rx_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
     330                 :            :                 }
     331                 :          0 :                 RNP_E_REG_WR(hw, RNP_VLAN_Q_STRIP_CTRL(index), reg);
     332                 :            :         }
     333                 :          0 : }
     334                 :            : 
     335                 :            : static void
     336                 :          0 : rnp_vlan_strip_enable(struct rnp_eth_port *port, bool en)
     337                 :            : {
     338                 :            :         int i = 0;
     339                 :            : 
     340         [ #  # ]:          0 :         for (i = 0; i < port->eth_dev->data->nb_rx_queues; i++) {
     341         [ #  # ]:          0 :                 if (port->eth_dev->data->rx_queues[i] == NULL) {
     342                 :          0 :                         RNP_PMD_ERR("Strip queue[%d] is NULL.", i);
     343                 :          0 :                         continue;
     344                 :            :                 }
     345                 :          0 :                 rnp_vlan_strip_queue_set(port->eth_dev, i, en);
     346                 :            :         }
     347                 :          0 : }
     348                 :            : 
     349                 :            : static void
     350                 :            : rnp_double_vlan_enable(struct rnp_eth_port *port, bool on)
     351                 :            : {
     352                 :          0 :         uint16_t lane = port->attr.nr_lane;
     353                 :          0 :         struct rnp_hw *hw = port->hw;
     354                 :            :         uint32_t ctrl;
     355                 :            : 
     356                 :            :         /* En Double Vlan Engine */
     357                 :          0 :         ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_TAG);
     358         [ #  # ]:          0 :         if (on)
     359                 :          0 :                 ctrl |= RNP_MAC_VLAN_EDVLP | RNP_MAC_VLAN_ESVL;
     360                 :            :         else
     361                 :          0 :                 ctrl &= ~(RNP_MAC_VLAN_EDVLP | RNP_MAC_VLAN_ESVL);
     362                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_TAG, ctrl);
     363                 :          0 : }
     364                 :            : 
     365                 :            : static int
     366                 :          0 : rnp_vlan_offload_set(struct rte_eth_dev *dev, int mask)
     367                 :            : {
     368                 :          0 :         struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
     369                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     370                 :            : 
     371         [ #  # ]:          0 :         if (mask & RTE_ETH_QINQ_STRIP_MASK) {
     372                 :          0 :                 RNP_PMD_ERR("QinQ Strip isn't supported.");
     373                 :          0 :                 return -ENOTSUP;
     374                 :            :         }
     375         [ #  # ]:          0 :         if (mask & RTE_ETH_VLAN_FILTER_MASK) {
     376         [ #  # ]:          0 :                 if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
     377                 :          0 :                         rnp_rx_vlan_filter_en(port, true);
     378                 :            :                 else
     379                 :            : 
     380                 :          0 :                         rnp_rx_vlan_filter_en(port, false);
     381                 :            :         }
     382         [ #  # ]:          0 :         if (mask & RTE_ETH_VLAN_STRIP_MASK) {
     383         [ #  # ]:          0 :                 if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
     384                 :          0 :                         rnp_vlan_strip_enable(port, true);
     385                 :            :                 else
     386                 :          0 :                         rnp_vlan_strip_enable(port, false);
     387                 :            :         }
     388         [ #  # ]:          0 :         if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
     389         [ #  # ]:          0 :                 if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
     390                 :            :                         rnp_double_vlan_enable(port, true);
     391                 :            :                 else
     392                 :            :                         rnp_double_vlan_enable(port, false);
     393                 :            :         }
     394                 :            : 
     395                 :            :         return 0;
     396                 :            : }
     397                 :            : 
     398                 :            : static int
     399                 :          0 : rnp_vlan_filter_set(struct rte_eth_dev *dev,
     400                 :            :                 uint16_t vlan_id, int on)
     401                 :            : {
     402                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     403                 :            : 
     404                 :          0 :         return rnp_update_vlan_filter(port, vlan_id, on);
     405                 :            : }
     406                 :            : 
     407                 :          0 : static int rnp_dev_start(struct rte_eth_dev *eth_dev)
     408                 :            : {
     409                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     410                 :            :         struct rte_eth_dev_data *data = eth_dev->data;
     411                 :          0 :         uint16_t max_rx_pkt_len = eth_dev->data->mtu;
     412                 :          0 :         bool lsc = data->dev_conf.intr_conf.lsc;
     413                 :          0 :         struct rnp_hw *hw = port->hw;
     414                 :            :         uint16_t lane = 0;
     415                 :            :         uint16_t idx = 0;
     416                 :            :         int ret = 0;
     417                 :            : 
     418                 :          0 :         PMD_INIT_FUNC_TRACE();
     419                 :          0 :         lane = port->attr.nr_lane;
     420                 :          0 :         ret = rnp_clock_valid_check(hw, lane);
     421         [ #  # ]:          0 :         if (ret) {
     422                 :          0 :                 RNP_PMD_ERR("port[%d] function[%d] lane[%d] hw clock error",
     423                 :            :                                 data->port_id, hw->mbx.pf_num, lane);
     424                 :          0 :                 return ret;
     425                 :            :         }
     426                 :            :         /* disable eth rx flow */
     427                 :          0 :         RNP_RX_ETH_DISABLE(hw, lane);
     428                 :          0 :         ret = rnp_dev_rss_configure(eth_dev);
     429         [ #  # ]:          0 :         if (ret)
     430                 :            :                 return ret;
     431                 :          0 :         ret = rnp_rx_scattered_setup(eth_dev);
     432         [ #  # ]:          0 :         if (ret)
     433                 :            :                 return ret;
     434                 :          0 :         ret = rnp_mtu_set(eth_dev, max_rx_pkt_len);
     435         [ #  # ]:          0 :         if (ret)
     436                 :            :                 return ret;
     437                 :          0 :         ret = rnp_enable_all_tx_queue(eth_dev);
     438         [ #  # ]:          0 :         if (ret)
     439                 :          0 :                 goto txq_start_failed;
     440                 :          0 :         ret = rnp_enable_all_rx_queue(eth_dev);
     441         [ #  # ]:          0 :         if (ret)
     442                 :          0 :                 goto rxq_start_failed;
     443                 :          0 :         rnp_mac_init(eth_dev);
     444                 :          0 :         ret = rnp_mbx_fw_lane_link_event_en(port, lsc);
     445         [ #  # ]:          0 :         if (ret < 0)
     446                 :          0 :                 goto rxq_start_failed;
     447         [ #  # ]:          0 :         if (!lsc)
     448                 :          0 :                 rnp_run_link_poll_task(port);
     449                 :          0 :         ret = rnp_dev_set_link_up(eth_dev);
     450         [ #  # ]:          0 :         if (ret < 0)
     451                 :          0 :                 goto rxq_start_failed;
     452                 :            :         /* enable eth rx flow */
     453                 :          0 :         RNP_RX_ETH_ENABLE(hw, lane);
     454                 :          0 :         rnp_rx_func_select(eth_dev);
     455                 :          0 :         rnp_tx_func_select(eth_dev);
     456                 :          0 :         port->port_stopped = 0;
     457                 :            : 
     458                 :          0 :         return 0;
     459                 :          0 : rxq_start_failed:
     460         [ #  # ]:          0 :         for (idx = 0; idx < data->nb_rx_queues; idx++)
     461                 :          0 :                 rnp_rx_queue_stop(eth_dev, idx);
     462                 :          0 : txq_start_failed:
     463         [ #  # ]:          0 :         for (idx = 0; idx < data->nb_tx_queues; idx++)
     464                 :          0 :                 rnp_tx_queue_stop(eth_dev, idx);
     465                 :            : 
     466                 :            :         return ret;
     467                 :            : }
     468                 :            : 
     469                 :          0 : static int rnp_disable_all_rx_queue(struct rte_eth_dev *dev)
     470                 :            : {
     471                 :            :         struct rnp_rx_queue *rxq;
     472                 :            :         uint16_t idx;
     473                 :            :         int ret = 0;
     474                 :            : 
     475         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
     476                 :          0 :                 rxq = dev->data->rx_queues[idx];
     477   [ #  #  #  # ]:          0 :                 if (!rxq || rxq->rx_deferred_start)
     478                 :          0 :                         continue;
     479         [ #  # ]:          0 :                 if (dev->data->rx_queue_state[idx] ==
     480                 :            :                                 RTE_ETH_QUEUE_STATE_STARTED) {
     481                 :          0 :                         ret = rnp_rx_queue_stop(dev, idx);
     482         [ #  # ]:          0 :                         if (ret < 0)
     483                 :          0 :                                 return ret;
     484                 :            :                 }
     485                 :            :         }
     486                 :            : 
     487                 :            :         return ret;
     488                 :            : }
     489                 :            : 
     490                 :          0 : static int rnp_disable_all_tx_queue(struct rte_eth_dev *dev)
     491                 :            : {
     492                 :            :         struct rnp_tx_queue *txq;
     493                 :            :         uint16_t idx;
     494                 :            :         int ret = 0;
     495                 :            : 
     496         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
     497                 :          0 :                 txq = dev->data->tx_queues[idx];
     498   [ #  #  #  # ]:          0 :                 if (!txq || txq->tx_deferred_start)
     499                 :          0 :                         continue;
     500         [ #  # ]:          0 :                 if (dev->data->tx_queue_state[idx] ==
     501                 :            :                                 RTE_ETH_QUEUE_STATE_STARTED) {
     502                 :          0 :                         ret = rnp_tx_queue_stop(dev, idx);
     503         [ #  # ]:          0 :                         if (ret < 0)
     504                 :          0 :                                 return ret;
     505                 :            :                 }
     506                 :            :         }
     507                 :            : 
     508                 :            :         return ret;
     509                 :            : }
     510                 :            : 
     511                 :          0 : static void rnp_set_rx_cksum_offload(struct rte_eth_dev *dev)
     512                 :            : {
     513                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     514                 :          0 :         struct rnp_hw *hw = port->hw;
     515                 :            :         uint32_t cksum_ctrl;
     516                 :            :         uint64_t offloads;
     517                 :            : 
     518                 :          0 :         offloads = dev->data->dev_conf.rxmode.offloads;
     519                 :            :         cksum_ctrl = RNP_HW_CHECK_ERR_MASK;
     520                 :            :         /* enable rx checksum feature */
     521         [ #  # ]:          0 :         if (!rnp_pf_is_multiple_ports(hw->device_id)) {
     522         [ #  # ]:          0 :                 if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
     523                 :            :                         /* Tunnel Option Cksum L4_Option */
     524                 :            :                         cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR;
     525         [ #  # ]:          0 :                         if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
     526                 :            :                                                 RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
     527                 :            :                                 cksum_ctrl &= ~RNP_HW_INNER_L4_CKSUM_ERR;
     528                 :            :                         else
     529                 :            :                                 cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR;
     530                 :            :                 } else {
     531                 :            :                         /* no tunnel option cksum l4_option */
     532                 :            :                         cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR;
     533         [ #  # ]:          0 :                         if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
     534                 :            :                                                 RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
     535                 :            :                                 cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR;
     536                 :            :                         else
     537                 :            :                                 cksum_ctrl |= RNP_HW_L4_CKSUM_ERR;
     538                 :            :                 }
     539         [ #  # ]:          0 :                 if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
     540                 :            :                         /* tunnel option cksum l3_option */
     541                 :          0 :                         cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR;
     542         [ #  # ]:          0 :                         if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)
     543                 :          0 :                                 cksum_ctrl &= ~RNP_HW_INNER_L3_CKSUM_ERR;
     544                 :            :                         else
     545                 :          0 :                                 cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR;
     546                 :            :                 } else {
     547                 :            :                         /* no tunnel option cksum l3_option */
     548                 :            :                         cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR;
     549         [ #  # ]:          0 :                         if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)
     550                 :          0 :                                 cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR;
     551                 :            :                         else
     552                 :          0 :                                 cksum_ctrl |= RNP_HW_L3_CKSUM_ERR;
     553                 :            :                 }
     554                 :            :                 /* sctp option */
     555         [ #  # ]:          0 :                 if (offloads & RTE_ETH_RX_OFFLOAD_SCTP_CKSUM) {
     556                 :          0 :                         cksum_ctrl &= ~RNP_HW_SCTP_CKSUM_ERR;
     557                 :          0 :                         RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true);
     558                 :            :                 } else {
     559                 :          0 :                         RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, false);
     560                 :            :                 }
     561                 :          0 :                 RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, cksum_ctrl);
     562                 :            :         } else {
     563                 :            :                 /* Enabled all support checksum features
     564                 :            :                  * use software mode support per port rx checksum
     565                 :            :                  * feature enabled/disabled for multiple port mode
     566                 :            :                  */
     567                 :          0 :                 RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, RNP_HW_ERR_RX_ALL_MASK);
     568                 :          0 :                 RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true);
     569                 :            :         }
     570                 :          0 : }
     571                 :            : 
     572                 :            : static void
     573                 :          0 : rnp_qinq_insert_offload_en(struct rnp_eth_port *port, bool on)
     574                 :            : {
     575                 :          0 :         uint16_t lane = port->attr.nr_lane;
     576                 :          0 :         struct rnp_hw *hw = port->hw;
     577                 :            :         uint32_t cvlan_ctrl, svlan_ctrl;
     578                 :            : 
     579                 :            :         /* en double vlan engine */
     580                 :            :         rnp_double_vlan_enable(port, on);
     581                 :            :         /* setup inner vlan mode*/
     582                 :          0 :         cvlan_ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_INNER_VLAN_INCL);
     583         [ #  # ]:          0 :         if (on) {
     584                 :            :                 cvlan_ctrl |= RNP_MAC_VLAN_VLTI;
     585                 :          0 :                 cvlan_ctrl &= ~RNP_MAC_VLAN_CSVL;
     586         [ #  # ]:          0 :                 if (port->invlan_type == RNP_SVLAN_TYPE)
     587                 :          0 :                         cvlan_ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
     588                 :          0 :                 cvlan_ctrl &= ~RNP_MAC_VLAN_VLC;
     589                 :          0 :                 cvlan_ctrl |= RNP_MAC_VLAN_VLC_ADD;
     590                 :            :         } else {
     591                 :            :                 cvlan_ctrl = 0;
     592                 :            :         }
     593                 :            :         /* setup outer vlan mode */
     594                 :          0 :         svlan_ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_INCL);
     595         [ #  # ]:          0 :         if (on) {
     596                 :            :                 svlan_ctrl |= RNP_MAC_VLAN_VLTI;
     597                 :          0 :                 svlan_ctrl &= ~RNP_MAC_VLAN_CSVL;
     598         [ #  # ]:          0 :                 if (port->outvlan_type == RNP_SVLAN_TYPE)
     599                 :          0 :                         svlan_ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
     600                 :          0 :                 svlan_ctrl &= ~RNP_MAC_VLAN_VLC;
     601                 :          0 :                 svlan_ctrl |= RNP_MAC_VLAN_VLC_ADD;
     602                 :            :         } else {
     603                 :            :                 svlan_ctrl = 0;
     604                 :            :         }
     605                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_INNER_VLAN_INCL, cvlan_ctrl);
     606                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_INCL, svlan_ctrl);
     607                 :          0 : }
     608                 :            : 
     609                 :            : static void
     610                 :            : rnp_vlan_insert_offload_en(struct rnp_eth_port *port, bool on)
     611                 :            : {
     612                 :          0 :         uint16_t lane = port->attr.nr_lane;
     613                 :          0 :         struct rnp_hw *hw = port->hw;
     614                 :            :         uint32_t ctrl;
     615                 :            : 
     616                 :          0 :         ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_INCL);
     617                 :            :         if (on) {
     618                 :            :                 ctrl |= RNP_MAC_VLAN_VLTI;
     619                 :          0 :                 ctrl &= ~RNP_MAC_VLAN_CSVL;
     620         [ #  # ]:          0 :                 if (port->invlan_type == RNP_SVLAN_TYPE)
     621                 :          0 :                         ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
     622                 :          0 :                 ctrl &= ~RNP_MAC_VLAN_VLC;
     623                 :          0 :                 ctrl |= RNP_MAC_VLAN_VLC_ADD;
     624                 :            :         } else {
     625                 :            :                 ctrl = 0;
     626                 :            :         }
     627                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_INCL, ctrl);
     628                 :          0 : }
     629                 :            : 
     630                 :          0 : static int rnp_dev_configure(struct rte_eth_dev *eth_dev)
     631                 :            : {
     632                 :          0 :         struct rte_eth_txmode *txmode = &eth_dev->data->dev_conf.txmode;
     633                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     634                 :            : 
     635         [ #  # ]:          0 :         if (txmode->offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT &&
     636                 :            :             txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT)
     637                 :          0 :                 rnp_qinq_insert_offload_en(port, true);
     638                 :            :         else
     639                 :          0 :                 rnp_qinq_insert_offload_en(port, false);
     640         [ #  # ]:          0 :         if (txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT &&
     641                 :            :             !(txmode->offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT))
     642                 :            :                 rnp_vlan_insert_offload_en(port, true);
     643         [ #  # ]:          0 :         if (!(txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT))
     644                 :            :                 rnp_vlan_insert_offload_en(port, false);
     645         [ #  # ]:          0 :         if (port->last_rx_num != eth_dev->data->nb_rx_queues)
     646                 :          0 :                 port->rxq_num_changed = true;
     647                 :            :         else
     648                 :          0 :                 port->rxq_num_changed = false;
     649                 :          0 :         port->last_rx_num = eth_dev->data->nb_rx_queues;
     650                 :          0 :         rnp_set_rx_cksum_offload(eth_dev);
     651                 :            : 
     652                 :          0 :         return 0;
     653                 :            : }
     654                 :            : 
     655                 :          0 : static int rnp_dev_stop(struct rte_eth_dev *eth_dev)
     656                 :            : {
     657                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     658                 :            :         const struct rte_eth_dev_data *data = eth_dev->data;
     659                 :          0 :         bool lsc = eth_dev->data->dev_conf.intr_conf.lsc;
     660                 :            :         struct rte_eth_link link;
     661                 :            :         int ret;
     662                 :            : 
     663         [ #  # ]:          0 :         if (port->port_stopped)
     664                 :            :                 return 0;
     665                 :          0 :         eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
     666                 :          0 :         eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
     667                 :          0 :         eth_dev->tx_pkt_prepare = rte_eth_pkt_burst_dummy;
     668                 :            : 
     669                 :            :         /* clear the recorded link status */
     670                 :            :         memset(&link, 0, sizeof(link));
     671                 :          0 :         rte_eth_linkstatus_set(eth_dev, &link);
     672                 :          0 :         rnp_dev_set_link_down(eth_dev);
     673                 :          0 :         ret = rnp_disable_all_tx_queue(eth_dev);
     674         [ #  # ]:          0 :         if (ret < 0) {
     675                 :          0 :                 RNP_PMD_ERR("port[%u] disable tx queue failed", data->port_id);
     676                 :          0 :                 return ret;
     677                 :            :         }
     678                 :          0 :         ret = rnp_disable_all_rx_queue(eth_dev);
     679         [ #  # ]:          0 :         if (ret < 0) {
     680                 :          0 :                 RNP_PMD_ERR("port[%u] disable rx queue failed", data->port_id);
     681                 :          0 :                 return ret;
     682                 :            :         }
     683                 :            :         rnp_mac_tx_disable(eth_dev);
     684                 :          0 :         rnp_mac_rx_disable(eth_dev);
     685         [ #  # ]:          0 :         if (!lsc)
     686                 :          0 :                 rnp_cancel_link_poll_task(port);
     687                 :          0 :         port->attr.link_ready = false;
     688                 :          0 :         port->attr.speed = 0;
     689                 :            : 
     690                 :          0 :         eth_dev->data->dev_started = 0;
     691                 :          0 :         port->port_stopped = 1;
     692                 :            : 
     693                 :          0 :         return 0;
     694                 :            : }
     695                 :            : 
     696                 :            : static void rnp_change_manage_port(struct rnp_eth_adapter *adapter)
     697                 :            : {
     698                 :            :         uint16_t idx = 0;
     699                 :            : 
     700                 :          0 :         adapter->eth_dev = NULL;
     701         [ #  # ]:          0 :         for (idx = 0; idx < adapter->inited_ports; idx++) {
     702         [ #  # ]:          0 :                 if (adapter->ports[idx])
     703                 :          0 :                         adapter->eth_dev = adapter->ports[idx]->eth_dev;
     704                 :            :         }
     705                 :            : }
     706                 :            : 
     707                 :          0 : static int rnp_dev_close(struct rte_eth_dev *eth_dev)
     708                 :            : {
     709                 :          0 :         struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(eth_dev);
     710                 :            :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     711                 :            :         uint16_t exp = RNP_PF_OP_DONE;
     712                 :            :         int ret = 0;
     713                 :            : 
     714                 :          0 :         PMD_INIT_FUNC_TRACE();
     715                 :            : 
     716         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
     717                 :            :                 return 0;
     718                 :          0 :         ret = rnp_dev_stop(eth_dev);
     719         [ #  # ]:          0 :         if (ret < 0)
     720                 :            :                 return ret;
     721                 :            :         do {
     722                 :          0 :                 ret = rte_atomic_compare_exchange_strong_explicit(&adapter->pf_op,
     723                 :            :                                 &exp, RNP_PF_OP_CLOSING, rte_memory_order_acquire,
     724                 :            :                                 rte_memory_order_acquire);
     725         [ #  # ]:          0 :         } while (!ret);
     726                 :          0 :         adapter->closed_ports++;
     727                 :          0 :         adapter->ports[port->attr.sw_id] = NULL;
     728   [ #  #  #  # ]:          0 :         if (adapter->intr_registered && adapter->eth_dev == eth_dev)
     729                 :            :                 rnp_change_manage_port(adapter);
     730         [ #  # ]:          0 :         if (adapter->closed_ports == adapter->inited_ports) {
     731                 :          0 :                 struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
     732         [ #  # ]:          0 :                 if (adapter->intr_registered) {
     733                 :            :                         /* disable uio irq before callback unregister */
     734                 :          0 :                         rte_intr_disable(pci_dev->intr_handle);
     735                 :          0 :                         rte_intr_callback_unregister(pci_dev->intr_handle,
     736                 :            :                                         rnp_dev_interrupt_handler,
     737                 :            :                                         (void *)eth_dev);
     738                 :          0 :                         adapter->intr_registered = false;
     739                 :            :                 }
     740                 :          0 :                 rnp_dma_mem_free(&adapter->hw, &adapter->hw.fw_info.mem);
     741                 :          0 :                 rte_free(adapter);
     742                 :            :         }
     743                 :          0 :         rte_atomic_store_explicit(&adapter->pf_op, RNP_PF_OP_DONE,
     744                 :            :                         rte_memory_order_release);
     745                 :            : 
     746                 :          0 :         return 0;
     747                 :            : }
     748                 :            : 
     749                 :            : static uint32_t
     750                 :          0 : rnp_get_speed_caps(struct rte_eth_dev *dev)
     751                 :            : {
     752                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     753                 :            :         uint32_t speed_cap = 0;
     754                 :            :         uint32_t i = 0, speed;
     755                 :            :         uint32_t support_link;
     756                 :            :         uint32_t link_types;
     757                 :            : 
     758                 :          0 :         support_link = port->attr.phy_meta.supported_link;
     759         [ #  # ]:          0 :         link_types = rte_popcount64(support_link);
     760         [ #  # ]:          0 :         if (!link_types)
     761                 :            :                 return 0;
     762         [ #  # ]:          0 :         for (i = 0; i < link_types; i++) {
     763         [ #  # ]:          0 :                 speed = ffs(support_link) - 1;
     764   [ #  #  #  #  :          0 :                 switch (RTE_BIT32(speed)) {
             #  #  #  #  
                      # ]
     765                 :          0 :                 case RNP_SPEED_CAP_10M_FULL:
     766                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_10M;
     767                 :          0 :                         break;
     768                 :          0 :                 case RNP_SPEED_CAP_100M_FULL:
     769                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_100M;
     770                 :          0 :                         break;
     771                 :          0 :                 case RNP_SPEED_CAP_1GB_FULL:
     772                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_1G;
     773                 :          0 :                         break;
     774                 :          0 :                 case RNP_SPEED_CAP_10GB_FULL:
     775                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_10G;
     776                 :          0 :                         break;
     777                 :          0 :                 case RNP_SPEED_CAP_40GB_FULL:
     778                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_40G;
     779                 :          0 :                         break;
     780                 :          0 :                 case RNP_SPEED_CAP_25GB_FULL:
     781                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_25G;
     782                 :          0 :                         break;
     783                 :          0 :                 case RNP_SPEED_CAP_10M_HALF:
     784                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_10M_HD;
     785                 :          0 :                         break;
     786                 :          0 :                 case RNP_SPEED_CAP_100M_HALF:
     787                 :          0 :                         speed_cap |= RTE_ETH_LINK_SPEED_100M_HD;
     788                 :          0 :                         break;
     789                 :            :                 default:
     790                 :            :                         speed_cap |= 0;
     791                 :            :                 }
     792                 :          0 :                 support_link &= ~RTE_BIT32(speed);
     793                 :            :         }
     794         [ #  # ]:          0 :         if (!port->attr.phy_meta.link_autoneg)
     795                 :          0 :                 speed_cap |= RTE_ETH_LINK_SPEED_FIXED;
     796                 :            : 
     797                 :            :         return speed_cap;
     798                 :            : }
     799                 :            : 
     800                 :          0 : static int rnp_dev_infos_get(struct rte_eth_dev *eth_dev,
     801                 :            :                              struct rte_eth_dev_info *dev_info)
     802                 :            : {
     803                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     804                 :            : 
     805                 :          0 :         PMD_INIT_FUNC_TRACE();
     806                 :            : 
     807                 :          0 :         dev_info->rx_desc_lim = (struct rte_eth_desc_lim){
     808                 :            :                 .nb_max = RNP_MAX_BD_COUNT,
     809                 :            :                 .nb_min = RNP_MIN_BD_COUNT,
     810                 :            :                 .nb_align = RNP_BD_ALIGN,
     811                 :            :                 .nb_seg_max = RNP_RX_MAX_SEG,
     812                 :            :                 .nb_mtu_seg_max = RNP_RX_MAX_MTU_SEG,
     813                 :            :         };
     814                 :          0 :         dev_info->tx_desc_lim = (struct rte_eth_desc_lim){
     815                 :            :                 .nb_max = RNP_MAX_BD_COUNT,
     816                 :            :                 .nb_min = RNP_MIN_BD_COUNT,
     817                 :            :                 .nb_align = RNP_BD_ALIGN,
     818                 :            :                 .nb_seg_max = RNP_TX_MAX_SEG,
     819                 :            :                 .nb_mtu_seg_max = RNP_TX_MAX_MTU_SEG,
     820                 :            :         };
     821                 :            : 
     822                 :          0 :         dev_info->max_rx_pktlen = RNP_MAC_MAXFRM_SIZE;
     823                 :          0 :         dev_info->min_mtu = RTE_ETHER_MIN_MTU;
     824                 :          0 :         dev_info->max_mtu = dev_info->max_rx_pktlen - RNP_ETH_OVERHEAD;
     825                 :          0 :         dev_info->min_rx_bufsize = RNP_MIN_DMA_BUF_SIZE;
     826                 :          0 :         dev_info->max_rx_queues = port->attr.max_rx_queues;
     827                 :          0 :         dev_info->max_tx_queues = port->attr.max_tx_queues;
     828                 :            :         /* mac filter info */
     829                 :          0 :         dev_info->max_mac_addrs = port->attr.max_mac_addrs;
     830                 :            :         /* for RSS offload just support four tuple */
     831                 :          0 :         dev_info->flow_type_rss_offloads = RNP_SUPPORT_RSS_OFFLOAD_ALL;
     832                 :          0 :         dev_info->hash_key_size = RNP_MAX_HASH_KEY_SIZE * sizeof(uint32_t);
     833                 :          0 :         dev_info->reta_size = RNP_RSS_INDIR_SIZE;
     834                 :            :         /* speed cap info */
     835                 :          0 :         dev_info->speed_capa = rnp_get_speed_caps(eth_dev);
     836                 :            :         /* per queue offload */
     837                 :          0 :         dev_info->rx_queue_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
     838                 :            :         /* rx support offload cap */
     839                 :            :         dev_info->rx_offload_capa = RNP_RX_CHECKSUM_SUPPORT |
     840                 :            :                                     RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
     841                 :            :                                     RTE_ETH_RX_OFFLOAD_SCATTER;
     842                 :          0 :         dev_info->rx_offload_capa |= dev_info->rx_queue_offload_capa;
     843                 :            :         /* tx support offload cap */
     844                 :          0 :         dev_info->tx_offload_capa = 0 |
     845                 :            :                                     RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
     846                 :            :                                     RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
     847                 :            :                                     RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
     848                 :            :                                     RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
     849                 :            :                                     RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
     850                 :            :                                     RTE_ETH_TX_OFFLOAD_TCP_TSO |
     851                 :            :                                     RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
     852                 :            :                                     RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
     853                 :            :                                     RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
     854                 :            :                                     RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
     855                 :            :                                     RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
     856                 :            :         /* default ring configure */
     857                 :          0 :         dev_info->default_rxportconf.burst_size = 32;
     858                 :          0 :         dev_info->default_txportconf.burst_size = 32;
     859                 :          0 :         dev_info->default_rxportconf.nb_queues = 1;
     860                 :          0 :         dev_info->default_txportconf.nb_queues = 1;
     861                 :          0 :         dev_info->default_rxportconf.ring_size = 256;
     862                 :          0 :         dev_info->default_txportconf.ring_size = 256;
     863                 :            :         /* default port configure */
     864                 :          0 :         dev_info->default_rxconf = (struct rte_eth_rxconf) {
     865                 :            :                 .rx_drop_en = 0,
     866                 :            :                 .rx_thresh = {
     867                 :            :                         .pthresh = RNP_RX_DESC_FETCH_TH,
     868                 :            :                         .hthresh = RNP_RX_DESC_FETCH_BURST,
     869                 :            :                 },
     870                 :            :                 .rx_free_thresh = RNP_DEFAULT_RX_FREE_THRESH,
     871                 :            :                 .offloads = 0,
     872                 :            :         };
     873                 :            : 
     874                 :          0 :         dev_info->default_txconf = (struct rte_eth_txconf) {
     875                 :            :                 .tx_thresh = {
     876                 :            :                         .pthresh = RNP_TX_DESC_FETCH_TH,
     877                 :            :                         .hthresh = RNP_TX_DESC_FETCH_BURST,
     878                 :            :                 },
     879                 :            :                 .tx_free_thresh = RNP_DEFAULT_TX_FREE_THRESH,
     880                 :            :                 .tx_rs_thresh = RNP_DEFAULT_TX_RS_THRESH,
     881                 :            :                 .offloads = 0,
     882                 :            :         };
     883                 :            : 
     884                 :          0 :         return 0;
     885                 :            : }
     886                 :            : 
     887                 :          0 : static int rnp_promiscuous_enable(struct rte_eth_dev *eth_dev)
     888                 :            : {
     889                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     890                 :            : 
     891                 :          0 :         PMD_INIT_FUNC_TRACE();
     892                 :            : 
     893                 :          0 :         return rnp_update_mpfm(port, RNP_MPF_MODE_PROMISC, 1);
     894                 :            : }
     895                 :            : 
     896                 :          0 : static int rnp_promiscuous_disable(struct rte_eth_dev *eth_dev)
     897                 :            : {
     898                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     899                 :            : 
     900                 :          0 :         PMD_INIT_FUNC_TRACE();
     901                 :            : 
     902                 :          0 :         return rnp_update_mpfm(port, RNP_MPF_MODE_PROMISC, 0);
     903                 :            : }
     904                 :            : 
     905                 :          0 : static int rnp_allmulticast_enable(struct rte_eth_dev *eth_dev)
     906                 :            : {
     907                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     908                 :            : 
     909                 :          0 :         PMD_INIT_FUNC_TRACE();
     910                 :            : 
     911                 :          0 :         return rnp_update_mpfm(port, RNP_MPF_MODE_ALLMULTI, 1);
     912                 :            : }
     913                 :            : 
     914                 :          0 : static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev)
     915                 :            : {
     916                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     917                 :            : 
     918                 :          0 :         PMD_INIT_FUNC_TRACE();
     919         [ #  # ]:          0 :         if (eth_dev->data->promiscuous == 1)
     920                 :            :                 return 0;
     921                 :          0 :         return rnp_update_mpfm(port, RNP_MPF_MODE_ALLMULTI, 0);
     922                 :            : }
     923                 :            : 
     924                 :            : static bool
     925                 :          0 : rnp_verify_pf_scatter(struct rnp_eth_adapter *adapter)
     926                 :            : {
     927                 :            :         struct rnp_hw *hw = &adapter->hw;
     928                 :            :         struct rte_eth_dev *eth_dev;
     929                 :            :         uint8_t i = 0;
     930                 :            : 
     931         [ #  # ]:          0 :         for (i = 0; i < hw->max_port_num; i++) {
     932         [ #  # ]:          0 :                 if (adapter->ports[i] == NULL)
     933                 :          0 :                         continue;
     934                 :          0 :                 eth_dev = adapter->ports[i]->eth_dev;
     935         [ #  # ]:          0 :                 if (eth_dev->data == NULL)
     936                 :          0 :                         continue;
     937                 :            :                 /* sub port of pf eth_dev state is not
     938                 :            :                  * started so the scatter_rx attr isn't
     939                 :            :                  * setup don't check this sub port.
     940                 :            :                  */
     941         [ #  # ]:          0 :                 if (!eth_dev->data->dev_started)
     942                 :          0 :                         continue;
     943         [ #  # ]:          0 :                 if (!eth_dev->data->scattered_rx)
     944                 :            :                         return false;
     945                 :            :         }
     946                 :            : 
     947                 :            :         return true;
     948                 :            : }
     949                 :            : 
     950                 :            : static int
     951                 :          0 : rnp_update_valid_mtu(struct rnp_eth_port *port, uint16_t *set_mtu)
     952                 :            : {
     953                 :          0 :         struct rnp_eth_adapter *adapter = port->hw->back;
     954                 :            :         struct rnp_eth_port *sub_port = NULL;
     955                 :            :         struct rnp_hw *hw = port->hw;
     956                 :            :         uint16_t origin_mtu = 0;
     957                 :            :         uint16_t mtu = 0;
     958                 :            :         uint8_t i = 0;
     959                 :            : 
     960         [ #  # ]:          0 :         if (hw->max_port_num == 1) {
     961                 :          0 :                 port->cur_mtu = *set_mtu;
     962                 :            : 
     963                 :          0 :                 return 0;
     964                 :            :         }
     965                 :          0 :         origin_mtu = port->cur_mtu;
     966                 :          0 :         port->cur_mtu = *set_mtu;
     967                 :            :         mtu = *set_mtu;
     968         [ #  # ]:          0 :         for (i = 0; i < hw->max_port_num; i++) {
     969                 :          0 :                 sub_port = adapter->ports[i];
     970         [ #  # ]:          0 :                 if (sub_port == NULL)
     971                 :          0 :                         continue;
     972                 :          0 :                 mtu = RTE_MAX(mtu, sub_port->cur_mtu);
     973                 :            :         }
     974         [ #  # ]:          0 :         if (hw->max_port_num > 1 &&
     975         [ #  # ]:          0 :                         mtu + RNP_ETH_OVERHEAD > hw->min_dma_size) {
     976         [ #  # ]:          0 :                 if (!rnp_verify_pf_scatter(adapter)) {
     977                 :          0 :                         RNP_PMD_ERR("single pf multiple port max_frame_sz "
     978                 :            :                                         "is bigger than min_dma_size please "
     979                 :            :                                         "stop all pf port before set mtu.");
     980                 :          0 :                         port->cur_mtu = origin_mtu;
     981                 :          0 :                         return -EINVAL;
     982                 :            :                 }
     983                 :            :         }
     984                 :          0 :         *set_mtu = mtu;
     985                 :            : 
     986                 :          0 :         return 0;
     987                 :            : }
     988                 :            : 
     989                 :            : static int
     990                 :          0 : rnp_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
     991                 :            : {
     992                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     993                 :          0 :         uint32_t frame_size = mtu + RNP_ETH_OVERHEAD;
     994                 :          0 :         uint16_t lane = port->attr.nr_lane;
     995                 :          0 :         struct rnp_hw *hw = port->hw;
     996                 :            :         bool jumbo_en = false;
     997                 :            :         uint32_t reg;
     998                 :            :         int ret = 0;
     999                 :            : 
    1000                 :          0 :         PMD_INIT_FUNC_TRACE();
    1001                 :            :         /* check that mtu is within the allowed range */
    1002         [ #  # ]:          0 :         if (frame_size < RTE_ETHER_MIN_LEN ||
    1003                 :            :                         frame_size > RNP_MAC_MAXFRM_SIZE) {
    1004                 :          0 :                 RNP_PMD_ERR("valid packet length must be "
    1005                 :            :                                 "range from %u to  %u, "
    1006                 :            :                                 "when Jumbo Frame Feature disabled",
    1007                 :            :                                 (uint32_t)RTE_ETHER_MIN_LEN,
    1008                 :            :                                 (uint32_t)RTE_ETHER_MAX_LEN);
    1009                 :          0 :                 return -EINVAL;
    1010                 :            :         }
    1011                 :            :         /*
    1012                 :            :          * Refuse mtu that requires the support of scattered packets
    1013                 :            :          * when this feature has not been enabled before.
    1014                 :            :          */
    1015         [ #  # ]:          0 :         if (dev->data->dev_started && !dev->data->scattered_rx &&
    1016         [ #  # ]:          0 :                         frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) {
    1017                 :          0 :                 RNP_PMD_ERR("port %d mtu update must be stopped "
    1018                 :            :                                 "before configuration when scatter rx off.",
    1019                 :            :                                 dev->data->port_id);
    1020                 :            : 
    1021                 :          0 :                 return -EBUSY;
    1022                 :            :         }
    1023                 :            :         /* For one pf multiple port the mtu we must set
    1024                 :            :          * the biggest mtu the ports selong to pf
    1025                 :            :          * because of the control button is only one
    1026                 :            :          */
    1027                 :          0 :         ret = rnp_update_valid_mtu(port, &mtu);
    1028         [ #  # ]:          0 :         if (ret < 0)
    1029                 :            :                 return ret;
    1030                 :          0 :         frame_size = mtu + RNP_ETH_OVERHEAD;
    1031         [ #  # ]:          0 :         if (frame_size > RTE_ETHER_MAX_LEN)
    1032                 :            :                 jumbo_en = true;
    1033                 :            :         /* setting the MTU */
    1034                 :          0 :         RNP_E_REG_WR(hw, RNP_MAX_FRAME_CTRL, frame_size);
    1035                 :          0 :         RNP_E_REG_WR(hw, RNP_MIN_FRAME_CTRL, 60);
    1036         [ #  # ]:          0 :         if (jumbo_en) {
    1037                 :            :                 /* To protect conflict hw resource */
    1038                 :          0 :                 rte_spinlock_lock(&port->rx_mac_lock);
    1039                 :          0 :                 reg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
    1040                 :          0 :                 reg |= RNP_MAC_JE;
    1041                 :          0 :                 RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, reg);
    1042                 :            :                 rte_spinlock_unlock(&port->rx_mac_lock);
    1043                 :            :         }
    1044                 :          0 :         port->jumbo_en = jumbo_en;
    1045                 :            : 
    1046                 :          0 :         return 0;
    1047                 :            : }
    1048                 :            : 
    1049                 :            : struct rte_rnp_xstats_name_off {
    1050                 :            :         char name[RTE_ETH_XSTATS_NAME_SIZE];
    1051                 :            :         uint32_t offset;
    1052                 :            :         uint32_t reg_base;
    1053                 :            :         bool hi_addr_en;
    1054                 :            : };
    1055                 :            : 
    1056                 :            : static const struct rte_rnp_xstats_name_off rte_rnp_rx_eth_stats_str[] = {
    1057                 :            :         {"rx_trans_drop", offsetof(struct rnp_hw_eth_stats,
    1058                 :            :                         rx_trans_drop), RNP_ETH_RXTRANS_DROP, false},
    1059                 :            :         {"rx_trunc_drop", offsetof(struct rnp_hw_eth_stats,
    1060                 :            :                         rx_trunc_drop), RNP_ETH_RXTRUNC_DROP, false},
    1061                 :            :         {"rx_undersize_err_packets", offsetof(struct rnp_hw_eth_stats,
    1062                 :            :                         rx_slen_drop), RNP_ETH_RXSLAN_DROP, false},
    1063                 :            :         {"rx_oversize_err_packets", offsetof(struct rnp_hw_eth_stats,
    1064                 :            :                         rx_glen_drop), RNP_ETH_RXGLAN_DROP, false},
    1065                 :            :         {"rx_iph_err_packet", offsetof(struct rnp_hw_eth_stats,
    1066                 :            :                         rx_cksum_e_drop), RNP_ETH_RXCKSUM_E_DROP, false},
    1067                 :            :         {"rx_cksum_err_packet", offsetof(struct rnp_hw_eth_stats,
    1068                 :            :                         rx_iph_e_drop), RNP_ETH_RXIPH_E_DROP, false},
    1069                 :            : };
    1070                 :            : 
    1071                 :            : static const struct rte_rnp_xstats_name_off rte_rnp_mac_stats_str[] = {
    1072                 :            :         {"rx_packets", offsetof(struct rnp_hw_mac_stats,
    1073                 :            :                         rx_all_pkts), RNP_MMC_RX_GBFRMB, true},
    1074                 :            :         {"rx_bytes", offsetof(struct rnp_hw_mac_stats,
    1075                 :            :                         rx_all_bytes), RNP_MMC_RX_GBOCTGB, true},
    1076                 :            :         {"rx_unicast_packets", offsetof(struct rnp_hw_mac_stats,
    1077                 :            :                         rx_unicast), RNP_MMC_RX_UCASTGB, true},
    1078                 :            :         {"rx_broadcast_packets", offsetof(struct rnp_hw_mac_stats,
    1079                 :            :                         rx_broadcast), RNP_MMC_RX_BCASTGB, true},
    1080                 :            :         {"rx_multicast_packets", offsetof(struct rnp_hw_mac_stats,
    1081                 :            :                         rx_multicast), RNP_MMC_RX_MCASTGB, true},
    1082                 :            :         {"rx_pause_packets", offsetof(struct rnp_hw_mac_stats,
    1083                 :            :                         rx_pause), RNP_MMC_RX_PAUSEB, true},
    1084                 :            :         {"rx_vlan_packets", offsetof(struct rnp_hw_mac_stats,
    1085                 :            :                         rx_vlan), RNP_MMC_RX_VLANGB, true},
    1086                 :            :         {"rx_64_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1087                 :            :                         rx_64octes_pkts), RNP_MMC_RX_64_BYTESB, true},
    1088                 :            :         {"rx_65_to_127_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1089                 :            :                         rx_65to127_octes_pkts), RNP_MMC_RX_65TO127_BYTESB, true},
    1090                 :            :         {"rx_128_to_255_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1091                 :            :                         rx_128to255_octes_pkts), RNP_MMC_RX_128TO255_BYTESB, true},
    1092                 :            :         {"rx_256_to_511_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1093                 :            :                         rx_256to511_octes_pkts), RNP_MMC_RX_256TO511_BYTESB, true},
    1094                 :            :         {"rx_512_to_1023_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1095                 :            :                         rx_512to1023_octes_pkts), RNP_MMC_RX_512TO1203_BYTESB, true},
    1096                 :            :         {"rx_1024_to_max_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1097                 :            :                         rx_1024tomax_octes_pkts), RNP_MMC_RX_1024TOMAX_BYTESB, true},
    1098                 :            :         {"rx_len_over_9k", offsetof(struct rnp_hw_mac_stats,
    1099                 :            :                         rx_oversize_9k), RNP_MMC_RX_OSIZEGB, false},
    1100                 :            :         {"rx_crc_errors", offsetof(struct rnp_hw_mac_stats,
    1101                 :            :                         rx_crc_err), RNP_MMC_RX_CRCERB, true},
    1102                 :            :         {"rx_crc_errors_small_packets", offsetof(struct rnp_hw_mac_stats,
    1103                 :            :                         rx_runt_err), RNP_MMC_RX_RUNTERB, false},
    1104                 :            :         {"rx_jabber_errors", offsetof(struct rnp_hw_mac_stats,
    1105                 :            :                         rx_jabber_err), RNP_MMC_RX_JABBER_ERR, false},
    1106                 :            :         {"rx_length_errors", offsetof(struct rnp_hw_mac_stats,
    1107                 :            :                         rx_len_err), RNP_MMC_RX_LENERRB, true},
    1108                 :            :         {"rx_out_of_range_errors", offsetof(struct rnp_hw_mac_stats,
    1109                 :            :                         rx_len_invalid), RNP_MMC_RX_OUTOF_RANGE, true},
    1110                 :            :         {"rx_watchdog_errors", offsetof(struct rnp_hw_mac_stats,
    1111                 :            :                         rx_watchdog_err), RNP_MMC_RX_WDOGERRB, true},
    1112                 :            : 
    1113                 :            :         {"tx_packets", offsetof(struct rnp_hw_mac_stats,
    1114                 :            :                         tx_all_pkts), RNP_MMC_TX_GBFRMB, true},
    1115                 :            :         {"tx_bytes", offsetof(struct rnp_hw_mac_stats,
    1116                 :            :                         tx_all_bytes), RNP_MMC_TX_GBOCTGB, true},
    1117                 :            :         {"tx_unicast_packets", offsetof(struct rnp_hw_mac_stats,
    1118                 :            :                         tx_all_unicast), RNP_MMC_TX_GBUCASTB, true},
    1119                 :            :         {"tx_broadcast_packets", offsetof(struct rnp_hw_mac_stats,
    1120                 :            :                         tx_all_broadcast), RNP_MMC_TX_BCASTB, true},
    1121                 :            :         {"tx_multicast_packets", offsetof(struct rnp_hw_mac_stats,
    1122                 :            :                         tx_all_multicast), RNP_MMC_TX_MCASTB, true},
    1123                 :            :         {"tx_vlan_packets", offsetof(struct rnp_hw_mac_stats,
    1124                 :            :                         tx_vlan_pkts), RNP_MMC_TX_VLANB, true},
    1125                 :            :         {"tx_pause_packets", offsetof(struct rnp_hw_mac_stats,
    1126                 :            :                         tx_pause_pkts), RNP_MMC_TX_PAUSEB, true},
    1127                 :            :         {"tx_64_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1128                 :            :                         tx_64octes_pkts), RNP_MMC_TX_64_BYTESB, true},
    1129                 :            :         {"tx_65_to_127_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1130                 :            :                         tx_65to127_octes_pkts), RNP_MMC_TX_65TO127_BYTESB, true},
    1131                 :            :         {"tx_128_to_255_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1132                 :            :                         tx_128to255_octes_pkts), RNP_MMC_TX_128TO255_BYTEB, true},
    1133                 :            :         {"tx_256_to_511_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1134                 :            :                         tx_256to511_octes_pkts), RNP_MMC_TX_256TO511_BYTEB, true},
    1135                 :            :         {"tx_512_to_1023_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1136                 :            :                         tx_512to1023_octes_pkts), RNP_MMC_TX_512TO1023_BYTEB, true},
    1137                 :            :         {"tx_1024_to_max_byte_packets", offsetof(struct rnp_hw_mac_stats,
    1138                 :            :                         tx_1024tomax_octes_pkts), RNP_MMC_TX_1024TOMAX_BYTEB, true},
    1139                 :            :         {"tx_underflow_errors", offsetof(struct rnp_hw_mac_stats,
    1140                 :            :                         tx_underflow_err), RNP_MMC_TX_UNDRFLWB, true},
    1141                 :            : };
    1142                 :            : 
    1143                 :            : #define RNP_NB_HW_MAC_STATS (RTE_DIM(rte_rnp_mac_stats_str))
    1144                 :            : #define RNP_NB_RX_HW_ETH_STATS (RTE_DIM(rte_rnp_rx_eth_stats_str))
    1145                 :            : #define RNP_GET_E_HW_COUNT(stats, offset)            \
    1146                 :            :         ((uint64_t *)(((char *)(stats)) + (offset)))
    1147                 :            : #define RNP_ADD_INCL_COUNT(stats, offset, val)       \
    1148                 :            :         ((*(RNP_GET_E_HW_COUNT((stats), (offset)))) += (val))
    1149                 :            : static inline void
    1150                 :            : rnp_store_hw_stats(struct rnp_hw_mac_stats *stats,
    1151                 :            :                    uint32_t offset, uint64_t val)
    1152                 :            : {
    1153                 :          0 :         *(uint64_t *)(((char *)stats) + offset) = val;
    1154                 :          0 : }
    1155                 :            : 
    1156                 :            : static int rnp_dev_cal_xstats_num(void)
    1157                 :            : {
    1158                 :            :         int cnt = RNP_NB_HW_MAC_STATS + RNP_NB_RX_HW_ETH_STATS;
    1159                 :            : 
    1160                 :            :         return cnt;
    1161                 :            : }
    1162                 :            : 
    1163                 :            : static inline void
    1164                 :            : rnp_update_eth_stats_32bit(struct rnp_hw_eth_stats *new,
    1165                 :            :                            struct rnp_hw_eth_stats *old,
    1166                 :            :                            uint32_t offset, uint32_t val)
    1167                 :            : {
    1168                 :            :         uint64_t *last_count = NULL;
    1169                 :            : 
    1170                 :          0 :         last_count = RNP_GET_E_HW_COUNT(old, offset);
    1171                 :          0 :         if (val >= *last_count)
    1172                 :          0 :                 RNP_ADD_INCL_COUNT(new, offset, val - (*last_count));
    1173                 :            :         else
    1174                 :          0 :                 RNP_ADD_INCL_COUNT(new, offset, val + UINT32_MAX);
    1175                 :          0 :         *last_count = val;
    1176                 :          0 : }
    1177                 :            : 
    1178                 :          0 : static void rnp_get_eth_count(struct rnp_hw *hw,
    1179                 :            :                               uint16_t lane,
    1180                 :            :                               struct rnp_hw_eth_stats *new,
    1181                 :            :                               struct rnp_hw_eth_stats *old,
    1182                 :            :                               const struct rte_rnp_xstats_name_off *ptr)
    1183                 :            : {
    1184                 :            :         uint64_t val = 0;
    1185                 :            : 
    1186         [ #  # ]:          0 :         if (ptr->reg_base) {
    1187                 :          0 :                 val = RNP_E_REG_RD(hw, ptr->reg_base + 0x40 * lane);
    1188         [ #  # ]:          0 :                 rnp_update_eth_stats_32bit(new, old, ptr->offset, val);
    1189                 :            :         }
    1190                 :          0 : }
    1191                 :            : 
    1192                 :            : static void
    1193                 :          0 : rnp_get_mmc_info(struct rnp_hw *hw,
    1194                 :            :                  uint16_t lane,
    1195                 :            :                  struct rnp_hw_mac_stats *stats,
    1196                 :            :                  const struct rte_rnp_xstats_name_off *ptr)
    1197                 :            : {
    1198                 :            :         uint64_t count = 0;
    1199                 :            :         uint32_t offset;
    1200                 :            :         uint64_t hi_reg;
    1201                 :            : 
    1202         [ #  # ]:          0 :         if (ptr->reg_base) {
    1203                 :          0 :                 count = RNP_MAC_REG_RD(hw, lane, ptr->reg_base);
    1204         [ #  # ]:          0 :                 if (ptr->hi_addr_en) {
    1205                 :          0 :                         offset = ptr->reg_base + 4;
    1206                 :          0 :                         hi_reg = RNP_MAC_REG_RD(hw, lane, offset);
    1207                 :          0 :                         count += (hi_reg << 32);
    1208                 :            :                 }
    1209                 :          0 :                 rnp_store_hw_stats(stats, ptr->offset, count);
    1210                 :            :         }
    1211                 :          0 : }
    1212                 :            : 
    1213                 :          0 : static void rnp_get_hw_stats(struct rte_eth_dev *dev)
    1214                 :            : {
    1215                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1216                 :          0 :         struct rnp_hw_eth_stats *old = &port->eth_stats_old;
    1217                 :          0 :         struct rnp_hw_eth_stats *new = &port->eth_stats;
    1218                 :          0 :         struct rnp_hw_mac_stats *stats = &port->mac_stats;
    1219                 :            :         const struct rte_rnp_xstats_name_off *ptr;
    1220                 :          0 :         uint16_t lane = port->attr.nr_lane;
    1221                 :          0 :         struct rnp_hw *hw = port->hw;
    1222                 :            :         uint32_t i;
    1223                 :            : 
    1224         [ #  # ]:          0 :         for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
    1225                 :          0 :                 ptr = &rte_rnp_rx_eth_stats_str[i];
    1226                 :          0 :                 rnp_get_eth_count(hw, lane, new, old, ptr);
    1227                 :            :         }
    1228         [ #  # ]:          0 :         for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
    1229                 :          0 :                 ptr = &rte_rnp_mac_stats_str[i];
    1230                 :          0 :                 rnp_get_mmc_info(hw, lane, stats, ptr);
    1231                 :            :         }
    1232                 :          0 : }
    1233                 :            : 
    1234                 :            : static int
    1235                 :          0 : rnp_dev_stats_get(struct rte_eth_dev *dev,
    1236                 :            :                   struct rte_eth_stats *stats)
    1237                 :            : {
    1238                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1239                 :            :         struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
    1240                 :            :         struct rnp_hw_mac_stats *mac_stats = &port->mac_stats;
    1241                 :            :         struct rte_eth_dev_data *data = dev->data;
    1242                 :            :         uint16_t i = 0;
    1243                 :            : 
    1244                 :          0 :         PMD_INIT_FUNC_TRACE();
    1245                 :          0 :         rnp_get_hw_stats(dev);
    1246                 :            : 
    1247         [ #  # ]:          0 :         for (i = 0; i < data->nb_rx_queues; i++) {
    1248                 :          0 :                 const struct rnp_rx_queue *rxq = dev->data->rx_queues[i];
    1249                 :            : 
    1250         [ #  # ]:          0 :                 if (!rxq)
    1251                 :          0 :                         continue;
    1252                 :          0 :                 stats->ipackets += rxq->stats.ipackets;
    1253                 :          0 :                 stats->ibytes += rxq->stats.ibytes;
    1254         [ #  # ]:          0 :                 if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
    1255                 :          0 :                         stats->q_ipackets[i] = rxq->stats.ipackets;
    1256                 :          0 :                         stats->q_ibytes[i] = rxq->stats.ibytes;
    1257                 :            :                 }
    1258                 :            :         }
    1259                 :            : 
    1260         [ #  # ]:          0 :         for (i = 0; i < data->nb_tx_queues; i++) {
    1261                 :          0 :                 const struct rnp_tx_queue *txq = dev->data->tx_queues[i];
    1262                 :            : 
    1263         [ #  # ]:          0 :                 if (!txq)
    1264                 :          0 :                         continue;
    1265                 :          0 :                 stats->opackets += txq->stats.opackets;
    1266                 :          0 :                 stats->obytes += txq->stats.obytes;
    1267                 :          0 :                 stats->oerrors += txq->stats.errors;
    1268         [ #  # ]:          0 :                 if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
    1269                 :          0 :                         stats->q_opackets[i] = txq->stats.opackets;
    1270                 :          0 :                         stats->q_obytes[i] = txq->stats.obytes;
    1271                 :            :                 }
    1272                 :            :         }
    1273                 :          0 :         stats->imissed = eth_stats->rx_trans_drop + eth_stats->rx_trunc_drop;
    1274                 :          0 :         stats->ierrors = mac_stats->rx_crc_err + mac_stats->rx_len_err;
    1275                 :          0 :         stats->ierrors += mac_stats->rx_watchdog_err;
    1276                 :          0 :         stats->oerrors += mac_stats->tx_underflow_err;
    1277                 :            : 
    1278                 :          0 :         return 0;
    1279                 :            : }
    1280                 :            : 
    1281                 :            : static int
    1282                 :          0 : rnp_dev_stats_reset(struct rte_eth_dev *dev)
    1283                 :            : {
    1284                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1285                 :          0 :         struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
    1286                 :            :         uint16_t idx;
    1287                 :            : 
    1288                 :          0 :         PMD_INIT_FUNC_TRACE();
    1289                 :            :         memset(eth_stats, 0, sizeof(*eth_stats));
    1290         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
    1291                 :          0 :                 struct rnp_rx_queue *rxq = dev->data->rx_queues[idx];
    1292                 :            : 
    1293         [ #  # ]:          0 :                 if (!rxq)
    1294                 :          0 :                         continue;
    1295                 :          0 :                 memset(&rxq->stats, 0, sizeof(struct rnp_queue_stats));
    1296                 :            :         }
    1297         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
    1298                 :          0 :                 struct rnp_tx_queue *txq = dev->data->tx_queues[idx];
    1299                 :            : 
    1300         [ #  # ]:          0 :                 if (!txq)
    1301                 :          0 :                         continue;
    1302                 :          0 :                 memset(&txq->stats, 0, sizeof(struct rnp_queue_stats));
    1303                 :            :         }
    1304                 :            : 
    1305                 :          0 :         return 0;
    1306                 :            : }
    1307                 :            : 
    1308                 :            : static inline uint64_t
    1309                 :            : rnp_get_statistic_value(void *stats_ptr, uint32_t offset)
    1310                 :            : {
    1311                 :          0 :         stats_ptr = (char *)stats_ptr + offset;
    1312                 :            : 
    1313                 :          0 :         return *((uint64_t *)stats_ptr);
    1314                 :            : }
    1315                 :            : 
    1316                 :            : static int
    1317                 :          0 : rnp_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
    1318                 :            :                    unsigned int n __rte_unused)
    1319                 :            : {
    1320                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1321                 :          0 :         struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
    1322                 :          0 :         struct rnp_hw_mac_stats *mac_stats = &port->mac_stats;
    1323                 :            :         int count = 0;
    1324                 :            :         uint32_t i;
    1325                 :            : 
    1326         [ #  # ]:          0 :         if (xstats != NULL) {
    1327                 :          0 :                 rnp_get_hw_stats(dev);
    1328         [ #  # ]:          0 :                 for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
    1329                 :          0 :                         xstats[count].value = rnp_get_statistic_value(eth_stats,
    1330                 :          0 :                                         rte_rnp_rx_eth_stats_str[i].offset);
    1331                 :          0 :                         xstats[count].id = count;
    1332                 :          0 :                         count++;
    1333                 :            :                 }
    1334         [ #  # ]:          0 :                 for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
    1335                 :          0 :                         xstats[count].value = rnp_get_statistic_value(mac_stats,
    1336                 :          0 :                                         rte_rnp_mac_stats_str[i].offset);
    1337                 :          0 :                         xstats[count].id = count;
    1338                 :          0 :                         count++;
    1339                 :            :                 }
    1340                 :            :         } else {
    1341                 :            :                 return rnp_dev_cal_xstats_num();
    1342                 :            :         }
    1343                 :            : 
    1344                 :            :         return count;
    1345                 :            : }
    1346                 :            : 
    1347                 :            : static int
    1348                 :          0 : rnp_dev_xstats_reset(struct rte_eth_dev *dev)
    1349                 :            : {
    1350                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1351                 :          0 :         uint16_t lane = port->attr.nr_lane;
    1352                 :          0 :         struct rnp_hw *hw = port->hw;
    1353                 :            :         uint32_t reg;
    1354                 :            : 
    1355                 :            :         /* set MMC reset hw counter when read event */
    1356                 :          0 :         reg = RNP_MAC_REG_RD(hw, lane, RNP_MMC_CTRL);
    1357                 :          0 :         reg |= RNP_MMC_RSTONRD;
    1358                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MMC_CTRL, reg);
    1359                 :            : 
    1360                 :          0 :         rnp_dev_stats_reset(dev);
    1361                 :          0 :         rnp_get_hw_stats(dev);
    1362                 :          0 :         reg = RNP_MAC_REG_RD(hw, lane, RNP_MMC_CTRL);
    1363                 :          0 :         reg &= ~RNP_MMC_RSTONRD;
    1364                 :          0 :         RNP_MAC_REG_WR(hw, lane, RNP_MMC_CTRL, reg);
    1365                 :            : 
    1366                 :          0 :         return 0;
    1367                 :            : }
    1368                 :            : 
    1369                 :            : static int
    1370                 :          0 : rnp_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
    1371                 :            :                          struct rte_eth_xstat_name *xstats_names,
    1372                 :            :                          __rte_unused unsigned int size)
    1373                 :            : {
    1374                 :            :         int count = 0;
    1375                 :            :         uint32_t i;
    1376                 :            : 
    1377         [ #  # ]:          0 :         if (xstats_names == NULL)
    1378                 :            :                 return rnp_dev_cal_xstats_num();
    1379                 :            : 
    1380         [ #  # ]:          0 :         for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
    1381                 :          0 :                 strlcpy(xstats_names[count].name,
    1382                 :            :                                 rte_rnp_rx_eth_stats_str[i].name,
    1383                 :            :                                 sizeof(xstats_names[count].name));
    1384                 :          0 :                 count++;
    1385                 :            :         }
    1386         [ #  # ]:          0 :         for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
    1387                 :          0 :                 strlcpy(xstats_names[count].name,
    1388                 :            :                                 rte_rnp_mac_stats_str[i].name,
    1389                 :            :                                 sizeof(xstats_names[count].name));
    1390                 :          0 :                 count++;
    1391                 :            :         }
    1392                 :            : 
    1393                 :            :         return count;
    1394                 :            : }
    1395                 :            : 
    1396                 :            : static int
    1397                 :          0 : rnp_dev_mac_addr_set(struct rte_eth_dev *dev,
    1398                 :            :                      struct rte_ether_addr *mac_addr)
    1399                 :            : {
    1400                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1401                 :            : 
    1402                 :          0 :         return rnp_set_macaddr(port, (u8 *)mac_addr, 0);
    1403                 :            : }
    1404                 :            : 
    1405                 :            : static int
    1406                 :          0 : rnp_dev_mac_addr_add(struct rte_eth_dev *dev,
    1407                 :            :                      struct rte_ether_addr *mac_addr,
    1408                 :            :                      uint32_t index,
    1409                 :            :                      uint32_t vmdq __rte_unused)
    1410                 :            : {
    1411                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1412                 :            : 
    1413         [ #  # ]:          0 :         if (index >= port->attr.max_mac_addrs) {
    1414                 :          0 :                 RNP_PMD_ERR("mac add index %u is of range", index);
    1415                 :          0 :                 return -EINVAL;
    1416                 :            :         }
    1417                 :            : 
    1418                 :          0 :         return rnp_set_macaddr(port, (u8 *)mac_addr, index);
    1419                 :            : }
    1420                 :            : 
    1421                 :            : static void
    1422                 :          0 : rnp_dev_mac_addr_remove(struct rte_eth_dev *dev,
    1423                 :            :                         uint32_t index)
    1424                 :            : {
    1425                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1426                 :            : 
    1427         [ #  # ]:          0 :         if (index >= port->attr.max_mac_addrs) {
    1428                 :          0 :                 RNP_PMD_ERR("mac add index %u is of range", index);
    1429                 :          0 :                 return;
    1430                 :            :         }
    1431                 :          0 :         rnp_clear_macaddr(port, index);
    1432                 :            : }
    1433                 :            : 
    1434                 :            : static int
    1435                 :          0 : rnp_dev_set_mc_addr_list(struct rte_eth_dev *dev,
    1436                 :            :                          struct rte_ether_addr *mc_addr_list,
    1437                 :            :                          uint32_t nb_mc_addr)
    1438                 :            : {
    1439                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
    1440                 :            :         uint32_t idx = 0;
    1441                 :            : 
    1442         [ #  # ]:          0 :         if (nb_mc_addr > port->attr.max_mc_mac_hash)
    1443                 :            :                 return -EINVAL;
    1444                 :          0 :         rnp_clear_mc_hash(port);
    1445         [ #  # ]:          0 :         for (idx = 0; idx < nb_mc_addr; idx++) {
    1446         [ #  # ]:          0 :                 if (!rte_is_multicast_ether_addr(&mc_addr_list[idx])) {
    1447                 :          0 :                         RNP_PMD_ERR("mc_list[%d] isn't a valid multicast", idx);
    1448                 :          0 :                         return -EINVAL;
    1449                 :            :                 }
    1450                 :            :         }
    1451         [ #  # ]:          0 :         for (idx = 0; idx < nb_mc_addr; idx++)
    1452                 :          0 :                 rnp_update_mc_hash(port, (uint8_t *)&mc_addr_list[idx]);
    1453                 :            : 
    1454                 :            :         return 0;
    1455                 :            : }
    1456                 :            : 
    1457                 :            : static uint32_t *rnp_support_ptypes_get(void)
    1458                 :            : {
    1459                 :            :         static uint32_t ptypes[] = {
    1460                 :            :                 RTE_PTYPE_L2_ETHER,
    1461                 :            :                 RTE_PTYPE_L2_ETHER_TIMESYNC,
    1462                 :            :                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
    1463                 :            :                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
    1464                 :            :                 RTE_PTYPE_L4_TCP,
    1465                 :            :                 RTE_PTYPE_L4_UDP,
    1466                 :            :                 RTE_PTYPE_L4_SCTP,
    1467                 :            :                 RTE_PTYPE_TUNNEL_VXLAN,
    1468                 :            :                 RTE_PTYPE_TUNNEL_GRE,
    1469                 :            :                 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
    1470                 :            :                 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
    1471                 :            :                 RTE_PTYPE_INNER_L4_TCP,
    1472                 :            :                 RTE_PTYPE_INNER_L4_UDP,
    1473                 :            :                 RTE_PTYPE_INNER_L4_SCTP,
    1474                 :            :                 RTE_PTYPE_UNKNOWN,
    1475                 :            :         };
    1476                 :            : 
    1477                 :            :         return ptypes;
    1478                 :            : }
    1479                 :            : 
    1480                 :            : static const uint32_t *
    1481                 :          0 : rnp_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
    1482                 :            :                              size_t *no_of_elements __rte_unused)
    1483                 :            : {
    1484                 :          0 :         return rnp_support_ptypes_get();
    1485                 :            : }
    1486                 :            : 
    1487                 :            : /* Features supported by this driver */
    1488                 :            : static const struct eth_dev_ops rnp_eth_dev_ops = {
    1489                 :            :         .dev_configure                = rnp_dev_configure,
    1490                 :            :         .dev_close                    = rnp_dev_close,
    1491                 :            :         .dev_start                    = rnp_dev_start,
    1492                 :            :         .dev_stop                     = rnp_dev_stop,
    1493                 :            :         .dev_infos_get                = rnp_dev_infos_get,
    1494                 :            : 
    1495                 :            :         /* PROMISC */
    1496                 :            :         .promiscuous_enable           = rnp_promiscuous_enable,
    1497                 :            :         .promiscuous_disable          = rnp_promiscuous_disable,
    1498                 :            :         .allmulticast_enable          = rnp_allmulticast_enable,
    1499                 :            :         .allmulticast_disable         = rnp_allmulticast_disable,
    1500                 :            : 
    1501                 :            :         .mtu_set                      = rnp_mtu_set,
    1502                 :            :         .rx_queue_setup               = rnp_rx_queue_setup,
    1503                 :            :         .rx_queue_release             = rnp_dev_rx_queue_release,
    1504                 :            :         .rx_queue_stop                = rnp_rx_queue_stop,
    1505                 :            :         .rx_queue_start               = rnp_rx_queue_start,
    1506                 :            :         .rxq_info_get                 = rnp_rx_queue_info_get,
    1507                 :            :         .rx_burst_mode_get            = rnp_rx_burst_mode_get,
    1508                 :            :         .tx_queue_setup               = rnp_tx_queue_setup,
    1509                 :            :         .tx_queue_release             = rnp_dev_tx_queue_release,
    1510                 :            :         .tx_queue_stop                = rnp_tx_queue_stop,
    1511                 :            :         .tx_queue_start               = rnp_tx_queue_start,
    1512                 :            :         .txq_info_get                 = rnp_tx_queue_info_get,
    1513                 :            :         .tx_burst_mode_get            = rnp_tx_burst_mode_get,
    1514                 :            :         /* rss impl */
    1515                 :            :         .reta_update                  = rnp_dev_rss_reta_update,
    1516                 :            :         .reta_query                   = rnp_dev_rss_reta_query,
    1517                 :            :         .rss_hash_update              = rnp_dev_rss_hash_update,
    1518                 :            :         .rss_hash_conf_get            = rnp_dev_rss_hash_conf_get,
    1519                 :            :         /* stats */
    1520                 :            :         .stats_get                    = rnp_dev_stats_get,
    1521                 :            :         .stats_reset                  = rnp_dev_stats_reset,
    1522                 :            :         .xstats_get                   = rnp_dev_xstats_get,
    1523                 :            :         .xstats_reset                 = rnp_dev_xstats_reset,
    1524                 :            :         .xstats_get_names             = rnp_dev_xstats_get_names,
    1525                 :            :         /* link impl */
    1526                 :            :         .link_update                  = rnp_dev_link_update,
    1527                 :            :         .dev_set_link_up              = rnp_dev_set_link_up,
    1528                 :            :         .dev_set_link_down            = rnp_dev_set_link_down,
    1529                 :            :         /* mac address filter */
    1530                 :            :         .mac_addr_set                 = rnp_dev_mac_addr_set,
    1531                 :            :         .mac_addr_add                 = rnp_dev_mac_addr_add,
    1532                 :            :         .mac_addr_remove              = rnp_dev_mac_addr_remove,
    1533                 :            :         .set_mc_addr_list             = rnp_dev_set_mc_addr_list,
    1534                 :            :         /* vlan offload */
    1535                 :            :         .vlan_offload_set             = rnp_vlan_offload_set,
    1536                 :            :         .vlan_strip_queue_set         = rnp_vlan_strip_queue_set,
    1537                 :            :         .vlan_filter_set              = rnp_vlan_filter_set,
    1538                 :            :         .dev_supported_ptypes_get     = rnp_dev_supported_ptypes_get,
    1539                 :            : };
    1540                 :            : 
    1541                 :            : static void
    1542                 :          0 : rnp_setup_port_attr(struct rnp_eth_port *port,
    1543                 :            :                     struct rte_eth_dev *eth_dev,
    1544                 :            :                     uint8_t sw_id)
    1545                 :            : {
    1546                 :            :         struct rnp_port_attr *attr = &port->attr;
    1547                 :          0 :         struct rnp_hw *hw = port->hw;
    1548                 :            :         uint32_t lane;
    1549                 :            : 
    1550                 :          0 :         PMD_INIT_FUNC_TRACE();
    1551                 :            : 
    1552                 :          0 :         lane = hw->phy_port_ids[sw_id] & (hw->max_port_num - 1);
    1553                 :          0 :         attr->port_id = eth_dev->data->port_id;
    1554                 :          0 :         attr->port_offset = RNP_E_REG_RD(hw, RNP_TC_PORT_OFFSET(lane));
    1555                 :          0 :         attr->nr_lane = lane;
    1556                 :          0 :         attr->sw_id = sw_id;
    1557                 :            : 
    1558                 :          0 :         attr->max_rx_queues = RNP_MAX_RX_QUEUE_NUM / hw->max_port_num;
    1559                 :          0 :         attr->max_tx_queues = RNP_MAX_TX_QUEUE_NUM / hw->max_port_num;
    1560                 :            : 
    1561         [ #  # ]:          0 :         if (hw->nic_mode > RNP_SINGLE_10G) {
    1562                 :          0 :                 attr->max_mac_addrs = RNP_PORT_MAX_MACADDR;
    1563                 :          0 :                 attr->max_uc_mac_hash = 0;
    1564                 :          0 :                 attr->max_mc_mac_hash = RNP_PORT_MAX_MC_MAC_SIZE;
    1565                 :          0 :                 attr->uc_hash_tb_size = 0;
    1566                 :          0 :                 attr->mc_hash_tb_size = RNP_PORT_MAX_MC_HASH_TB;
    1567                 :          0 :                 attr->hash_table_shift = RNP_PORT_HASH_SHIFT;
    1568                 :            :         } else {
    1569                 :          0 :                 attr->max_mac_addrs = RNP_MAX_MAC_ADDRS;
    1570                 :          0 :                 attr->max_uc_mac_hash = RNP_MAX_HASH_UC_MAC_SIZE;
    1571                 :          0 :                 attr->max_mc_mac_hash = RNP_MAX_HASH_MC_MAC_SIZE;
    1572                 :          0 :                 attr->uc_hash_tb_size = RNP_MAX_UC_HASH_TABLE;
    1573                 :          0 :                 attr->mc_hash_tb_size = RNP_MAC_MC_HASH_TABLE;
    1574                 :          0 :                 attr->hash_table_shift = 0;
    1575                 :            :         }
    1576                 :          0 :         port->outvlan_type = RNP_SVLAN_TYPE;
    1577                 :          0 :         port->invlan_type = RNP_CVLAN_TYPE;
    1578                 :            : 
    1579                 :          0 :         rnp_mbx_fw_get_lane_stat(port);
    1580                 :            : 
    1581                 :          0 :         RNP_PMD_INFO("PF[%d] SW-ETH-PORT[%d]<->PHY_LANE[%d]",
    1582                 :            :                         hw->mbx.pf_num, sw_id, lane);
    1583                 :          0 : }
    1584                 :            : 
    1585                 :            : static int
    1586                 :          0 : rnp_init_port_resource(struct rnp_eth_adapter *adapter,
    1587                 :            :                        struct rte_eth_dev *eth_dev,
    1588                 :            :                        char *name,
    1589                 :            :                        uint8_t p_id)
    1590                 :            : {
    1591                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
    1592                 :          0 :         struct rte_pci_device *pci_dev = adapter->pdev;
    1593                 :          0 :         char mac_str[RTE_ETHER_ADDR_FMT_SIZE] = " ";
    1594                 :            : 
    1595                 :          0 :         PMD_INIT_FUNC_TRACE();
    1596                 :            : 
    1597                 :          0 :         port->eth_dev = eth_dev;
    1598                 :          0 :         port->hw = &adapter->hw;
    1599                 :            : 
    1600                 :          0 :         eth_dev->dev_ops = &rnp_eth_dev_ops;
    1601                 :          0 :         eth_dev->device = &pci_dev->device;
    1602                 :          0 :         eth_dev->data->mtu = RTE_ETHER_MTU;
    1603                 :            : 
    1604                 :          0 :         rnp_setup_port_attr(port, eth_dev, p_id);
    1605                 :          0 :         eth_dev->data->mac_addrs = rte_zmalloc(name,
    1606                 :            :                         sizeof(struct rte_ether_addr) *
    1607                 :          0 :                         port->attr.max_mac_addrs, 0);
    1608         [ #  # ]:          0 :         if (!eth_dev->data->mac_addrs) {
    1609                 :          0 :                 RNP_PMD_ERR("zmalloc for mac failed! Exiting.");
    1610                 :          0 :                 return -ENOMEM;
    1611                 :            :         }
    1612                 :          0 :         rnp_get_mac_addr(port, port->mac_addr.addr_bytes);
    1613                 :          0 :         rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
    1614                 :          0 :                                         &port->mac_addr);
    1615                 :          0 :         RNP_PMD_INFO("get mac addr from firmware %s", mac_str);
    1616                 :            :         if (!rte_is_valid_assigned_ether_addr(&port->mac_addr)) {
    1617                 :          0 :                 RNP_PMD_WARN("get mac_addr is invalid, just use random");
    1618                 :          0 :                 rte_eth_random_addr(port->mac_addr.addr_bytes);
    1619                 :            :         }
    1620                 :          0 :         rte_ether_addr_copy(&port->mac_addr, &eth_dev->data->mac_addrs[0]);
    1621                 :          0 :         rnp_set_macaddr(port, (u8 *)&port->mac_addr, 0);
    1622                 :            : 
    1623                 :            :         rte_spinlock_init(&port->rx_mac_lock);
    1624                 :          0 :         adapter->ports[p_id] = port;
    1625                 :          0 :         adapter->inited_ports++;
    1626                 :            : 
    1627                 :          0 :         return 0;
    1628                 :            : }
    1629                 :            : 
    1630                 :            : static int
    1631                 :            : rnp_proc_priv_init(struct rte_eth_dev *dev)
    1632                 :            : {
    1633                 :            :         struct rnp_proc_priv *priv;
    1634                 :            : 
    1635                 :          0 :         priv = rte_zmalloc_socket("rnp_proc_priv",
    1636                 :            :                         sizeof(struct rnp_proc_priv),
    1637                 :            :                         RTE_CACHE_LINE_SIZE,
    1638                 :          0 :                         dev->device->numa_node);
    1639   [ #  #  #  # ]:          0 :         if (!priv)
    1640                 :            :                 return -ENOMEM;
    1641                 :          0 :         dev->process_private = priv;
    1642                 :            : 
    1643                 :            :         return 0;
    1644                 :            : }
    1645                 :            : 
    1646                 :            : static int
    1647                 :          0 : rnp_rx_reset_pool_setup(struct rnp_eth_adapter *adapter)
    1648                 :            : {
    1649                 :          0 :         struct rte_eth_dev *eth_dev = adapter->eth_dev;
    1650                 :            :         char name[RTE_MEMPOOL_NAMESIZE];
    1651                 :            : 
    1652                 :          0 :         snprintf(name, sizeof(name), "rx_reset_pool_%d:%d",
    1653                 :          0 :                         eth_dev->data->port_id, eth_dev->device->numa_node);
    1654                 :            : 
    1655                 :          0 :         adapter->reset_pool = rte_pktmbuf_pool_create(name, 2,
    1656                 :            :                         0, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
    1657                 :          0 :                         eth_dev->device->numa_node);
    1658         [ #  # ]:          0 :         if (adapter->reset_pool == NULL) {
    1659                 :          0 :                 RNP_PMD_ERR("mempool %s create failed", name);
    1660                 :          0 :                 return -ENOMEM;
    1661                 :            :         }
    1662                 :            : 
    1663                 :            :         return 0;
    1664                 :            : }
    1665                 :            : 
    1666                 :            : static int
    1667                 :          0 : rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
    1668                 :            : {
    1669                 :          0 :         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
    1670                 :          0 :         struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
    1671                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
    1672                 :          0 :         char name[RTE_ETH_NAME_MAX_LEN] = " ";
    1673                 :            :         struct rnp_eth_adapter *adapter;
    1674                 :            :         struct rte_eth_dev *sub_eth_dev;
    1675                 :            :         struct rnp_hw *hw;
    1676                 :            :         uint16_t p_id;
    1677                 :            :         int ret = -1;
    1678                 :            : 
    1679                 :          0 :         PMD_INIT_FUNC_TRACE();
    1680                 :            : 
    1681                 :          0 :         snprintf(name, sizeof(name), "rnp_adapter_%d", eth_dev->data->port_id);
    1682                 :          0 :         adapter = rte_zmalloc(name, sizeof(struct rnp_eth_adapter), 0);
    1683         [ #  # ]:          0 :         if (!adapter) {
    1684                 :          0 :                 RNP_PMD_ERR("rnp_adapter zmalloc mem failed");
    1685                 :          0 :                 return -ENOMEM;
    1686                 :            :         }
    1687                 :          0 :         hw = &adapter->hw;
    1688                 :          0 :         adapter->pdev = pci_dev;
    1689                 :          0 :         adapter->eth_dev = eth_dev;
    1690                 :          0 :         adapter->ports[0] = port;
    1691                 :          0 :         hw->back = (void *)adapter;
    1692                 :          0 :         port->eth_dev = eth_dev;
    1693                 :          0 :         port->hw = hw;
    1694                 :            : 
    1695                 :          0 :         hw->e_ctrl = (u8 *)pci_dev->mem_resource[4].addr;
    1696                 :          0 :         hw->c_ctrl = (u8 *)pci_dev->mem_resource[0].addr;
    1697                 :          0 :         hw->c_blen = pci_dev->mem_resource[0].len;
    1698                 :          0 :         hw->device_id = pci_dev->id.device_id;
    1699                 :          0 :         hw->vendor_id = pci_dev->id.vendor_id;
    1700                 :          0 :         hw->mbx.en_vfs = pci_dev->max_vfs;
    1701         [ #  # ]:          0 :         if (hw->mbx.en_vfs > hw->max_vfs) {
    1702                 :            :                 ret = -EINVAL;
    1703                 :          0 :                 RNP_PMD_ERR("sriov vfs max support 64");
    1704                 :          0 :                 goto free_ad;
    1705                 :            :         }
    1706                 :            : 
    1707                 :          0 :         strlcpy(hw->device_name, pci_dev->device.name,
    1708                 :            :                         strlen(pci_dev->device.name) + 1);
    1709                 :            :         ret = rnp_proc_priv_init(eth_dev);
    1710                 :            :         if (ret < 0) {
    1711                 :          0 :                 RNP_PMD_ERR("proc_priv_alloc failed");
    1712                 :          0 :                 goto free_ad;
    1713                 :            :         }
    1714                 :          0 :         ret = rnp_init_mbx_pf(hw);
    1715         [ #  # ]:          0 :         if (ret < 0) {
    1716                 :          0 :                 RNP_PMD_ERR("mailbox hardware init failed");
    1717                 :          0 :                 goto free_ad;
    1718                 :            :         }
    1719                 :          0 :         ret = rnp_init_hw(hw);
    1720         [ #  # ]:          0 :         if (ret < 0) {
    1721                 :          0 :                 RNP_PMD_ERR("Hardware initialization failed");
    1722                 :          0 :                 goto free_ad;
    1723                 :            :         }
    1724                 :          0 :         ret = rnp_setup_common_ops(hw);
    1725         [ #  # ]:          0 :         if (ret < 0) {
    1726                 :          0 :                 RNP_PMD_ERR("hardware common ops setup failed");
    1727                 :          0 :                 goto free_ad;
    1728                 :            :         }
    1729                 :          0 :         rnp_mbx_fw_pf_link_event_en(port, false);
    1730         [ #  # ]:          0 :         for (p_id = 0; p_id < hw->max_port_num; p_id++) {
    1731                 :            :                 /* port 0 resource has been allocated when probe */
    1732         [ #  # ]:          0 :                 if (!p_id) {
    1733                 :            :                         sub_eth_dev = eth_dev;
    1734                 :            :                 } else {
    1735         [ #  # ]:          0 :                         if (strlen(hw->device_name) + 4 > sizeof(name))
    1736                 :            :                                 return -EINVAL;
    1737                 :          0 :                         snprintf(name, sizeof(name),
    1738                 :            :                                         "%s_%d", hw->device_name, p_id);
    1739                 :          0 :                         sub_eth_dev = rnp_alloc_eth_port(pci_dev, name);
    1740         [ #  # ]:          0 :                         if (!sub_eth_dev) {
    1741                 :          0 :                                 RNP_PMD_ERR("%s sub_eth alloc failed",
    1742                 :            :                                                 hw->device_name);
    1743                 :            :                                 ret = -ENOMEM;
    1744                 :          0 :                                 goto eth_alloc_error;
    1745                 :            :                         }
    1746                 :            :                         ret = rnp_proc_priv_init(sub_eth_dev);
    1747                 :            :                         if (ret < 0) {
    1748                 :          0 :                                 RNP_PMD_ERR("proc_priv_alloc failed");
    1749                 :          0 :                                 goto eth_alloc_error;
    1750                 :            :                         }
    1751                 :            :                         memcpy(sub_eth_dev->process_private,
    1752                 :          0 :                                         eth_dev->process_private,
    1753                 :            :                                         sizeof(struct rnp_proc_priv));
    1754                 :            :                 }
    1755                 :          0 :                 ret = rnp_init_port_resource(adapter, sub_eth_dev, name, p_id);
    1756         [ #  # ]:          0 :                 if (ret)
    1757                 :          0 :                         goto eth_alloc_error;
    1758                 :          0 :                 rnp_mac_rx_disable(sub_eth_dev);
    1759                 :            :                 rnp_mac_tx_disable(sub_eth_dev);
    1760         [ #  # ]:          0 :                 if (p_id) {
    1761                 :            :                         /* port 0 will be probe by platform */
    1762                 :          0 :                         rte_eth_dev_probing_finish(sub_eth_dev);
    1763                 :            :                 }
    1764                 :            :         }
    1765                 :          0 :         ret = rnp_rx_reset_pool_setup(adapter);
    1766         [ #  # ]:          0 :         if (ret)
    1767                 :          0 :                 goto eth_alloc_error;
    1768                 :            :         /* enable link update event interrupt */
    1769                 :          0 :         rte_intr_callback_register(intr_handle,
    1770                 :            :                         rnp_dev_interrupt_handler, adapter);
    1771                 :          0 :         rte_intr_enable(intr_handle);
    1772                 :          0 :         rnp_mbx_fw_pf_link_event_en(port, true);
    1773                 :            : 
    1774                 :          0 :         return 0;
    1775                 :            : 
    1776                 :          0 : eth_alloc_error:
    1777         [ #  # ]:          0 :         for (p_id = 0; p_id < adapter->inited_ports; p_id++) {
    1778                 :          0 :                 port = adapter->ports[p_id];
    1779         [ #  # ]:          0 :                 if (!port)
    1780                 :          0 :                         continue;
    1781         [ #  # ]:          0 :                 if (port->eth_dev) {
    1782                 :          0 :                         rnp_dev_close(port->eth_dev);
    1783                 :            :                         /* just release eth_dev allocated by myself */
    1784         [ #  # ]:          0 :                         if (port->eth_dev != adapter->eth_dev)
    1785                 :          0 :                                 rte_eth_dev_release_port(port->eth_dev);
    1786                 :            :                 }
    1787                 :            :         }
    1788                 :          0 : free_ad:
    1789         [ #  # ]:          0 :         if (hw->fw_info.cookie_pool)
    1790                 :          0 :                 rnp_dma_mem_free(hw, &hw->fw_info.mem);
    1791                 :          0 :         rte_free(adapter);
    1792                 :            : 
    1793                 :          0 :         return ret;
    1794                 :            : 
    1795                 :            : }
    1796                 :            : 
    1797                 :            : static int
    1798                 :          0 : rnp_eth_dev_uninit(struct rte_eth_dev *eth_dev)
    1799                 :            : {
    1800                 :          0 :         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
    1801                 :            :         uint16_t port_id;
    1802                 :            :         int err = 0;
    1803                 :            : 
    1804                 :            :         /* Free up other ports and all resources */
    1805         [ #  # ]:          0 :         RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)
    1806                 :          0 :                 err |= rte_eth_dev_close(port_id);
    1807                 :            : 
    1808         [ #  # ]:          0 :         return err == 0 ? 0 : -EIO;
    1809                 :            : }
    1810                 :            : 
    1811                 :            : static int
    1812                 :          0 : rnp_pci_remove(struct rte_pci_device *pci_dev)
    1813                 :            : {
    1814                 :          0 :         char device_name[RTE_ETH_NAME_MAX_LEN] = "";
    1815                 :            :         struct rte_eth_dev *eth_dev = NULL;
    1816                 :            :         uint16_t idx = 0;
    1817                 :            : 
    1818                 :            :         /* Find a port belong to pf that not be called dev_close */
    1819         [ #  # ]:          0 :         for (idx = 0; idx < RNP_MAX_PORT_OF_PF; idx++) {
    1820         [ #  # ]:          0 :                 if (idx)
    1821                 :          0 :                         snprintf(device_name, sizeof(device_name), "%s_%d",
    1822                 :            :                                         pci_dev->device.name,
    1823                 :            :                                         idx);
    1824                 :            :                 else
    1825                 :          0 :                         snprintf(device_name, sizeof(device_name), "%s",
    1826                 :            :                                         pci_dev->device.name);
    1827                 :          0 :                 eth_dev = rte_eth_dev_allocated(device_name);
    1828         [ #  # ]:          0 :                 if (eth_dev)
    1829                 :            :                         break;
    1830                 :            :         }
    1831         [ #  # ]:          0 :         if (eth_dev)
    1832                 :            :                 /* Cleanup eth dev */
    1833                 :          0 :                 return rnp_eth_dev_uninit(eth_dev);
    1834                 :            :         return -ENODEV;
    1835                 :            : }
    1836                 :            : 
    1837                 :            : static int
    1838                 :          0 : rnp_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
    1839                 :            : {
    1840                 :            :         int rc;
    1841                 :            : 
    1842                 :            :         RTE_SET_USED(pci_drv);
    1843                 :            : 
    1844                 :          0 :         rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct rnp_eth_port),
    1845                 :            :                         rnp_eth_dev_init);
    1846                 :            : 
    1847                 :          0 :         return rc;
    1848                 :            : }
    1849                 :            : 
    1850                 :            : static const struct rte_pci_id pci_id_rnp_map[] = {
    1851                 :            :         { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X2) },
    1852                 :            :         { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X4) },
    1853                 :            :         { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X8) },
    1854                 :            :         { .vendor_id = 0, },
    1855                 :            : };
    1856                 :            : 
    1857                 :            : static struct rte_pci_driver rte_rnp_pmd = {
    1858                 :            :         .id_table = pci_id_rnp_map,
    1859                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
    1860                 :            :         .probe = rnp_pci_probe,
    1861                 :            :         .remove = rnp_pci_remove,
    1862                 :            : };
    1863                 :            : 
    1864         [ -  + ]:        254 : RTE_LOG_REGISTER_SUFFIX(rnp_init_logtype, init, NOTICE);
    1865                 :            : 
    1866                 :        254 : RTE_PMD_REGISTER_PCI(net_rnp, rte_rnp_pmd);
    1867                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_rnp, pci_id_rnp_map);
    1868                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_rnp, "igb_uio | uio_pci_generic | vfio-pci");

Generated by: LCOV version 1.14