193cc4f0dSTal Shnaiderman /* SPDX-License-Identifier: BSD-3-Clause 293cc4f0dSTal Shnaiderman * Copyright 2020 Mellanox Technologies, Ltd 393cc4f0dSTal Shnaiderman */ 493cc4f0dSTal Shnaiderman #include <stdio.h> 593cc4f0dSTal Shnaiderman 693cc4f0dSTal Shnaiderman #include <rte_errno.h> 793cc4f0dSTal Shnaiderman #include <rte_ether.h> 893cc4f0dSTal Shnaiderman #include <rte_ethdev_driver.h> 993cc4f0dSTal Shnaiderman #include <rte_interrupts.h> 1093cc4f0dSTal Shnaiderman 1193cc4f0dSTal Shnaiderman #include <mlx5_glue.h> 1293cc4f0dSTal Shnaiderman #include <mlx5_devx_cmds.h> 1393cc4f0dSTal Shnaiderman #include <mlx5_common.h> 1493cc4f0dSTal Shnaiderman #include <mlx5_win_ext.h> 1593cc4f0dSTal Shnaiderman #include <mlx5_malloc.h> 1693cc4f0dSTal Shnaiderman #include <mlx5.h> 1799d7c45cSTal Shnaiderman #include <mlx5_utils.h> 1893cc4f0dSTal Shnaiderman 1993cc4f0dSTal Shnaiderman /** 2093cc4f0dSTal Shnaiderman * Get MAC address by querying netdevice. 2193cc4f0dSTal Shnaiderman * 2293cc4f0dSTal Shnaiderman * @param[in] dev 2393cc4f0dSTal Shnaiderman * Pointer to Ethernet device. 2493cc4f0dSTal Shnaiderman * @param[out] mac 2593cc4f0dSTal Shnaiderman * MAC address output buffer. 2693cc4f0dSTal Shnaiderman * 2793cc4f0dSTal Shnaiderman * @return 2893cc4f0dSTal Shnaiderman * 0 on success, a negative errno value otherwise and rte_errno is set. 2993cc4f0dSTal Shnaiderman */ 3093cc4f0dSTal Shnaiderman int 3193cc4f0dSTal Shnaiderman mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[RTE_ETHER_ADDR_LEN]) 3293cc4f0dSTal Shnaiderman { 3393cc4f0dSTal Shnaiderman struct mlx5_priv *priv; 3493cc4f0dSTal Shnaiderman mlx5_context_st *context_obj; 3593cc4f0dSTal Shnaiderman 3693cc4f0dSTal Shnaiderman if (!dev) { 3793cc4f0dSTal Shnaiderman rte_errno = EINVAL; 3893cc4f0dSTal Shnaiderman return -rte_errno; 3993cc4f0dSTal Shnaiderman } 4093cc4f0dSTal Shnaiderman priv = dev->data->dev_private; 4193cc4f0dSTal Shnaiderman context_obj = (mlx5_context_st *)priv->sh->ctx; 4293cc4f0dSTal Shnaiderman memcpy(mac, context_obj->mlx5_dev.eth_mac, RTE_ETHER_ADDR_LEN); 4393cc4f0dSTal Shnaiderman return 0; 4493cc4f0dSTal Shnaiderman } 45b653ce1dSOphir Munk 46b653ce1dSOphir Munk /** 4749c797f8STal Shnaiderman * Get interface name from private structure. 4849c797f8STal Shnaiderman * 4949c797f8STal Shnaiderman * 5049c797f8STal Shnaiderman * @param[in] dev 5149c797f8STal Shnaiderman * Pointer to Ethernet device. 5249c797f8STal Shnaiderman * @param[out] ifname 5349c797f8STal Shnaiderman * Interface name output buffer. 5449c797f8STal Shnaiderman * 5549c797f8STal Shnaiderman * @return 5649c797f8STal Shnaiderman * 0 on success, a negative errno value otherwise and rte_errno is set. 5749c797f8STal Shnaiderman */ 5849c797f8STal Shnaiderman int 5949c797f8STal Shnaiderman mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]) 6049c797f8STal Shnaiderman { 6149c797f8STal Shnaiderman struct mlx5_priv *priv; 6249c797f8STal Shnaiderman mlx5_context_st *context_obj; 6349c797f8STal Shnaiderman 6449c797f8STal Shnaiderman if (!dev) { 6549c797f8STal Shnaiderman rte_errno = EINVAL; 6649c797f8STal Shnaiderman return -rte_errno; 6749c797f8STal Shnaiderman } 6849c797f8STal Shnaiderman priv = dev->data->dev_private; 6949c797f8STal Shnaiderman context_obj = (mlx5_context_st *)priv->sh->ctx; 7049c797f8STal Shnaiderman strncpy(*ifname, context_obj->mlx5_dev.name, IF_NAMESIZE); 7149c797f8STal Shnaiderman return 0; 7249c797f8STal Shnaiderman } 7349c797f8STal Shnaiderman 7449c797f8STal Shnaiderman /** 7507cae8ffSTal Shnaiderman * Get device MTU. 7607cae8ffSTal Shnaiderman * 7707cae8ffSTal Shnaiderman * @param dev 7807cae8ffSTal Shnaiderman * Pointer to Ethernet device. 7907cae8ffSTal Shnaiderman * @param[out] mtu 8007cae8ffSTal Shnaiderman * MTU value output buffer. 8107cae8ffSTal Shnaiderman * 8207cae8ffSTal Shnaiderman * @return 8307cae8ffSTal Shnaiderman * 0 on success, a negative errno value otherwise and rte_errno is set. 8407cae8ffSTal Shnaiderman */ 8507cae8ffSTal Shnaiderman int 8607cae8ffSTal Shnaiderman mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu) 8707cae8ffSTal Shnaiderman { 8807cae8ffSTal Shnaiderman struct mlx5_priv *priv; 8907cae8ffSTal Shnaiderman mlx5_context_st *context_obj; 9007cae8ffSTal Shnaiderman 9107cae8ffSTal Shnaiderman if (!dev) { 9207cae8ffSTal Shnaiderman rte_errno = EINVAL; 9307cae8ffSTal Shnaiderman return -rte_errno; 9407cae8ffSTal Shnaiderman } 9507cae8ffSTal Shnaiderman priv = dev->data->dev_private; 9607cae8ffSTal Shnaiderman context_obj = (mlx5_context_st *)priv->sh->ctx; 9707cae8ffSTal Shnaiderman *mtu = context_obj->mlx5_dev.mtu_bytes; 9807cae8ffSTal Shnaiderman return 0; 9907cae8ffSTal Shnaiderman } 10007cae8ffSTal Shnaiderman 10107cae8ffSTal Shnaiderman /** 102b653ce1dSOphir Munk * Set device MTU. 103b653ce1dSOphir Munk * 104b653ce1dSOphir Munk * @param dev 105b653ce1dSOphir Munk * Pointer to Ethernet device. 106b653ce1dSOphir Munk * @param mtu 107b653ce1dSOphir Munk * MTU value to set. 108b653ce1dSOphir Munk * 109b653ce1dSOphir Munk * @return 110b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise and rte_errno is set. 111b653ce1dSOphir Munk */ 112b653ce1dSOphir Munk int 113b653ce1dSOphir Munk mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 114b653ce1dSOphir Munk { 115b653ce1dSOphir Munk RTE_SET_USED(dev); 116b653ce1dSOphir Munk RTE_SET_USED(mtu); 117b653ce1dSOphir Munk return -ENOTSUP; 118b653ce1dSOphir Munk } 119b653ce1dSOphir Munk 120b653ce1dSOphir Munk /* 121b653ce1dSOphir Munk * Unregister callback handler safely. The handler may be active 122b653ce1dSOphir Munk * while we are trying to unregister it, in this case code -EAGAIN 123b653ce1dSOphir Munk * is returned by rte_intr_callback_unregister(). This routine checks 124b653ce1dSOphir Munk * the return code and tries to unregister handler again. 125b653ce1dSOphir Munk * 126b653ce1dSOphir Munk * @param handle 127b653ce1dSOphir Munk * interrupt handle 128b653ce1dSOphir Munk * @param cb_fn 129b653ce1dSOphir Munk * pointer to callback routine 130b653ce1dSOphir Munk * @cb_arg 131b653ce1dSOphir Munk * opaque callback parameter 132b653ce1dSOphir Munk */ 133b653ce1dSOphir Munk void 134b653ce1dSOphir Munk mlx5_intr_callback_unregister(const struct rte_intr_handle *handle, 135b653ce1dSOphir Munk rte_intr_callback_fn cb_fn, void *cb_arg) 136b653ce1dSOphir Munk { 137b653ce1dSOphir Munk RTE_SET_USED(handle); 138b653ce1dSOphir Munk RTE_SET_USED(cb_fn); 139b653ce1dSOphir Munk RTE_SET_USED(cb_arg); 140b653ce1dSOphir Munk } 141b653ce1dSOphir Munk 142b653ce1dSOphir Munk /** 143b653ce1dSOphir Munk * DPDK callback to get flow control status. 144b653ce1dSOphir Munk * 145b653ce1dSOphir Munk * @param dev 146b653ce1dSOphir Munk * Pointer to Ethernet device structure. 147b653ce1dSOphir Munk * @param[out] fc_conf 148b653ce1dSOphir Munk * Flow control output buffer. 149b653ce1dSOphir Munk * 150b653ce1dSOphir Munk * @return 151b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise and rte_errno is set. 152b653ce1dSOphir Munk */ 153b653ce1dSOphir Munk int 154b653ce1dSOphir Munk mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 155b653ce1dSOphir Munk { 156b653ce1dSOphir Munk RTE_SET_USED(dev); 157b653ce1dSOphir Munk RTE_SET_USED(fc_conf); 158b653ce1dSOphir Munk return -ENOTSUP; 159b653ce1dSOphir Munk } 160b653ce1dSOphir Munk 161b653ce1dSOphir Munk /** 162b653ce1dSOphir Munk * DPDK callback to modify flow control parameters. 163b653ce1dSOphir Munk * 164b653ce1dSOphir Munk * @param dev 165b653ce1dSOphir Munk * Pointer to Ethernet device structure. 166b653ce1dSOphir Munk * @param[in] fc_conf 167b653ce1dSOphir Munk * Flow control parameters. 168b653ce1dSOphir Munk * 169b653ce1dSOphir Munk * @return 170b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise and rte_errno is set. 171b653ce1dSOphir Munk */ 172b653ce1dSOphir Munk int 173b653ce1dSOphir Munk mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 174b653ce1dSOphir Munk { 175b653ce1dSOphir Munk RTE_SET_USED(dev); 176b653ce1dSOphir Munk RTE_SET_USED(fc_conf); 177b653ce1dSOphir Munk return -ENOTSUP; 178b653ce1dSOphir Munk } 179b653ce1dSOphir Munk 180b653ce1dSOphir Munk /** 181b653ce1dSOphir Munk * Query the number of statistics provided by ETHTOOL. 182b653ce1dSOphir Munk * 183b653ce1dSOphir Munk * @param dev 184b653ce1dSOphir Munk * Pointer to Ethernet device. 185b653ce1dSOphir Munk * 186b653ce1dSOphir Munk * @return 187b653ce1dSOphir Munk * Number of statistics on success, negative errno value otherwise and 188b653ce1dSOphir Munk * rte_errno is set. 189b653ce1dSOphir Munk */ 190b653ce1dSOphir Munk int 191b653ce1dSOphir Munk mlx5_os_get_stats_n(struct rte_eth_dev *dev) 192b653ce1dSOphir Munk { 193b653ce1dSOphir Munk RTE_SET_USED(dev); 194b653ce1dSOphir Munk return -ENOTSUP; 195b653ce1dSOphir Munk } 196b653ce1dSOphir Munk 197b653ce1dSOphir Munk /** 198b653ce1dSOphir Munk * Init the structures to read device counters. 199b653ce1dSOphir Munk * 200b653ce1dSOphir Munk * @param dev 201b653ce1dSOphir Munk * Pointer to Ethernet device. 202b653ce1dSOphir Munk */ 203b653ce1dSOphir Munk void 204b653ce1dSOphir Munk mlx5_os_stats_init(struct rte_eth_dev *dev) 205b653ce1dSOphir Munk { 206b653ce1dSOphir Munk RTE_SET_USED(dev); 207b653ce1dSOphir Munk } 208b653ce1dSOphir Munk 209b653ce1dSOphir Munk /** 210b653ce1dSOphir Munk * Read device counters table. 211b653ce1dSOphir Munk * 212b653ce1dSOphir Munk * @param dev 213b653ce1dSOphir Munk * Pointer to Ethernet device. 214b653ce1dSOphir Munk * @param[out] stats 215b653ce1dSOphir Munk * Counters table output buffer. 216b653ce1dSOphir Munk * 217b653ce1dSOphir Munk * @return 218b653ce1dSOphir Munk * 0 on success and stats is filled, negative errno value otherwise and 219b653ce1dSOphir Munk * rte_errno is set. 220b653ce1dSOphir Munk */ 221b653ce1dSOphir Munk int 222b653ce1dSOphir Munk mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 223b653ce1dSOphir Munk { 224b653ce1dSOphir Munk RTE_SET_USED(dev); 225b653ce1dSOphir Munk RTE_SET_USED(stats); 226b653ce1dSOphir Munk return -ENOTSUP; 227b653ce1dSOphir Munk } 228b653ce1dSOphir Munk 229b653ce1dSOphir Munk /** 2306fbd7370STal Shnaiderman * DPDK callback to retrieve physical link information. 2316fbd7370STal Shnaiderman * 2326fbd7370STal Shnaiderman * @param dev 2336fbd7370STal Shnaiderman * Pointer to Ethernet device structure. 2346fbd7370STal Shnaiderman * @param wait_to_complete 2356fbd7370STal Shnaiderman * Wait for request completion. 2366fbd7370STal Shnaiderman * 2376fbd7370STal Shnaiderman * @return 2386fbd7370STal Shnaiderman * 0 if link status was not updated, positive if it was, a negative errno 2396fbd7370STal Shnaiderman * value otherwise and rte_errno is set. 2406fbd7370STal Shnaiderman */ 2416fbd7370STal Shnaiderman int 2426fbd7370STal Shnaiderman mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) 2436fbd7370STal Shnaiderman { 2446fbd7370STal Shnaiderman RTE_SET_USED(wait_to_complete); 2456fbd7370STal Shnaiderman struct mlx5_priv *priv; 2466fbd7370STal Shnaiderman mlx5_context_st *context_obj; 2476fbd7370STal Shnaiderman struct rte_eth_link dev_link; 2486fbd7370STal Shnaiderman int ret; 2496fbd7370STal Shnaiderman 2506fbd7370STal Shnaiderman ret = 0; 2516fbd7370STal Shnaiderman if (!dev) { 2526fbd7370STal Shnaiderman rte_errno = EINVAL; 2536fbd7370STal Shnaiderman return -rte_errno; 2546fbd7370STal Shnaiderman } 2556fbd7370STal Shnaiderman priv = dev->data->dev_private; 2566fbd7370STal Shnaiderman context_obj = (mlx5_context_st *)priv->sh->ctx; 2576fbd7370STal Shnaiderman dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1024 * 1024); 2586fbd7370STal Shnaiderman dev_link.link_status = 2596fbd7370STal Shnaiderman (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev)) 2606fbd7370STal Shnaiderman ? 1 : 0; 2616fbd7370STal Shnaiderman dev_link.link_duplex = 1; 2626fbd7370STal Shnaiderman if (dev->data->dev_link.link_speed != dev_link.link_speed || 2636fbd7370STal Shnaiderman dev->data->dev_link.link_duplex != dev_link.link_duplex || 2646fbd7370STal Shnaiderman dev->data->dev_link.link_autoneg != dev_link.link_autoneg || 2656fbd7370STal Shnaiderman dev->data->dev_link.link_status != dev_link.link_status) 2666fbd7370STal Shnaiderman ret = 1; 2676fbd7370STal Shnaiderman else 2686fbd7370STal Shnaiderman ret = 0; 2696fbd7370STal Shnaiderman dev->data->dev_link = dev_link; 2706fbd7370STal Shnaiderman return ret; 2716fbd7370STal Shnaiderman } 2726fbd7370STal Shnaiderman 2736fbd7370STal Shnaiderman /** 274b653ce1dSOphir Munk * DPDK callback to bring the link DOWN. 275b653ce1dSOphir Munk * 276b653ce1dSOphir Munk * @param dev 277b653ce1dSOphir Munk * Pointer to Ethernet device structure. 278b653ce1dSOphir Munk * 279b653ce1dSOphir Munk * @return 280b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise 281b653ce1dSOphir Munk */ 282b653ce1dSOphir Munk int 283b653ce1dSOphir Munk mlx5_set_link_down(struct rte_eth_dev *dev) 284b653ce1dSOphir Munk { 285b653ce1dSOphir Munk RTE_SET_USED(dev); 286b653ce1dSOphir Munk return -ENOTSUP; 287b653ce1dSOphir Munk } 288b653ce1dSOphir Munk 289b653ce1dSOphir Munk /** 290b653ce1dSOphir Munk * DPDK callback to bring the link UP. 291b653ce1dSOphir Munk * 292b653ce1dSOphir Munk * @param dev 293b653ce1dSOphir Munk * Pointer to Ethernet device structure. 294b653ce1dSOphir Munk * 295b653ce1dSOphir Munk * @return 296b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise 297b653ce1dSOphir Munk */ 298b653ce1dSOphir Munk int 299b653ce1dSOphir Munk mlx5_set_link_up(struct rte_eth_dev *dev) 300b653ce1dSOphir Munk { 301b653ce1dSOphir Munk RTE_SET_USED(dev); 302b653ce1dSOphir Munk return -ENOTSUP; 303b653ce1dSOphir Munk } 304b653ce1dSOphir Munk 305b653ce1dSOphir Munk /** 306b653ce1dSOphir Munk * DPDK callback to retrieve plug-in module EEPROM information (type and size). 307b653ce1dSOphir Munk * 308b653ce1dSOphir Munk * @param dev 309b653ce1dSOphir Munk * Pointer to Ethernet device structure. 310b653ce1dSOphir Munk * @param[out] modinfo 311b653ce1dSOphir Munk * Storage for plug-in module EEPROM information. 312b653ce1dSOphir Munk * 313b653ce1dSOphir Munk * @return 314b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise and rte_errno is set. 315b653ce1dSOphir Munk */ 316b653ce1dSOphir Munk int 317b653ce1dSOphir Munk mlx5_get_module_info(struct rte_eth_dev *dev, 318b653ce1dSOphir Munk struct rte_eth_dev_module_info *modinfo) 319b653ce1dSOphir Munk { 320b653ce1dSOphir Munk RTE_SET_USED(dev); 321b653ce1dSOphir Munk RTE_SET_USED(modinfo); 322b653ce1dSOphir Munk return -ENOTSUP; 323b653ce1dSOphir Munk } 324b653ce1dSOphir Munk 325b653ce1dSOphir Munk /** 326b653ce1dSOphir Munk * DPDK callback to retrieve plug-in module EEPROM data. 327b653ce1dSOphir Munk * 328b653ce1dSOphir Munk * @param dev 329b653ce1dSOphir Munk * Pointer to Ethernet device structure. 330b653ce1dSOphir Munk * @param[out] info 331b653ce1dSOphir Munk * Storage for plug-in module EEPROM data. 332b653ce1dSOphir Munk * 333b653ce1dSOphir Munk * @return 334b653ce1dSOphir Munk * 0 on success, a negative errno value otherwise and rte_errno is set. 335b653ce1dSOphir Munk */ 336b653ce1dSOphir Munk int mlx5_get_module_eeprom(struct rte_eth_dev *dev, 337b653ce1dSOphir Munk struct rte_dev_eeprom_info *info) 338b653ce1dSOphir Munk { 339b653ce1dSOphir Munk RTE_SET_USED(dev); 340b653ce1dSOphir Munk RTE_SET_USED(info); 341b653ce1dSOphir Munk return -ENOTSUP; 342b653ce1dSOphir Munk } 34399d7c45cSTal Shnaiderman 34499d7c45cSTal Shnaiderman /** 34599d7c45cSTal Shnaiderman * Get device current raw clock counter 34699d7c45cSTal Shnaiderman * 34799d7c45cSTal Shnaiderman * @param dev 34899d7c45cSTal Shnaiderman * Pointer to Ethernet device structure. 34999d7c45cSTal Shnaiderman * @param[out] time 35099d7c45cSTal Shnaiderman * Current raw clock counter of the device. 35199d7c45cSTal Shnaiderman * 35299d7c45cSTal Shnaiderman * @return 35399d7c45cSTal Shnaiderman * 0 if the clock has correctly been read 35499d7c45cSTal Shnaiderman * The value of errno in case of error 35599d7c45cSTal Shnaiderman */ 35699d7c45cSTal Shnaiderman int 35799d7c45cSTal Shnaiderman mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) 35899d7c45cSTal Shnaiderman { 35999d7c45cSTal Shnaiderman int err; 36099d7c45cSTal Shnaiderman struct mlx5_devx_clock mlx5_clock; 36199d7c45cSTal Shnaiderman struct mlx5_priv *priv = dev->data->dev_private; 36299d7c45cSTal Shnaiderman mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->ctx; 36399d7c45cSTal Shnaiderman 36499d7c45cSTal Shnaiderman err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock); 36599d7c45cSTal Shnaiderman if (err != 0) { 36699d7c45cSTal Shnaiderman DRV_LOG(WARNING, "Could not query the clock"); 36799d7c45cSTal Shnaiderman return err; 36899d7c45cSTal Shnaiderman } 36999d7c45cSTal Shnaiderman *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer; 37099d7c45cSTal Shnaiderman return 0; 37199d7c45cSTal Shnaiderman } 372*165e5d07STal Shnaiderman 373*165e5d07STal Shnaiderman /** 374*165e5d07STal Shnaiderman * Check if mlx5 device was removed. 375*165e5d07STal Shnaiderman * 376*165e5d07STal Shnaiderman * @param dev 377*165e5d07STal Shnaiderman * Pointer to Ethernet device structure. 378*165e5d07STal Shnaiderman * 379*165e5d07STal Shnaiderman * @return 380*165e5d07STal Shnaiderman * 1 when device is removed, otherwise 0. 381*165e5d07STal Shnaiderman */ 382*165e5d07STal Shnaiderman int 383*165e5d07STal Shnaiderman mlx5_is_removed(struct rte_eth_dev *dev) 384*165e5d07STal Shnaiderman { 385*165e5d07STal Shnaiderman struct mlx5_priv *priv = dev->data->dev_private; 386*165e5d07STal Shnaiderman mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->ctx; 387*165e5d07STal Shnaiderman 388*165e5d07STal Shnaiderman if (*context_obj->shutdown_event_obj.p_flag) 389*165e5d07STal Shnaiderman return 1; 390*165e5d07STal Shnaiderman return 0; 391*165e5d07STal Shnaiderman } 392