1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020 Mellanox Technologies, Ltd 3 */ 4 #include <stdio.h> 5 6 #include <rte_errno.h> 7 #include <rte_ether.h> 8 #include <ethdev_driver.h> 9 #include <rte_interrupts.h> 10 11 #include <mlx5_glue.h> 12 #include <mlx5_devx_cmds.h> 13 #include <mlx5_common.h> 14 #include <mlx5_win_ext.h> 15 #include <mlx5_malloc.h> 16 #include <mlx5.h> 17 #include <mlx5_utils.h> 18 19 /** 20 * Get MAC address by querying netdevice. 21 * 22 * @param[in] dev 23 * Pointer to Ethernet device. 24 * @param[out] mac 25 * MAC address output buffer. 26 * 27 * @return 28 * 0 on success, a negative errno value otherwise and rte_errno is set. 29 */ 30 int 31 mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[RTE_ETHER_ADDR_LEN]) 32 { 33 struct mlx5_priv *priv; 34 mlx5_context_st *context_obj; 35 36 if (!dev) { 37 rte_errno = EINVAL; 38 return -rte_errno; 39 } 40 priv = dev->data->dev_private; 41 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 42 memcpy(mac, context_obj->mlx5_dev.eth_mac, RTE_ETHER_ADDR_LEN); 43 return 0; 44 } 45 46 /** 47 * Get interface name from private structure. 48 * 49 * 50 * @param[in] dev 51 * Pointer to Ethernet device. 52 * @param[out] ifname 53 * Interface name output buffer. 54 * 55 * @return 56 * 0 on success, a negative errno value otherwise and rte_errno is set. 57 */ 58 int 59 mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[MLX5_NAMESIZE]) 60 { 61 struct mlx5_priv *priv; 62 mlx5_context_st *context_obj; 63 64 if (!dev) { 65 rte_errno = EINVAL; 66 return -rte_errno; 67 } 68 priv = dev->data->dev_private; 69 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 70 strncpy(*ifname, context_obj->mlx5_dev.name, MLX5_NAMESIZE); 71 return 0; 72 } 73 74 /** 75 * Get device MTU. 76 * 77 * @param dev 78 * Pointer to Ethernet device. 79 * @param[out] mtu 80 * MTU value output buffer. 81 * 82 * @return 83 * 0 on success, a negative errno value otherwise and rte_errno is set. 84 */ 85 int 86 mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu) 87 { 88 struct mlx5_priv *priv; 89 mlx5_context_st *context_obj; 90 91 if (!dev) { 92 rte_errno = EINVAL; 93 return -rte_errno; 94 } 95 priv = dev->data->dev_private; 96 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 97 *mtu = context_obj->mlx5_dev.mtu_bytes; 98 return 0; 99 } 100 101 /** 102 * Set device MTU. 103 * 104 * @param dev 105 * Pointer to Ethernet device. 106 * @param mtu 107 * MTU value to set. 108 * 109 * @return 110 * 0 on success, a negative errno value otherwise and rte_errno is set. 111 */ 112 int 113 mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 114 { 115 RTE_SET_USED(dev); 116 RTE_SET_USED(mtu); 117 return -ENOTSUP; 118 } 119 120 /* 121 * Unregister callback handler safely. The handler may be active 122 * while we are trying to unregister it, in this case code -EAGAIN 123 * is returned by rte_intr_callback_unregister(). This routine checks 124 * the return code and tries to unregister handler again. 125 * 126 * @param handle 127 * interrupt handle 128 * @param cb_fn 129 * pointer to callback routine 130 * @cb_arg 131 * opaque callback parameter 132 */ 133 void 134 mlx5_intr_callback_unregister(const struct rte_intr_handle *handle, 135 rte_intr_callback_fn cb_fn, void *cb_arg) 136 { 137 RTE_SET_USED(handle); 138 RTE_SET_USED(cb_fn); 139 RTE_SET_USED(cb_arg); 140 } 141 142 /** 143 * DPDK callback to get flow control status. 144 * 145 * @param dev 146 * Pointer to Ethernet device structure. 147 * @param[out] fc_conf 148 * Flow control output buffer. 149 * 150 * @return 151 * 0 on success, a negative errno value otherwise and rte_errno is set. 152 */ 153 int 154 mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 155 { 156 RTE_SET_USED(dev); 157 RTE_SET_USED(fc_conf); 158 return -ENOTSUP; 159 } 160 161 /** 162 * DPDK callback to modify flow control parameters. 163 * 164 * @param dev 165 * Pointer to Ethernet device structure. 166 * @param[in] fc_conf 167 * Flow control parameters. 168 * 169 * @return 170 * 0 on success, a negative errno value otherwise and rte_errno is set. 171 */ 172 int 173 mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 174 { 175 RTE_SET_USED(dev); 176 RTE_SET_USED(fc_conf); 177 return -ENOTSUP; 178 } 179 180 /** 181 * Query the number of statistics provided by ETHTOOL. 182 * 183 * @param dev 184 * Pointer to Ethernet device. 185 * 186 * @return 187 * Number of statistics on success, negative errno value otherwise and 188 * rte_errno is set. 189 */ 190 int 191 mlx5_os_get_stats_n(struct rte_eth_dev *dev) 192 { 193 RTE_SET_USED(dev); 194 return -ENOTSUP; 195 } 196 197 /** 198 * Init the structures to read device counters. 199 * 200 * @param dev 201 * Pointer to Ethernet device. 202 */ 203 void 204 mlx5_os_stats_init(struct rte_eth_dev *dev) 205 { 206 RTE_SET_USED(dev); 207 } 208 209 /** 210 * Read device counters table. 211 * 212 * @param dev 213 * Pointer to Ethernet device. 214 * @param[out] stats 215 * Counters table output buffer. 216 * 217 * @return 218 * 0 on success and stats is filled, negative errno value otherwise and 219 * rte_errno is set. 220 */ 221 int 222 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 223 { 224 RTE_SET_USED(dev); 225 RTE_SET_USED(stats); 226 return -ENOTSUP; 227 } 228 229 /** 230 * DPDK callback to retrieve physical link information. 231 * 232 * @param dev 233 * Pointer to Ethernet device structure. 234 * @param wait_to_complete 235 * Wait for request completion. 236 * 237 * @return 238 * 0 if link status was not updated, positive if it was, a negative errno 239 * value otherwise and rte_errno is set. 240 */ 241 int 242 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) 243 { 244 RTE_SET_USED(wait_to_complete); 245 struct mlx5_priv *priv; 246 mlx5_context_st *context_obj; 247 struct rte_eth_link dev_link; 248 int ret; 249 250 ret = 0; 251 if (!dev) { 252 rte_errno = EINVAL; 253 return -rte_errno; 254 } 255 priv = dev->data->dev_private; 256 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 257 dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1000 * 1000); 258 dev_link.link_status = 259 (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev)) 260 ? 1 : 0; 261 dev_link.link_duplex = 1; 262 if (dev->data->dev_link.link_speed != dev_link.link_speed || 263 dev->data->dev_link.link_duplex != dev_link.link_duplex || 264 dev->data->dev_link.link_autoneg != dev_link.link_autoneg || 265 dev->data->dev_link.link_status != dev_link.link_status) 266 ret = 1; 267 else 268 ret = 0; 269 dev->data->dev_link = dev_link; 270 return ret; 271 } 272 273 /** 274 * DPDK callback to bring the link DOWN. 275 * 276 * @param dev 277 * Pointer to Ethernet device structure. 278 * 279 * @return 280 * 0 on success, a negative errno value otherwise 281 */ 282 int 283 mlx5_set_link_down(struct rte_eth_dev *dev) 284 { 285 RTE_SET_USED(dev); 286 return -ENOTSUP; 287 } 288 289 /** 290 * DPDK callback to bring the link UP. 291 * 292 * @param dev 293 * Pointer to Ethernet device structure. 294 * 295 * @return 296 * 0 on success, a negative errno value otherwise 297 */ 298 int 299 mlx5_set_link_up(struct rte_eth_dev *dev) 300 { 301 RTE_SET_USED(dev); 302 return -ENOTSUP; 303 } 304 305 /** 306 * DPDK callback to retrieve plug-in module EEPROM information (type and size). 307 * 308 * @param dev 309 * Pointer to Ethernet device structure. 310 * @param[out] modinfo 311 * Storage for plug-in module EEPROM information. 312 * 313 * @return 314 * 0 on success, a negative errno value otherwise and rte_errno is set. 315 */ 316 int 317 mlx5_get_module_info(struct rte_eth_dev *dev, 318 struct rte_eth_dev_module_info *modinfo) 319 { 320 RTE_SET_USED(dev); 321 RTE_SET_USED(modinfo); 322 return -ENOTSUP; 323 } 324 325 /** 326 * DPDK callback to retrieve plug-in module EEPROM data. 327 * 328 * @param dev 329 * Pointer to Ethernet device structure. 330 * @param[out] info 331 * Storage for plug-in module EEPROM data. 332 * 333 * @return 334 * 0 on success, a negative errno value otherwise and rte_errno is set. 335 */ 336 int mlx5_get_module_eeprom(struct rte_eth_dev *dev, 337 struct rte_dev_eeprom_info *info) 338 { 339 RTE_SET_USED(dev); 340 RTE_SET_USED(info); 341 return -ENOTSUP; 342 } 343 344 /** 345 * Get device current raw clock counter 346 * 347 * @param dev 348 * Pointer to Ethernet device structure. 349 * @param[out] time 350 * Current raw clock counter of the device. 351 * 352 * @return 353 * 0 if the clock has correctly been read 354 * The value of errno in case of error 355 */ 356 int 357 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) 358 { 359 int err; 360 struct mlx5_devx_clock mlx5_clock; 361 struct mlx5_priv *priv = dev->data->dev_private; 362 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 363 364 err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock); 365 if (err != 0) { 366 DRV_LOG(WARNING, "Could not query the clock"); 367 return err; 368 } 369 *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer; 370 return 0; 371 } 372 373 /** 374 * Check if mlx5 device was removed. 375 * 376 * @param dev 377 * Pointer to Ethernet device structure. 378 * 379 * @return 380 * 1 when device is removed, otherwise 0. 381 */ 382 int 383 mlx5_is_removed(struct rte_eth_dev *dev) 384 { 385 struct mlx5_priv *priv = dev->data->dev_private; 386 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 387 388 if (*context_obj->shutdown_event_obj.p_flag) 389 return 1; 390 return 0; 391 } 392 393 /* 394 * Query dropless_rq private flag value provided by ETHTOOL. 395 * 396 * @param dev 397 * Pointer to Ethernet device. 398 * 399 * @return 400 * - 0 on success, flag is not set. 401 * - 1 on success, flag is set. 402 * - negative errno value otherwise and rte_errno is set. 403 */ 404 int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev) 405 { 406 RTE_SET_USED(dev); 407 return -ENOTSUP; 408 } 409