12f97422eSNelio Laranjeiro /*- 22f97422eSNelio Laranjeiro * BSD LICENSE 32f97422eSNelio Laranjeiro * 42f97422eSNelio Laranjeiro * Copyright 2015 6WIND S.A. 52f97422eSNelio Laranjeiro * Copyright 2015 Mellanox. 62f97422eSNelio Laranjeiro * 72f97422eSNelio Laranjeiro * Redistribution and use in source and binary forms, with or without 82f97422eSNelio Laranjeiro * modification, are permitted provided that the following conditions 92f97422eSNelio Laranjeiro * are met: 102f97422eSNelio Laranjeiro * 112f97422eSNelio Laranjeiro * * Redistributions of source code must retain the above copyright 122f97422eSNelio Laranjeiro * notice, this list of conditions and the following disclaimer. 132f97422eSNelio Laranjeiro * * Redistributions in binary form must reproduce the above copyright 142f97422eSNelio Laranjeiro * notice, this list of conditions and the following disclaimer in 152f97422eSNelio Laranjeiro * the documentation and/or other materials provided with the 162f97422eSNelio Laranjeiro * distribution. 172f97422eSNelio Laranjeiro * * Neither the name of 6WIND S.A. nor the names of its 182f97422eSNelio Laranjeiro * contributors may be used to endorse or promote products derived 192f97422eSNelio Laranjeiro * from this software without specific prior written permission. 202f97422eSNelio Laranjeiro * 212f97422eSNelio Laranjeiro * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 222f97422eSNelio Laranjeiro * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 232f97422eSNelio Laranjeiro * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 242f97422eSNelio Laranjeiro * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 252f97422eSNelio Laranjeiro * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 262f97422eSNelio Laranjeiro * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 272f97422eSNelio Laranjeiro * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 282f97422eSNelio Laranjeiro * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 292f97422eSNelio Laranjeiro * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 302f97422eSNelio Laranjeiro * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 312f97422eSNelio Laranjeiro * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 322f97422eSNelio Laranjeiro */ 332f97422eSNelio Laranjeiro 342f97422eSNelio Laranjeiro #include <stddef.h> 352f97422eSNelio Laranjeiro #include <stdint.h> 362f97422eSNelio Laranjeiro #include <errno.h> 372f97422eSNelio Laranjeiro #include <string.h> 382f97422eSNelio Laranjeiro #include <assert.h> 392f97422eSNelio Laranjeiro 402f97422eSNelio Laranjeiro /* Verbs header. */ 412f97422eSNelio Laranjeiro /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ 422f97422eSNelio Laranjeiro #ifdef PEDANTIC 43fc5b160fSBruce Richardson #pragma GCC diagnostic ignored "-Wpedantic" 442f97422eSNelio Laranjeiro #endif 452f97422eSNelio Laranjeiro #include <infiniband/verbs.h> 462f97422eSNelio Laranjeiro #ifdef PEDANTIC 47fc5b160fSBruce Richardson #pragma GCC diagnostic error "-Wpedantic" 482f97422eSNelio Laranjeiro #endif 492f97422eSNelio Laranjeiro 502f97422eSNelio Laranjeiro #include <rte_malloc.h> 512f97422eSNelio Laranjeiro #include <rte_ethdev.h> 522f97422eSNelio Laranjeiro 532f97422eSNelio Laranjeiro #include "mlx5.h" 542f97422eSNelio Laranjeiro #include "mlx5_rxtx.h" 552f97422eSNelio Laranjeiro 562f97422eSNelio Laranjeiro /** 570573873dSNelio Laranjeiro * Get a RSS configuration hash key. 580573873dSNelio Laranjeiro * 590573873dSNelio Laranjeiro * @param priv 600573873dSNelio Laranjeiro * Pointer to private structure. 610573873dSNelio Laranjeiro * @param rss_hf 620573873dSNelio Laranjeiro * RSS hash functions configuration must be retrieved for. 630573873dSNelio Laranjeiro * 640573873dSNelio Laranjeiro * @return 650573873dSNelio Laranjeiro * Pointer to a RSS configuration structure or NULL if rss_hf cannot 660573873dSNelio Laranjeiro * be matched. 670573873dSNelio Laranjeiro */ 680573873dSNelio Laranjeiro static struct rte_eth_rss_conf * 690573873dSNelio Laranjeiro rss_hash_get(struct priv *priv, uint64_t rss_hf) 700573873dSNelio Laranjeiro { 710573873dSNelio Laranjeiro unsigned int i; 720573873dSNelio Laranjeiro 730573873dSNelio Laranjeiro for (i = 0; (i != hash_rxq_init_n); ++i) { 740573873dSNelio Laranjeiro uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf; 750573873dSNelio Laranjeiro 760573873dSNelio Laranjeiro if (!(dpdk_rss_hf & rss_hf)) 770573873dSNelio Laranjeiro continue; 780573873dSNelio Laranjeiro return (*priv->rss_conf)[i]; 790573873dSNelio Laranjeiro } 800573873dSNelio Laranjeiro return NULL; 810573873dSNelio Laranjeiro } 820573873dSNelio Laranjeiro 830573873dSNelio Laranjeiro /** 842f97422eSNelio Laranjeiro * Register a RSS key. 852f97422eSNelio Laranjeiro * 862f97422eSNelio Laranjeiro * @param priv 872f97422eSNelio Laranjeiro * Pointer to private structure. 882f97422eSNelio Laranjeiro * @param key 892f97422eSNelio Laranjeiro * Hash key to register. 902f97422eSNelio Laranjeiro * @param key_len 912f97422eSNelio Laranjeiro * Hash key length in bytes. 920573873dSNelio Laranjeiro * @param rss_hf 930573873dSNelio Laranjeiro * RSS hash functions the provided key applies to. 942f97422eSNelio Laranjeiro * 952f97422eSNelio Laranjeiro * @return 962f97422eSNelio Laranjeiro * 0 on success, errno value on failure. 972f97422eSNelio Laranjeiro */ 982f97422eSNelio Laranjeiro int 992f97422eSNelio Laranjeiro rss_hash_rss_conf_new_key(struct priv *priv, const uint8_t *key, 1000573873dSNelio Laranjeiro unsigned int key_len, uint64_t rss_hf) 1012f97422eSNelio Laranjeiro { 1020573873dSNelio Laranjeiro unsigned int i; 1032f97422eSNelio Laranjeiro 1040573873dSNelio Laranjeiro for (i = 0; (i != hash_rxq_init_n); ++i) { 1050573873dSNelio Laranjeiro struct rte_eth_rss_conf *rss_conf; 1060573873dSNelio Laranjeiro uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf; 1070573873dSNelio Laranjeiro 1080573873dSNelio Laranjeiro if (!(dpdk_rss_hf & rss_hf)) 1090573873dSNelio Laranjeiro continue; 1100573873dSNelio Laranjeiro rss_conf = rte_realloc((*priv->rss_conf)[i], 1112f97422eSNelio Laranjeiro (sizeof(*rss_conf) + key_len), 1122f97422eSNelio Laranjeiro 0); 1132f97422eSNelio Laranjeiro if (!rss_conf) 1142f97422eSNelio Laranjeiro return ENOMEM; 1152f97422eSNelio Laranjeiro rss_conf->rss_key = (void *)(rss_conf + 1); 1162f97422eSNelio Laranjeiro rss_conf->rss_key_len = key_len; 1170573873dSNelio Laranjeiro rss_conf->rss_hf = dpdk_rss_hf; 1182f97422eSNelio Laranjeiro memcpy(rss_conf->rss_key, key, key_len); 1190573873dSNelio Laranjeiro (*priv->rss_conf)[i] = rss_conf; 1200573873dSNelio Laranjeiro } 1212f97422eSNelio Laranjeiro return 0; 1222f97422eSNelio Laranjeiro } 1232f97422eSNelio Laranjeiro 1242f97422eSNelio Laranjeiro /** 1252f97422eSNelio Laranjeiro * DPDK callback to update the RSS hash configuration. 1262f97422eSNelio Laranjeiro * 1272f97422eSNelio Laranjeiro * @param dev 1282f97422eSNelio Laranjeiro * Pointer to Ethernet device structure. 1292f97422eSNelio Laranjeiro * @param[in] rss_conf 1302f97422eSNelio Laranjeiro * RSS configuration data. 1312f97422eSNelio Laranjeiro * 1322f97422eSNelio Laranjeiro * @return 1332f97422eSNelio Laranjeiro * 0 on success, negative errno value on failure. 1342f97422eSNelio Laranjeiro */ 1352f97422eSNelio Laranjeiro int 1362f97422eSNelio Laranjeiro mlx5_rss_hash_update(struct rte_eth_dev *dev, 1372f97422eSNelio Laranjeiro struct rte_eth_rss_conf *rss_conf) 1382f97422eSNelio Laranjeiro { 1392f97422eSNelio Laranjeiro struct priv *priv = dev->data->dev_private; 1402f97422eSNelio Laranjeiro int err = 0; 1412f97422eSNelio Laranjeiro 1422f97422eSNelio Laranjeiro priv_lock(priv); 1432f97422eSNelio Laranjeiro 1442f97422eSNelio Laranjeiro assert(priv->rss_conf != NULL); 1452f97422eSNelio Laranjeiro 1462f97422eSNelio Laranjeiro /* Apply configuration. */ 1472f97422eSNelio Laranjeiro if (rss_conf->rss_key) 1482f97422eSNelio Laranjeiro err = rss_hash_rss_conf_new_key(priv, 1492f97422eSNelio Laranjeiro rss_conf->rss_key, 1500573873dSNelio Laranjeiro rss_conf->rss_key_len, 1510573873dSNelio Laranjeiro rss_conf->rss_hf); 152c64ccc0eSNélio Laranjeiro /* Store protocols for which RSS is enabled. */ 153c64ccc0eSNélio Laranjeiro priv->rss_hf = rss_conf->rss_hf; 1542f97422eSNelio Laranjeiro priv_unlock(priv); 1552f97422eSNelio Laranjeiro assert(err >= 0); 1562f97422eSNelio Laranjeiro return -err; 1572f97422eSNelio Laranjeiro } 1582f97422eSNelio Laranjeiro 1592f97422eSNelio Laranjeiro /** 1602f97422eSNelio Laranjeiro * DPDK callback to get the RSS hash configuration. 1612f97422eSNelio Laranjeiro * 1622f97422eSNelio Laranjeiro * @param dev 1632f97422eSNelio Laranjeiro * Pointer to Ethernet device structure. 1642f97422eSNelio Laranjeiro * @param[in, out] rss_conf 1652f97422eSNelio Laranjeiro * RSS configuration data. 1662f97422eSNelio Laranjeiro * 1672f97422eSNelio Laranjeiro * @return 1682f97422eSNelio Laranjeiro * 0 on success, negative errno value on failure. 1692f97422eSNelio Laranjeiro */ 1702f97422eSNelio Laranjeiro int 1712f97422eSNelio Laranjeiro mlx5_rss_hash_conf_get(struct rte_eth_dev *dev, 1722f97422eSNelio Laranjeiro struct rte_eth_rss_conf *rss_conf) 1732f97422eSNelio Laranjeiro { 1742f97422eSNelio Laranjeiro struct priv *priv = dev->data->dev_private; 1750573873dSNelio Laranjeiro struct rte_eth_rss_conf *priv_rss_conf; 1762f97422eSNelio Laranjeiro 1772f97422eSNelio Laranjeiro priv_lock(priv); 1782f97422eSNelio Laranjeiro 1792f97422eSNelio Laranjeiro assert(priv->rss_conf != NULL); 1802f97422eSNelio Laranjeiro 1810573873dSNelio Laranjeiro priv_rss_conf = rss_hash_get(priv, rss_conf->rss_hf); 1820573873dSNelio Laranjeiro if (!priv_rss_conf) { 1830573873dSNelio Laranjeiro rss_conf->rss_hf = 0; 1840573873dSNelio Laranjeiro priv_unlock(priv); 1850573873dSNelio Laranjeiro return -EINVAL; 1860573873dSNelio Laranjeiro } 1872f97422eSNelio Laranjeiro if (rss_conf->rss_key && 1880573873dSNelio Laranjeiro rss_conf->rss_key_len >= priv_rss_conf->rss_key_len) 1892f97422eSNelio Laranjeiro memcpy(rss_conf->rss_key, 1900573873dSNelio Laranjeiro priv_rss_conf->rss_key, 1910573873dSNelio Laranjeiro priv_rss_conf->rss_key_len); 1920573873dSNelio Laranjeiro rss_conf->rss_key_len = priv_rss_conf->rss_key_len; 1930573873dSNelio Laranjeiro rss_conf->rss_hf = priv_rss_conf->rss_hf; 1942f97422eSNelio Laranjeiro 1952f97422eSNelio Laranjeiro priv_unlock(priv); 1962f97422eSNelio Laranjeiro return 0; 1972f97422eSNelio Laranjeiro } 198634efbc2SNelio Laranjeiro 199634efbc2SNelio Laranjeiro /** 200634efbc2SNelio Laranjeiro * Allocate/reallocate RETA index table. 201634efbc2SNelio Laranjeiro * 202634efbc2SNelio Laranjeiro * @param priv 203634efbc2SNelio Laranjeiro * Pointer to private structure. 204634efbc2SNelio Laranjeiro * @praram reta_size 205634efbc2SNelio Laranjeiro * The size of the array to allocate. 206634efbc2SNelio Laranjeiro * 207634efbc2SNelio Laranjeiro * @return 208634efbc2SNelio Laranjeiro * 0 on success, errno value on failure. 209634efbc2SNelio Laranjeiro */ 210634efbc2SNelio Laranjeiro int 211634efbc2SNelio Laranjeiro priv_rss_reta_index_resize(struct priv *priv, unsigned int reta_size) 212634efbc2SNelio Laranjeiro { 213634efbc2SNelio Laranjeiro void *mem; 214634efbc2SNelio Laranjeiro unsigned int old_size = priv->reta_idx_n; 215634efbc2SNelio Laranjeiro 216634efbc2SNelio Laranjeiro if (priv->reta_idx_n == reta_size) 217634efbc2SNelio Laranjeiro return 0; 218634efbc2SNelio Laranjeiro 219634efbc2SNelio Laranjeiro mem = rte_realloc(priv->reta_idx, 220634efbc2SNelio Laranjeiro reta_size * sizeof((*priv->reta_idx)[0]), 0); 221634efbc2SNelio Laranjeiro if (!mem) 222634efbc2SNelio Laranjeiro return ENOMEM; 223634efbc2SNelio Laranjeiro priv->reta_idx = mem; 224634efbc2SNelio Laranjeiro priv->reta_idx_n = reta_size; 225634efbc2SNelio Laranjeiro 226634efbc2SNelio Laranjeiro if (old_size < reta_size) 227634efbc2SNelio Laranjeiro memset(&(*priv->reta_idx)[old_size], 0, 228634efbc2SNelio Laranjeiro (reta_size - old_size) * 229634efbc2SNelio Laranjeiro sizeof((*priv->reta_idx)[0])); 230634efbc2SNelio Laranjeiro return 0; 231634efbc2SNelio Laranjeiro } 232634efbc2SNelio Laranjeiro 233634efbc2SNelio Laranjeiro /** 234634efbc2SNelio Laranjeiro * Query RETA table. 235634efbc2SNelio Laranjeiro * 236634efbc2SNelio Laranjeiro * @param priv 237634efbc2SNelio Laranjeiro * Pointer to private structure. 238634efbc2SNelio Laranjeiro * @param[in, out] reta_conf 239634efbc2SNelio Laranjeiro * Pointer to the first RETA configuration structure. 240634efbc2SNelio Laranjeiro * @param reta_size 241634efbc2SNelio Laranjeiro * Number of entries. 242634efbc2SNelio Laranjeiro * 243634efbc2SNelio Laranjeiro * @return 244634efbc2SNelio Laranjeiro * 0 on success, errno value on failure. 245634efbc2SNelio Laranjeiro */ 246634efbc2SNelio Laranjeiro static int 247634efbc2SNelio Laranjeiro priv_dev_rss_reta_query(struct priv *priv, 248634efbc2SNelio Laranjeiro struct rte_eth_rss_reta_entry64 *reta_conf, 249634efbc2SNelio Laranjeiro unsigned int reta_size) 250634efbc2SNelio Laranjeiro { 251634efbc2SNelio Laranjeiro unsigned int idx; 252634efbc2SNelio Laranjeiro unsigned int i; 253634efbc2SNelio Laranjeiro 254d365210eSYongseok Koh if (!reta_size || reta_size > priv->reta_idx_n) 255d365210eSYongseok Koh return EINVAL; 256634efbc2SNelio Laranjeiro /* Fill each entry of the table even if its bit is not set. */ 257634efbc2SNelio Laranjeiro for (idx = 0, i = 0; (i != reta_size); ++i) { 258634efbc2SNelio Laranjeiro idx = i / RTE_RETA_GROUP_SIZE; 259634efbc2SNelio Laranjeiro reta_conf[idx].reta[i % RTE_RETA_GROUP_SIZE] = 260634efbc2SNelio Laranjeiro (*priv->reta_idx)[i]; 261634efbc2SNelio Laranjeiro } 262634efbc2SNelio Laranjeiro return 0; 263634efbc2SNelio Laranjeiro } 264634efbc2SNelio Laranjeiro 265634efbc2SNelio Laranjeiro /** 266634efbc2SNelio Laranjeiro * Update RETA table. 267634efbc2SNelio Laranjeiro * 268634efbc2SNelio Laranjeiro * @param priv 269634efbc2SNelio Laranjeiro * Pointer to private structure. 270634efbc2SNelio Laranjeiro * @param[in] reta_conf 271634efbc2SNelio Laranjeiro * Pointer to the first RETA configuration structure. 272634efbc2SNelio Laranjeiro * @param reta_size 273634efbc2SNelio Laranjeiro * Number of entries. 274634efbc2SNelio Laranjeiro * 275634efbc2SNelio Laranjeiro * @return 276634efbc2SNelio Laranjeiro * 0 on success, errno value on failure. 277634efbc2SNelio Laranjeiro */ 278634efbc2SNelio Laranjeiro static int 279634efbc2SNelio Laranjeiro priv_dev_rss_reta_update(struct priv *priv, 280634efbc2SNelio Laranjeiro struct rte_eth_rss_reta_entry64 *reta_conf, 281634efbc2SNelio Laranjeiro unsigned int reta_size) 282634efbc2SNelio Laranjeiro { 283634efbc2SNelio Laranjeiro unsigned int idx; 284634efbc2SNelio Laranjeiro unsigned int i; 285634efbc2SNelio Laranjeiro unsigned int pos; 286634efbc2SNelio Laranjeiro int ret; 287634efbc2SNelio Laranjeiro 288d365210eSYongseok Koh if (!reta_size) 289d365210eSYongseok Koh return EINVAL; 290d365210eSYongseok Koh ret = priv_rss_reta_index_resize(priv, reta_size); 291634efbc2SNelio Laranjeiro if (ret) 292634efbc2SNelio Laranjeiro return ret; 293634efbc2SNelio Laranjeiro 294634efbc2SNelio Laranjeiro for (idx = 0, i = 0; (i != reta_size); ++i) { 295634efbc2SNelio Laranjeiro idx = i / RTE_RETA_GROUP_SIZE; 296634efbc2SNelio Laranjeiro pos = i % RTE_RETA_GROUP_SIZE; 297634efbc2SNelio Laranjeiro if (((reta_conf[idx].mask >> i) & 0x1) == 0) 298634efbc2SNelio Laranjeiro continue; 299634efbc2SNelio Laranjeiro assert(reta_conf[idx].reta[pos] < priv->rxqs_n); 300634efbc2SNelio Laranjeiro (*priv->reta_idx)[i] = reta_conf[idx].reta[pos]; 301634efbc2SNelio Laranjeiro } 302634efbc2SNelio Laranjeiro return 0; 303634efbc2SNelio Laranjeiro } 304634efbc2SNelio Laranjeiro 305634efbc2SNelio Laranjeiro /** 306634efbc2SNelio Laranjeiro * DPDK callback to get the RETA indirection table. 307634efbc2SNelio Laranjeiro * 308634efbc2SNelio Laranjeiro * @param dev 309634efbc2SNelio Laranjeiro * Pointer to Ethernet device structure. 310634efbc2SNelio Laranjeiro * @param reta_conf 311634efbc2SNelio Laranjeiro * Pointer to RETA configuration structure array. 312634efbc2SNelio Laranjeiro * @param reta_size 313634efbc2SNelio Laranjeiro * Size of the RETA table. 314634efbc2SNelio Laranjeiro * 315634efbc2SNelio Laranjeiro * @return 316634efbc2SNelio Laranjeiro * 0 on success, negative errno value on failure. 317634efbc2SNelio Laranjeiro */ 318634efbc2SNelio Laranjeiro int 319634efbc2SNelio Laranjeiro mlx5_dev_rss_reta_query(struct rte_eth_dev *dev, 320634efbc2SNelio Laranjeiro struct rte_eth_rss_reta_entry64 *reta_conf, 321634efbc2SNelio Laranjeiro uint16_t reta_size) 322634efbc2SNelio Laranjeiro { 323634efbc2SNelio Laranjeiro int ret; 324634efbc2SNelio Laranjeiro struct priv *priv = dev->data->dev_private; 325634efbc2SNelio Laranjeiro 326634efbc2SNelio Laranjeiro priv_lock(priv); 327634efbc2SNelio Laranjeiro ret = priv_dev_rss_reta_query(priv, reta_conf, reta_size); 328634efbc2SNelio Laranjeiro priv_unlock(priv); 329634efbc2SNelio Laranjeiro return -ret; 330634efbc2SNelio Laranjeiro } 331634efbc2SNelio Laranjeiro 332634efbc2SNelio Laranjeiro /** 333634efbc2SNelio Laranjeiro * DPDK callback to update the RETA indirection table. 334634efbc2SNelio Laranjeiro * 335634efbc2SNelio Laranjeiro * @param dev 336634efbc2SNelio Laranjeiro * Pointer to Ethernet device structure. 337634efbc2SNelio Laranjeiro * @param reta_conf 338634efbc2SNelio Laranjeiro * Pointer to RETA configuration structure array. 339634efbc2SNelio Laranjeiro * @param reta_size 340634efbc2SNelio Laranjeiro * Size of the RETA table. 341634efbc2SNelio Laranjeiro * 342634efbc2SNelio Laranjeiro * @return 343634efbc2SNelio Laranjeiro * 0 on success, negative errno value on failure. 344634efbc2SNelio Laranjeiro */ 345634efbc2SNelio Laranjeiro int 346634efbc2SNelio Laranjeiro mlx5_dev_rss_reta_update(struct rte_eth_dev *dev, 347634efbc2SNelio Laranjeiro struct rte_eth_rss_reta_entry64 *reta_conf, 348634efbc2SNelio Laranjeiro uint16_t reta_size) 349634efbc2SNelio Laranjeiro { 350634efbc2SNelio Laranjeiro int ret; 351634efbc2SNelio Laranjeiro struct priv *priv = dev->data->dev_private; 352634efbc2SNelio Laranjeiro 353aee1b165SXueming Li assert(!mlx5_is_secondary()); 354634efbc2SNelio Laranjeiro priv_lock(priv); 355634efbc2SNelio Laranjeiro ret = priv_dev_rss_reta_update(priv, reta_conf, reta_size); 356634efbc2SNelio Laranjeiro priv_unlock(priv); 357*3f2fe392SNélio Laranjeiro if (dev->data->dev_started) { 358*3f2fe392SNélio Laranjeiro mlx5_dev_stop(dev); 359*3f2fe392SNélio Laranjeiro mlx5_dev_start(dev); 360*3f2fe392SNélio Laranjeiro } 361634efbc2SNelio Laranjeiro return -ret; 362634efbc2SNelio Laranjeiro } 363