LCOV - code coverage report
Current view: top level - drivers/net/mlx4 - mlx4_ethdev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 289 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 27 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 147 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2017 6WIND S.A.
       3                 :            :  * Copyright 2017 Mellanox Technologies, Ltd
       4                 :            :  */
       5                 :            : 
       6                 :            : /**
       7                 :            :  * @file
       8                 :            :  * Miscellaneous control operations for mlx4 driver.
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <dirent.h>
      12                 :            : #include <errno.h>
      13                 :            : #include <linux/ethtool.h>
      14                 :            : #include <linux/sockios.h>
      15                 :            : #include <net/if.h>
      16                 :            : #include <netinet/ip.h>
      17                 :            : #include <stddef.h>
      18                 :            : #include <stdint.h>
      19                 :            : #include <stdio.h>
      20                 :            : #include <stdlib.h>
      21                 :            : #include <string.h>
      22                 :            : #include <sys/ioctl.h>
      23                 :            : #include <sys/socket.h>
      24                 :            : #include <unistd.h>
      25                 :            : 
      26                 :            : /* Verbs headers do not support -pedantic. */
      27                 :            : #ifdef PEDANTIC
      28                 :            : #pragma GCC diagnostic ignored "-Wpedantic"
      29                 :            : #endif
      30                 :            : #include <infiniband/verbs.h>
      31                 :            : #ifdef PEDANTIC
      32                 :            : #pragma GCC diagnostic error "-Wpedantic"
      33                 :            : #endif
      34                 :            : 
      35                 :            : #include <bus_pci_driver.h>
      36                 :            : #include <rte_errno.h>
      37                 :            : #include <ethdev_driver.h>
      38                 :            : #include <rte_ether.h>
      39                 :            : #include <rte_flow.h>
      40                 :            : #include <rte_pci.h>
      41                 :            : #include <rte_string_fns.h>
      42                 :            : 
      43                 :            : #include "mlx4.h"
      44                 :            : #include "mlx4_flow.h"
      45                 :            : #include "mlx4_glue.h"
      46                 :            : #include "mlx4_rxtx.h"
      47                 :            : #include "mlx4_utils.h"
      48                 :            : 
      49                 :            : /**
      50                 :            :  * Get interface name from private structure.
      51                 :            :  *
      52                 :            :  * @param[in] priv
      53                 :            :  *   Pointer to private structure.
      54                 :            :  * @param[out] ifname
      55                 :            :  *   Interface name output buffer.
      56                 :            :  *
      57                 :            :  * @return
      58                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
      59                 :            :  */
      60                 :            : int
      61                 :          0 : mlx4_get_ifname(const struct mlx4_priv *priv, char (*ifname)[IF_NAMESIZE])
      62                 :            : {
      63                 :            :         DIR *dir;
      64                 :            :         struct dirent *dent;
      65                 :            :         unsigned int dev_type = 0;
      66                 :            :         unsigned int dev_port_prev = ~0u;
      67                 :          0 :         char match[IF_NAMESIZE] = "";
      68                 :            : 
      69                 :          0 :         {
      70                 :          0 :                 MKSTR(path, "%s/device/net", priv->ctx->device->ibdev_path);
      71                 :            : 
      72                 :          0 :                 dir = opendir(path);
      73         [ #  # ]:          0 :                 if (dir == NULL) {
      74                 :          0 :                         rte_errno = errno;
      75                 :          0 :                         return -rte_errno;
      76                 :            :                 }
      77                 :            :         }
      78         [ #  # ]:          0 :         while ((dent = readdir(dir)) != NULL) {
      79                 :          0 :                 char *name = dent->d_name;
      80                 :            :                 FILE *file;
      81                 :            :                 unsigned int dev_port;
      82                 :            :                 int r;
      83                 :            : 
      84         [ #  # ]:          0 :                 if ((name[0] == '.') &&
      85   [ #  #  #  # ]:          0 :                     ((name[1] == '\0') ||
      86         [ #  # ]:          0 :                      ((name[1] == '.') && (name[2] == '\0'))))
      87                 :          0 :                         continue;
      88                 :            : 
      89         [ #  # ]:          0 :                 MKSTR(path, "%s/device/net/%s/%s",
      90                 :            :                       priv->ctx->device->ibdev_path, name,
      91                 :            :                       (dev_type ? "dev_id" : "dev_port"));
      92                 :            : 
      93                 :          0 :                 file = fopen(path, "rb");
      94         [ #  # ]:          0 :                 if (file == NULL) {
      95         [ #  # ]:          0 :                         if (errno != ENOENT)
      96                 :          0 :                                 continue;
      97                 :            :                         /*
      98                 :            :                          * Switch to dev_id when dev_port does not exist as
      99                 :            :                          * is the case with Linux kernel versions < 3.15.
     100                 :            :                          */
     101                 :          0 : try_dev_id:
     102                 :          0 :                         match[0] = '\0';
     103         [ #  # ]:          0 :                         if (dev_type)
     104                 :            :                                 break;
     105                 :            :                         dev_type = 1;
     106                 :            :                         dev_port_prev = ~0u;
     107                 :          0 :                         rewinddir(dir);
     108                 :          0 :                         continue;
     109                 :            :                 }
     110         [ #  # ]:          0 :                 r = fscanf(file, (dev_type ? "%x" : "%u"), &dev_port);
     111                 :          0 :                 fclose(file);
     112         [ #  # ]:          0 :                 if (r != 1)
     113                 :          0 :                         continue;
     114                 :            :                 /*
     115                 :            :                  * Switch to dev_id when dev_port returns the same value for
     116                 :            :                  * all ports. May happen when using a MOFED release older than
     117                 :            :                  * 3.0 with a Linux kernel >= 3.15.
     118                 :            :                  */
     119         [ #  # ]:          0 :                 if (dev_port == dev_port_prev)
     120                 :          0 :                         goto try_dev_id;
     121                 :            :                 dev_port_prev = dev_port;
     122         [ #  # ]:          0 :                 if (dev_port == (priv->port - 1u))
     123                 :            :                         strlcpy(match, name, sizeof(match));
     124                 :            :         }
     125                 :          0 :         closedir(dir);
     126         [ #  # ]:          0 :         if (match[0] == '\0') {
     127                 :          0 :                 rte_errno = ENODEV;
     128                 :          0 :                 return -rte_errno;
     129                 :            :         }
     130                 :            :         strncpy(*ifname, match, sizeof(*ifname));
     131                 :          0 :         return 0;
     132                 :            : }
     133                 :            : 
     134                 :            : /**
     135                 :            :  * Perform ifreq ioctl() on associated Ethernet device.
     136                 :            :  *
     137                 :            :  * @param[in] priv
     138                 :            :  *   Pointer to private structure.
     139                 :            :  * @param req
     140                 :            :  *   Request number to pass to ioctl().
     141                 :            :  * @param[out] ifr
     142                 :            :  *   Interface request structure output buffer.
     143                 :            :  *
     144                 :            :  * @return
     145                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     146                 :            :  */
     147                 :            : static int
     148                 :          0 : mlx4_ifreq(const struct mlx4_priv *priv, int req, struct ifreq *ifr)
     149                 :            : {
     150                 :          0 :         int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
     151                 :            :         int ret;
     152                 :            : 
     153         [ #  # ]:          0 :         if (sock == -1) {
     154                 :          0 :                 rte_errno = errno;
     155                 :          0 :                 return -rte_errno;
     156                 :            :         }
     157                 :          0 :         ret = mlx4_get_ifname(priv, &ifr->ifr_name);
     158   [ #  #  #  # ]:          0 :         if (!ret && ioctl(sock, req, ifr) == -1) {
     159                 :          0 :                 rte_errno = errno;
     160                 :          0 :                 ret = -rte_errno;
     161                 :            :         }
     162                 :          0 :         close(sock);
     163                 :          0 :         return ret;
     164                 :            : }
     165                 :            : 
     166                 :            : /**
     167                 :            :  * Get MAC address by querying netdevice.
     168                 :            :  *
     169                 :            :  * @param[in] priv
     170                 :            :  *   Pointer to private structure.
     171                 :            :  * @param[out] mac
     172                 :            :  *   MAC address output buffer.
     173                 :            :  *
     174                 :            :  * @return
     175                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     176                 :            :  */
     177                 :            : int
     178                 :          0 : mlx4_get_mac(struct mlx4_priv *priv, uint8_t (*mac)[RTE_ETHER_ADDR_LEN])
     179                 :            : {
     180                 :            :         struct ifreq request;
     181                 :          0 :         int ret = mlx4_ifreq(priv, SIOCGIFHWADDR, &request);
     182                 :            : 
     183         [ #  # ]:          0 :         if (ret)
     184                 :            :                 return ret;
     185                 :            :         memcpy(mac, request.ifr_hwaddr.sa_data, RTE_ETHER_ADDR_LEN);
     186                 :          0 :         return 0;
     187                 :            : }
     188                 :            : 
     189                 :            : /**
     190                 :            :  * Get device MTU.
     191                 :            :  *
     192                 :            :  * @param priv
     193                 :            :  *   Pointer to private structure.
     194                 :            :  * @param[out] mtu
     195                 :            :  *   MTU value output buffer.
     196                 :            :  *
     197                 :            :  * @return
     198                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     199                 :            :  */
     200                 :            : int
     201                 :          0 : mlx4_mtu_get(struct mlx4_priv *priv, uint16_t *mtu)
     202                 :            : {
     203                 :            :         struct ifreq request;
     204                 :          0 :         int ret = mlx4_ifreq(priv, SIOCGIFMTU, &request);
     205                 :            : 
     206         [ #  # ]:          0 :         if (ret)
     207                 :            :                 return ret;
     208                 :          0 :         *mtu = request.ifr_mtu;
     209                 :          0 :         return 0;
     210                 :            : }
     211                 :            : 
     212                 :            : /**
     213                 :            :  * DPDK callback to change the MTU.
     214                 :            :  *
     215                 :            :  * @param priv
     216                 :            :  *   Pointer to Ethernet device structure.
     217                 :            :  * @param mtu
     218                 :            :  *   MTU value to set.
     219                 :            :  *
     220                 :            :  * @return
     221                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     222                 :            :  */
     223                 :            : int
     224                 :          0 : mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
     225                 :            : {
     226                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     227                 :          0 :         struct ifreq request = { .ifr_mtu = mtu, };
     228                 :          0 :         int ret = mlx4_ifreq(priv, SIOCSIFMTU, &request);
     229                 :            : 
     230         [ #  # ]:          0 :         if (ret)
     231                 :            :                 return ret;
     232                 :          0 :         priv->mtu = mtu;
     233                 :          0 :         return 0;
     234                 :            : }
     235                 :            : 
     236                 :            : /**
     237                 :            :  * Set device flags.
     238                 :            :  *
     239                 :            :  * @param priv
     240                 :            :  *   Pointer to private structure.
     241                 :            :  * @param keep
     242                 :            :  *   Bitmask for flags that must remain untouched.
     243                 :            :  * @param flags
     244                 :            :  *   Bitmask for flags to modify.
     245                 :            :  *
     246                 :            :  * @return
     247                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     248                 :            :  */
     249                 :            : static int
     250                 :          0 : mlx4_set_flags(struct mlx4_priv *priv, unsigned int keep, unsigned int flags)
     251                 :            : {
     252                 :            :         struct ifreq request;
     253                 :          0 :         int ret = mlx4_ifreq(priv, SIOCGIFFLAGS, &request);
     254                 :            : 
     255         [ #  # ]:          0 :         if (ret)
     256                 :            :                 return ret;
     257                 :          0 :         request.ifr_flags &= keep;
     258                 :          0 :         request.ifr_flags |= flags & ~keep;
     259                 :          0 :         return mlx4_ifreq(priv, SIOCSIFFLAGS, &request);
     260                 :            : }
     261                 :            : 
     262                 :            : /**
     263                 :            :  * Change the link state (UP / DOWN).
     264                 :            :  *
     265                 :            :  * @param priv
     266                 :            :  *   Pointer to Ethernet device private data.
     267                 :            :  * @param up
     268                 :            :  *   Nonzero for link up, otherwise link down.
     269                 :            :  *
     270                 :            :  * @return
     271                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     272                 :            :  */
     273                 :            : static int
     274                 :            : mlx4_dev_set_link(struct mlx4_priv *priv, int up)
     275                 :            : {
     276                 :            :         int err;
     277                 :            : 
     278                 :            :         if (up) {
     279                 :          0 :                 err = mlx4_set_flags(priv, ~IFF_UP, IFF_UP);
     280         [ #  # ]:          0 :                 if (err)
     281                 :          0 :                         return err;
     282                 :            :         } else {
     283                 :          0 :                 err = mlx4_set_flags(priv, ~IFF_UP, ~IFF_UP);
     284         [ #  # ]:          0 :                 if (err)
     285                 :          0 :                         return err;
     286                 :            :         }
     287                 :            :         return 0;
     288                 :            : }
     289                 :            : 
     290                 :            : /**
     291                 :            :  * DPDK callback to bring the link DOWN.
     292                 :            :  *
     293                 :            :  * @param dev
     294                 :            :  *   Pointer to Ethernet device structure.
     295                 :            :  *
     296                 :            :  * @return
     297                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     298                 :            :  */
     299                 :            : int
     300                 :          0 : mlx4_dev_set_link_down(struct rte_eth_dev *dev)
     301                 :            : {
     302                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     303                 :            : 
     304                 :          0 :         return mlx4_dev_set_link(priv, 0);
     305                 :            : }
     306                 :            : 
     307                 :            : /**
     308                 :            :  * DPDK callback to bring the link UP.
     309                 :            :  *
     310                 :            :  * @param dev
     311                 :            :  *   Pointer to Ethernet device structure.
     312                 :            :  *
     313                 :            :  * @return
     314                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     315                 :            :  */
     316                 :            : int
     317                 :          0 : mlx4_dev_set_link_up(struct rte_eth_dev *dev)
     318                 :            : {
     319                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     320                 :            : 
     321                 :          0 :         return mlx4_dev_set_link(priv, 1);
     322                 :            : }
     323                 :            : 
     324                 :            : /**
     325                 :            :  * Supported Rx mode toggles.
     326                 :            :  *
     327                 :            :  * Even and odd values respectively stand for off and on.
     328                 :            :  */
     329                 :            : enum rxmode_toggle {
     330                 :            :         RXMODE_TOGGLE_PROMISC_OFF,
     331                 :            :         RXMODE_TOGGLE_PROMISC_ON,
     332                 :            :         RXMODE_TOGGLE_ALLMULTI_OFF,
     333                 :            :         RXMODE_TOGGLE_ALLMULTI_ON,
     334                 :            : };
     335                 :            : 
     336                 :            : /**
     337                 :            :  * Helper function to toggle promiscuous and all multicast modes.
     338                 :            :  *
     339                 :            :  * @param dev
     340                 :            :  *   Pointer to Ethernet device structure.
     341                 :            :  * @param toggle
     342                 :            :  *   Toggle to set.
     343                 :            :  *
     344                 :            :  * @return
     345                 :            :  *   0 on success, a negative errno value otherwise and rte_errno is set.
     346                 :            :  */
     347                 :            : static int
     348                 :          0 : mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle)
     349                 :            : {
     350                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     351                 :            :         const char *mode;
     352                 :            :         struct rte_flow_error error;
     353                 :            :         int ret;
     354                 :            : 
     355      [ #  #  # ]:          0 :         switch (toggle) {
     356                 :          0 :         case RXMODE_TOGGLE_PROMISC_OFF:
     357                 :            :         case RXMODE_TOGGLE_PROMISC_ON:
     358                 :            :                 mode = "promiscuous";
     359                 :          0 :                 dev->data->promiscuous = toggle & 1;
     360                 :          0 :                 break;
     361                 :          0 :         case RXMODE_TOGGLE_ALLMULTI_OFF:
     362                 :            :         case RXMODE_TOGGLE_ALLMULTI_ON:
     363                 :            :                 mode = "all multicast";
     364                 :          0 :                 dev->data->all_multicast = toggle & 1;
     365                 :          0 :                 break;
     366                 :            :         default:
     367                 :            :                 mode = "undefined";
     368                 :            :         }
     369                 :            : 
     370                 :          0 :         ret = mlx4_flow_sync(priv, &error);
     371         [ #  # ]:          0 :         if (!ret)
     372                 :            :                 return 0;
     373                 :            : 
     374         [ #  # ]:          0 :         ERROR("cannot toggle %s mode (code %d, \"%s\"),"
     375                 :            :               " flow error type %d, cause %p, message: %s",
     376                 :            :               mode, rte_errno, strerror(rte_errno), error.type, error.cause,
     377                 :            :               error.message ? error.message : "(unspecified)");
     378                 :          0 :         return ret;
     379                 :            : }
     380                 :            : 
     381                 :            : /**
     382                 :            :  * DPDK callback to enable promiscuous mode.
     383                 :            :  *
     384                 :            :  * @param dev
     385                 :            :  *   Pointer to Ethernet device structure.
     386                 :            :  *
     387                 :            :  * @return
     388                 :            :  *   0 on success, a negative errno value otherwise and rte_errno is set.
     389                 :            :  */
     390                 :            : int
     391                 :          0 : mlx4_promiscuous_enable(struct rte_eth_dev *dev)
     392                 :            : {
     393                 :          0 :         return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_ON);
     394                 :            : }
     395                 :            : 
     396                 :            : /**
     397                 :            :  * DPDK callback to disable promiscuous mode.
     398                 :            :  *
     399                 :            :  * @param dev
     400                 :            :  *   Pointer to Ethernet device structure.
     401                 :            :  *
     402                 :            :  * @return
     403                 :            :  *   0 on success, a negative errno value otherwise and rte_errno is set.
     404                 :            :  */
     405                 :            : int
     406                 :          0 : mlx4_promiscuous_disable(struct rte_eth_dev *dev)
     407                 :            : {
     408                 :          0 :         return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_OFF);
     409                 :            : }
     410                 :            : 
     411                 :            : /**
     412                 :            :  * DPDK callback to enable all multicast mode.
     413                 :            :  *
     414                 :            :  * @param dev
     415                 :            :  *   Pointer to Ethernet device structure.
     416                 :            :  *
     417                 :            :  * @return
     418                 :            :  *   0 on success, a negative errno value otherwise and rte_errno is set.
     419                 :            :  */
     420                 :            : int
     421                 :          0 : mlx4_allmulticast_enable(struct rte_eth_dev *dev)
     422                 :            : {
     423                 :          0 :         return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_ON);
     424                 :            : }
     425                 :            : 
     426                 :            : /**
     427                 :            :  * DPDK callback to disable all multicast mode.
     428                 :            :  *
     429                 :            :  * @param dev
     430                 :            :  *   Pointer to Ethernet device structure.
     431                 :            :  *
     432                 :            :  * @return
     433                 :            :  *   0 on success, a negative errno value otherwise and rte_errno is set.
     434                 :            :  */
     435                 :            : int
     436                 :          0 : mlx4_allmulticast_disable(struct rte_eth_dev *dev)
     437                 :            : {
     438                 :          0 :         return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_ALLMULTI_OFF);
     439                 :            : }
     440                 :            : 
     441                 :            : /**
     442                 :            :  * DPDK callback to remove a MAC address.
     443                 :            :  *
     444                 :            :  * @param dev
     445                 :            :  *   Pointer to Ethernet device structure.
     446                 :            :  * @param index
     447                 :            :  *   MAC address index.
     448                 :            :  */
     449                 :            : void
     450                 :          0 : mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
     451                 :            : {
     452                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     453                 :            :         struct rte_flow_error error;
     454                 :            : 
     455         [ #  # ]:          0 :         if (index >= RTE_DIM(priv->mac) - priv->mac_mc) {
     456                 :          0 :                 rte_errno = EINVAL;
     457                 :          0 :                 return;
     458                 :            :         }
     459                 :          0 :         memset(&priv->mac[index], 0, sizeof(priv->mac[index]));
     460         [ #  # ]:          0 :         if (!mlx4_flow_sync(priv, &error))
     461                 :            :                 return;
     462         [ #  # ]:          0 :         ERROR("failed to synchronize flow rules after removing MAC address"
     463                 :            :               " at index %d (code %d, \"%s\"),"
     464                 :            :               " flow error type %d, cause %p, message: %s",
     465                 :            :               index, rte_errno, strerror(rte_errno), error.type, error.cause,
     466                 :            :               error.message ? error.message : "(unspecified)");
     467                 :            : }
     468                 :            : 
     469                 :            : /**
     470                 :            :  * DPDK callback to add a MAC address.
     471                 :            :  *
     472                 :            :  * @param dev
     473                 :            :  *   Pointer to Ethernet device structure.
     474                 :            :  * @param mac_addr
     475                 :            :  *   MAC address to register.
     476                 :            :  * @param index
     477                 :            :  *   MAC address index.
     478                 :            :  * @param vmdq
     479                 :            :  *   VMDq pool index to associate address with (ignored).
     480                 :            :  *
     481                 :            :  * @return
     482                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     483                 :            :  */
     484                 :            : int
     485                 :          0 : mlx4_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
     486                 :            :                   uint32_t index, uint32_t vmdq)
     487                 :            : {
     488                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     489                 :            :         struct rte_flow_error error;
     490                 :            :         int ret;
     491                 :            : 
     492                 :            :         (void)vmdq;
     493         [ #  # ]:          0 :         if (index >= RTE_DIM(priv->mac) - priv->mac_mc) {
     494                 :          0 :                 rte_errno = EINVAL;
     495                 :          0 :                 return -rte_errno;
     496                 :            :         }
     497                 :          0 :         memcpy(&priv->mac[index], mac_addr, sizeof(priv->mac[index]));
     498                 :          0 :         ret = mlx4_flow_sync(priv, &error);
     499         [ #  # ]:          0 :         if (!ret)
     500                 :            :                 return 0;
     501         [ #  # ]:          0 :         ERROR("failed to synchronize flow rules after adding MAC address"
     502                 :            :               " at index %d (code %d, \"%s\"),"
     503                 :            :               " flow error type %d, cause %p, message: %s",
     504                 :            :               index, rte_errno, strerror(rte_errno), error.type, error.cause,
     505                 :            :               error.message ? error.message : "(unspecified)");
     506                 :          0 :         return ret;
     507                 :            : }
     508                 :            : 
     509                 :            : /**
     510                 :            :  * DPDK callback to configure multicast addresses.
     511                 :            :  *
     512                 :            :  * @param dev
     513                 :            :  *   Pointer to Ethernet device structure.
     514                 :            :  * @param list
     515                 :            :  *   List of MAC addresses to register.
     516                 :            :  * @param num
     517                 :            :  *   Number of entries in list.
     518                 :            :  *
     519                 :            :  * @return
     520                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     521                 :            :  */
     522                 :            : int
     523                 :          0 : mlx4_set_mc_addr_list(struct rte_eth_dev *dev, struct rte_ether_addr *list,
     524                 :            :                       uint32_t num)
     525                 :            : {
     526                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     527                 :            :         struct rte_flow_error error;
     528                 :            :         int ret;
     529                 :            : 
     530         [ #  # ]:          0 :         if (num > RTE_DIM(priv->mac)) {
     531                 :          0 :                 rte_errno = EINVAL;
     532                 :          0 :                 return -rte_errno;
     533                 :            :         }
     534                 :            :         /*
     535                 :            :          * Make sure there is enough room to increase the number of
     536                 :            :          * multicast entries without overwriting standard entries.
     537                 :            :          */
     538         [ #  # ]:          0 :         if (num > priv->mac_mc) {
     539                 :            :                 unsigned int i;
     540                 :            : 
     541                 :          0 :                 for (i = RTE_DIM(priv->mac) - num;
     542         [ #  # ]:          0 :                      i != RTE_DIM(priv->mac) - priv->mac_mc;
     543                 :          0 :                      ++i)
     544         [ #  # ]:          0 :                         if (!rte_is_zero_ether_addr(&priv->mac[i])) {
     545                 :          0 :                                 rte_errno = EBUSY;
     546                 :          0 :                                 return -rte_errno;
     547                 :            :                         }
     548         [ #  # ]:          0 :         } else if (num < priv->mac_mc) {
     549                 :            :                 /* Clear unused entries. */
     550                 :          0 :                 memset(priv->mac + RTE_DIM(priv->mac) - priv->mac_mc,
     551                 :            :                        0,
     552                 :          0 :                        sizeof(priv->mac[0]) * (priv->mac_mc - num));
     553                 :            :         }
     554                 :          0 :         memcpy(priv->mac + RTE_DIM(priv->mac) - num, list, sizeof(*list) * num);
     555                 :          0 :         priv->mac_mc = num;
     556                 :          0 :         ret = mlx4_flow_sync(priv, &error);
     557         [ #  # ]:          0 :         if (!ret)
     558                 :            :                 return 0;
     559         [ #  # ]:          0 :         ERROR("failed to synchronize flow rules after modifying MC list,"
     560                 :            :               " (code %d, \"%s\"), flow error type %d, cause %p, message: %s",
     561                 :            :               rte_errno, strerror(rte_errno), error.type, error.cause,
     562                 :            :               error.message ? error.message : "(unspecified)");
     563                 :          0 :         return ret;
     564                 :            : }
     565                 :            : 
     566                 :            : /**
     567                 :            :  * DPDK callback to configure a VLAN filter.
     568                 :            :  *
     569                 :            :  * @param dev
     570                 :            :  *   Pointer to Ethernet device structure.
     571                 :            :  * @param vlan_id
     572                 :            :  *   VLAN ID to filter.
     573                 :            :  * @param on
     574                 :            :  *   Toggle filter.
     575                 :            :  *
     576                 :            :  * @return
     577                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     578                 :            :  */
     579                 :            : int
     580                 :          0 : mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
     581                 :            : {
     582                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     583                 :            :         struct rte_flow_error error;
     584                 :          0 :         unsigned int vidx = vlan_id / 64;
     585                 :          0 :         unsigned int vbit = vlan_id % 64;
     586                 :            :         uint64_t *v;
     587                 :            :         int ret;
     588                 :            : 
     589         [ #  # ]:          0 :         if (vidx >= RTE_DIM(dev->data->vlan_filter_conf.ids)) {
     590                 :          0 :                 rte_errno = EINVAL;
     591                 :          0 :                 return -rte_errno;
     592                 :            :         }
     593                 :            :         v = &dev->data->vlan_filter_conf.ids[vidx];
     594                 :          0 :         *v &= ~(UINT64_C(1) << vbit);
     595                 :          0 :         *v |= (uint64_t)!!on << vbit;
     596                 :          0 :         ret = mlx4_flow_sync(priv, &error);
     597         [ #  # ]:          0 :         if (!ret)
     598                 :            :                 return 0;
     599   [ #  #  #  # ]:          0 :         ERROR("failed to synchronize flow rules after %s VLAN filter on ID %u"
     600                 :            :               " (code %d, \"%s\"), "
     601                 :            :               " flow error type %d, cause %p, message: %s",
     602                 :            :               on ? "enabling" : "disabling", vlan_id,
     603                 :            :               rte_errno, strerror(rte_errno), error.type, error.cause,
     604                 :            :               error.message ? error.message : "(unspecified)");
     605                 :          0 :         return ret;
     606                 :            : }
     607                 :            : 
     608                 :            : /**
     609                 :            :  * DPDK callback to set the primary MAC address.
     610                 :            :  *
     611                 :            :  * @param dev
     612                 :            :  *   Pointer to Ethernet device structure.
     613                 :            :  * @param mac_addr
     614                 :            :  *   MAC address to register.
     615                 :            :  *
     616                 :            :  * @return
     617                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     618                 :            :  */
     619                 :            : int
     620                 :          0 : mlx4_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
     621                 :            : {
     622                 :          0 :         return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
     623                 :            : }
     624                 :            : 
     625                 :            : /**
     626                 :            :  * DPDK callback to get information about the device.
     627                 :            :  *
     628                 :            :  * @param dev
     629                 :            :  *   Pointer to Ethernet device structure.
     630                 :            :  * @param[out] info
     631                 :            :  *   Info structure output buffer.
     632                 :            :  */
     633                 :            : int
     634                 :          0 : mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
     635                 :            : {
     636                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     637                 :            :         unsigned int max;
     638                 :            : 
     639                 :            :         /* FIXME: we should ask the device for these values. */
     640                 :          0 :         info->min_rx_bufsize = 32;
     641                 :          0 :         info->max_rx_pktlen = 65536;
     642                 :            :         /*
     643                 :            :          * Since we need one CQ per QP, the limit is the minimum number
     644                 :            :          * between the two values.
     645                 :            :          */
     646                 :          0 :         max = ((priv->device_attr.max_cq > priv->device_attr.max_qp) ?
     647                 :          0 :                priv->device_attr.max_qp : priv->device_attr.max_cq);
     648                 :            :         /* max_rx_queues is uint16_t. */
     649                 :          0 :         max = RTE_MIN(max, (unsigned int)UINT16_MAX);
     650                 :          0 :         info->max_rx_queues = max;
     651                 :          0 :         info->max_tx_queues = max;
     652                 :          0 :         info->max_mac_addrs = RTE_DIM(priv->mac);
     653                 :          0 :         info->tx_offload_capa = mlx4_get_tx_port_offloads(priv);
     654                 :          0 :         info->rx_queue_offload_capa = mlx4_get_rx_queue_offloads(priv);
     655                 :          0 :         info->rx_offload_capa = (mlx4_get_rx_port_offloads(priv) |
     656                 :          0 :                                  info->rx_queue_offload_capa);
     657                 :          0 :         info->if_index = priv->if_index;
     658                 :          0 :         info->hash_key_size = MLX4_RSS_HASH_KEY_SIZE;
     659                 :          0 :         info->speed_capa =
     660                 :            :                         RTE_ETH_LINK_SPEED_1G |
     661                 :            :                         RTE_ETH_LINK_SPEED_10G |
     662                 :            :                         RTE_ETH_LINK_SPEED_20G |
     663                 :            :                         RTE_ETH_LINK_SPEED_40G |
     664                 :            :                         RTE_ETH_LINK_SPEED_56G;
     665                 :          0 :         info->flow_type_rss_offloads = mlx4_conv_rss_types(priv, 0, 1);
     666                 :            : 
     667                 :          0 :         return 0;
     668                 :            : }
     669                 :            : 
     670                 :            : /**
     671                 :            :  * Get firmware version of a device.
     672                 :            :  *
     673                 :            :  * @param dev
     674                 :            :  *   Ethernet device port.
     675                 :            :  * @param fw_ver
     676                 :            :  *   String output allocated by caller.
     677                 :            :  * @param fw_size
     678                 :            :  *   Size of the output string, including terminating null byte.
     679                 :            :  *
     680                 :            :  * @return
     681                 :            :  *   0 on success, or the size of the non truncated string if too big.
     682                 :            :  */
     683                 :          0 : int mlx4_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
     684                 :            : {
     685                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     686                 :            :         struct ibv_device_attr *attr = &priv->device_attr;
     687                 :          0 :         size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
     688                 :            : 
     689         [ #  # ]:          0 :         if (fw_size < size)
     690                 :          0 :                 return size;
     691         [ #  # ]:          0 :         if (fw_ver != NULL)
     692                 :            :                 strlcpy(fw_ver, attr->fw_ver, fw_size);
     693                 :            :         return 0;
     694                 :            : }
     695                 :            : 
     696                 :            : /**
     697                 :            :  * DPDK callback to get device statistics.
     698                 :            :  *
     699                 :            :  * @param dev
     700                 :            :  *   Pointer to Ethernet device structure.
     701                 :            :  * @param[out] stats
     702                 :            :  *   Stats structure output buffer.
     703                 :            :  */
     704                 :            : int
     705                 :          0 : mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
     706                 :            : {
     707                 :            :         struct rte_eth_stats tmp;
     708                 :            :         unsigned int i;
     709                 :            :         unsigned int idx;
     710                 :            : 
     711                 :            :         memset(&tmp, 0, sizeof(tmp));
     712                 :            :         /* Add software counters. */
     713         [ #  # ]:          0 :         for (i = 0; i != dev->data->nb_rx_queues; ++i) {
     714                 :          0 :                 struct rxq *rxq = dev->data->rx_queues[i];
     715                 :            : 
     716         [ #  # ]:          0 :                 if (rxq == NULL)
     717                 :          0 :                         continue;
     718                 :          0 :                 idx = rxq->stats.idx;
     719         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     720                 :          0 :                         tmp.q_ipackets[idx] += rxq->stats.ipackets;
     721                 :          0 :                         tmp.q_ibytes[idx] += rxq->stats.ibytes;
     722                 :          0 :                         tmp.q_errors[idx] += (rxq->stats.idropped +
     723                 :          0 :                                               rxq->stats.rx_nombuf);
     724                 :            :                 }
     725                 :          0 :                 tmp.ipackets += rxq->stats.ipackets;
     726                 :          0 :                 tmp.ibytes += rxq->stats.ibytes;
     727                 :          0 :                 tmp.ierrors += rxq->stats.idropped;
     728                 :          0 :                 tmp.rx_nombuf += rxq->stats.rx_nombuf;
     729                 :            :         }
     730         [ #  # ]:          0 :         for (i = 0; i != dev->data->nb_tx_queues; ++i) {
     731                 :          0 :                 struct txq *txq = dev->data->tx_queues[i];
     732                 :            : 
     733         [ #  # ]:          0 :                 if (txq == NULL)
     734                 :          0 :                         continue;
     735                 :          0 :                 idx = txq->stats.idx;
     736         [ #  # ]:          0 :                 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     737                 :          0 :                         tmp.q_opackets[idx] += txq->stats.opackets;
     738                 :          0 :                         tmp.q_obytes[idx] += txq->stats.obytes;
     739                 :            :                 }
     740                 :          0 :                 tmp.opackets += txq->stats.opackets;
     741                 :          0 :                 tmp.obytes += txq->stats.obytes;
     742                 :          0 :                 tmp.oerrors += txq->stats.odropped;
     743                 :            :         }
     744                 :          0 :         *stats = tmp;
     745                 :          0 :         return 0;
     746                 :            : }
     747                 :            : 
     748                 :            : /**
     749                 :            :  * DPDK callback to clear device statistics.
     750                 :            :  *
     751                 :            :  * @param dev
     752                 :            :  *   Pointer to Ethernet device structure.
     753                 :            :  *
     754                 :            :  * @return
     755                 :            :  *   always 0 on success
     756                 :            :  */
     757                 :            : int
     758                 :          0 : mlx4_stats_reset(struct rte_eth_dev *dev)
     759                 :            : {
     760                 :            :         unsigned int i;
     761                 :            : 
     762         [ #  # ]:          0 :         for (i = 0; i != dev->data->nb_rx_queues; ++i) {
     763                 :          0 :                 struct rxq *rxq = dev->data->rx_queues[i];
     764                 :            : 
     765         [ #  # ]:          0 :                 if (rxq)
     766                 :          0 :                         rxq->stats = (struct mlx4_rxq_stats){
     767                 :          0 :                                 .idx = rxq->stats.idx,
     768                 :            :                         };
     769                 :            :         }
     770         [ #  # ]:          0 :         for (i = 0; i != dev->data->nb_tx_queues; ++i) {
     771                 :          0 :                 struct txq *txq = dev->data->tx_queues[i];
     772                 :            : 
     773         [ #  # ]:          0 :                 if (txq)
     774                 :          0 :                         txq->stats = (struct mlx4_txq_stats){
     775                 :          0 :                                 .idx = txq->stats.idx,
     776                 :            :                         };
     777                 :            :         }
     778                 :            : 
     779                 :          0 :         return 0;
     780                 :            : }
     781                 :            : 
     782                 :            : /**
     783                 :            :  * DPDK callback to retrieve physical link information.
     784                 :            :  *
     785                 :            :  * @param dev
     786                 :            :  *   Pointer to Ethernet device structure.
     787                 :            :  * @param wait_to_complete
     788                 :            :  *   Wait for request completion (ignored).
     789                 :            :  *
     790                 :            :  * @return
     791                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     792                 :            :  */
     793                 :            : int
     794                 :          0 : mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
     795                 :            : {
     796                 :          0 :         const struct mlx4_priv *priv = dev->data->dev_private;
     797                 :          0 :         struct ethtool_cmd edata = {
     798                 :            :                 .cmd = ETHTOOL_GSET,
     799                 :            :         };
     800                 :            :         struct ifreq ifr;
     801                 :            :         struct rte_eth_link dev_link;
     802                 :            :         int link_speed = 0;
     803                 :            : 
     804         [ #  # ]:          0 :         if (priv == NULL) {
     805                 :          0 :                 rte_errno = EINVAL;
     806                 :          0 :                 return -rte_errno;
     807                 :            :         }
     808                 :            :         (void)wait_to_complete;
     809         [ #  # ]:          0 :         if (mlx4_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
     810                 :          0 :                 WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(rte_errno));
     811                 :          0 :                 return -rte_errno;
     812                 :            :         }
     813                 :            :         memset(&dev_link, 0, sizeof(dev_link));
     814                 :          0 :         dev_link.link_status = ((ifr.ifr_flags & IFF_UP) &&
     815                 :            :                                 (ifr.ifr_flags & IFF_RUNNING));
     816                 :          0 :         ifr.ifr_data = (void *)&edata;
     817         [ #  # ]:          0 :         if (mlx4_ifreq(priv, SIOCETHTOOL, &ifr)) {
     818                 :          0 :                 WARN("ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: %s",
     819                 :            :                      strerror(rte_errno));
     820                 :          0 :                 return -rte_errno;
     821                 :            :         }
     822                 :            :         link_speed = ethtool_cmd_speed(&edata);
     823         [ #  # ]:          0 :         if (link_speed == -1)
     824                 :            :                 dev_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
     825                 :            :         else
     826                 :          0 :                 dev_link.link_speed = link_speed;
     827                 :          0 :         dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
     828                 :          0 :                                 RTE_ETH_LINK_HALF_DUPLEX : RTE_ETH_LINK_FULL_DUPLEX);
     829                 :          0 :         dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
     830                 :            :                                   RTE_ETH_LINK_SPEED_FIXED);
     831                 :          0 :         dev->data->dev_link = dev_link;
     832                 :          0 :         return 0;
     833                 :            : }
     834                 :            : 
     835                 :            : /**
     836                 :            :  * DPDK callback to get flow control status.
     837                 :            :  *
     838                 :            :  * @param dev
     839                 :            :  *   Pointer to Ethernet device structure.
     840                 :            :  * @param[out] fc_conf
     841                 :            :  *   Flow control output buffer.
     842                 :            :  *
     843                 :            :  * @return
     844                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     845                 :            :  */
     846                 :            : int
     847                 :          0 : mlx4_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
     848                 :            : {
     849                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     850                 :            :         struct ifreq ifr;
     851                 :          0 :         struct ethtool_pauseparam ethpause = {
     852                 :            :                 .cmd = ETHTOOL_GPAUSEPARAM,
     853                 :            :         };
     854                 :            :         int ret;
     855                 :            : 
     856                 :          0 :         ifr.ifr_data = (void *)&ethpause;
     857         [ #  # ]:          0 :         if (mlx4_ifreq(priv, SIOCETHTOOL, &ifr)) {
     858                 :          0 :                 ret = rte_errno;
     859                 :          0 :                 WARN("ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM)"
     860                 :            :                      " failed: %s",
     861                 :            :                      strerror(rte_errno));
     862                 :          0 :                 goto out;
     863                 :            :         }
     864                 :          0 :         fc_conf->autoneg = ethpause.autoneg;
     865   [ #  #  #  # ]:          0 :         if (ethpause.rx_pause && ethpause.tx_pause)
     866                 :          0 :                 fc_conf->mode = RTE_ETH_FC_FULL;
     867         [ #  # ]:          0 :         else if (ethpause.rx_pause)
     868                 :          0 :                 fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
     869         [ #  # ]:          0 :         else if (ethpause.tx_pause)
     870                 :          0 :                 fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
     871                 :            :         else
     872                 :          0 :                 fc_conf->mode = RTE_ETH_FC_NONE;
     873                 :            :         ret = 0;
     874                 :          0 : out:
     875                 :            :         MLX4_ASSERT(ret >= 0);
     876                 :          0 :         return -ret;
     877                 :            : }
     878                 :            : 
     879                 :            : /**
     880                 :            :  * DPDK callback to modify flow control parameters.
     881                 :            :  *
     882                 :            :  * @param dev
     883                 :            :  *   Pointer to Ethernet device structure.
     884                 :            :  * @param[in] fc_conf
     885                 :            :  *   Flow control parameters.
     886                 :            :  *
     887                 :            :  * @return
     888                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
     889                 :            :  */
     890                 :            : int
     891                 :          0 : mlx4_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
     892                 :            : {
     893                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     894                 :            :         struct ifreq ifr;
     895                 :          0 :         struct ethtool_pauseparam ethpause = {
     896                 :            :                 .cmd = ETHTOOL_SPAUSEPARAM,
     897                 :            :         };
     898                 :            :         int ret;
     899                 :            : 
     900                 :          0 :         ifr.ifr_data = (void *)&ethpause;
     901                 :          0 :         ethpause.autoneg = fc_conf->autoneg;
     902         [ #  # ]:          0 :         if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
     903         [ #  # ]:          0 :             (fc_conf->mode & RTE_ETH_FC_RX_PAUSE))
     904                 :          0 :                 ethpause.rx_pause = 1;
     905                 :            :         else
     906                 :            :                 ethpause.rx_pause = 0;
     907         [ #  # ]:          0 :         if (((fc_conf->mode & RTE_ETH_FC_FULL) == RTE_ETH_FC_FULL) ||
     908         [ #  # ]:          0 :             (fc_conf->mode & RTE_ETH_FC_TX_PAUSE))
     909                 :          0 :                 ethpause.tx_pause = 1;
     910                 :            :         else
     911                 :            :                 ethpause.tx_pause = 0;
     912         [ #  # ]:          0 :         if (mlx4_ifreq(priv, SIOCETHTOOL, &ifr)) {
     913                 :          0 :                 ret = rte_errno;
     914                 :          0 :                 WARN("ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
     915                 :            :                      " failed: %s",
     916                 :            :                      strerror(rte_errno));
     917                 :          0 :                 goto out;
     918                 :            :         }
     919                 :            :         ret = 0;
     920                 :          0 : out:
     921                 :            :         MLX4_ASSERT(ret >= 0);
     922                 :          0 :         return -ret;
     923                 :            : }
     924                 :            : 
     925                 :            : /**
     926                 :            :  * DPDK callback to retrieve the received packet types that are recognized
     927                 :            :  * by the device.
     928                 :            :  *
     929                 :            :  * @param dev
     930                 :            :  *   Pointer to Ethernet device structure.
     931                 :            :  *
     932                 :            :  * @return
     933                 :            :  *   Pointer to an array of recognized packet types if in Rx burst mode,
     934                 :            :  *   NULL otherwise.
     935                 :            :  */
     936                 :            : const uint32_t *
     937                 :          0 : mlx4_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
     938                 :            : {
     939                 :            :         static const uint32_t ptypes[] = {
     940                 :            :                 /* refers to rxq_cq_to_pkt_type() */
     941                 :            :                 RTE_PTYPE_L2_ETHER,
     942                 :            :                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
     943                 :            :                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
     944                 :            :                 RTE_PTYPE_L4_FRAG,
     945                 :            :                 RTE_PTYPE_L4_TCP,
     946                 :            :                 RTE_PTYPE_L4_UDP,
     947                 :            :         };
     948                 :            :         static const uint32_t ptypes_l2tun[] = {
     949                 :            :                 /* refers to rxq_cq_to_pkt_type() */
     950                 :            :                 RTE_PTYPE_L2_ETHER,
     951                 :            :                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
     952                 :            :                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
     953                 :            :                 RTE_PTYPE_L4_FRAG,
     954                 :            :                 RTE_PTYPE_L4_TCP,
     955                 :            :                 RTE_PTYPE_L4_UDP,
     956                 :            :                 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
     957                 :            :                 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
     958                 :            :         };
     959                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     960                 :            : 
     961         [ #  # ]:          0 :         if (dev->rx_pkt_burst == mlx4_rx_burst) {
     962         [ #  # ]:          0 :                 if (priv->hw_csum_l2tun) {
     963                 :          0 :                         *no_of_elements = RTE_DIM(ptypes_l2tun);
     964                 :          0 :                         return ptypes_l2tun;
     965                 :            :                 } else {
     966                 :          0 :                         *no_of_elements = RTE_DIM(ptypes);
     967                 :          0 :                         return ptypes;
     968                 :            :                 }
     969                 :            :         }
     970                 :            :         return NULL;
     971                 :            : }
     972                 :            : 
     973                 :            : /**
     974                 :            :  * Check if mlx4 device was removed.
     975                 :            :  *
     976                 :            :  * @param dev
     977                 :            :  *   Pointer to Ethernet device structure.
     978                 :            :  *
     979                 :            :  * @return
     980                 :            :  *   1 when device is removed, otherwise 0.
     981                 :            :  */
     982                 :            : int
     983                 :          0 : mlx4_is_removed(struct rte_eth_dev *dev)
     984                 :            : {
     985                 :            :         struct ibv_device_attr device_attr;
     986                 :          0 :         struct mlx4_priv *priv = dev->data->dev_private;
     987                 :            : 
     988         [ #  # ]:          0 :         if (mlx4_glue->query_device(priv->ctx, &device_attr) == EIO)
     989                 :          0 :                 return 1;
     990                 :            :         return 0;
     991                 :            : }

Generated by: LCOV version 1.14