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 int err; 89 uint32_t curr_mtu; 90 struct mlx5_priv *priv; 91 mlx5_context_st *context_obj; 92 93 if (!dev) { 94 rte_errno = EINVAL; 95 return -rte_errno; 96 } 97 priv = dev->data->dev_private; 98 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 99 100 err = mlx5_glue->devx_get_mtu(context_obj, &curr_mtu); 101 if (err != 0) { 102 DRV_LOG(WARNING, "Could not get the MTU!"); 103 return err; 104 } 105 *mtu = (uint16_t)curr_mtu; 106 107 return 0; 108 } 109 110 /** 111 * Set device MTU. 112 * 113 * @param dev 114 * Pointer to Ethernet device. 115 * @param mtu 116 * MTU value to set. 117 * 118 * @return 119 * 0 on success, a negative errno value otherwise and rte_errno is set. 120 */ 121 int 122 mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 123 { 124 int err; 125 struct mlx5_priv *priv; 126 mlx5_context_st *context_obj; 127 128 if (!dev) { 129 rte_errno = EINVAL; 130 return -rte_errno; 131 } 132 priv = dev->data->dev_private; 133 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 134 135 err = mlx5_glue->devx_set_mtu(context_obj, mtu); 136 if (err != 0) { 137 DRV_LOG(WARNING, "Could not set the MTU!"); 138 return err; 139 } 140 return 0; 141 } 142 143 /** 144 * DPDK callback to get flow control status. 145 * 146 * @param dev 147 * Pointer to Ethernet device structure. 148 * @param[out] fc_conf 149 * Flow control output buffer. 150 * 151 * @return 152 * 0 on success, a negative errno value otherwise and rte_errno is set. 153 */ 154 int 155 mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 156 { 157 RTE_SET_USED(dev); 158 RTE_SET_USED(fc_conf); 159 return -ENOTSUP; 160 } 161 162 /** 163 * DPDK callback to modify flow control parameters. 164 * 165 * @param dev 166 * Pointer to Ethernet device structure. 167 * @param[in] fc_conf 168 * Flow control parameters. 169 * 170 * @return 171 * 0 on success, a negative errno value otherwise and rte_errno is set. 172 */ 173 int 174 mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 175 { 176 RTE_SET_USED(dev); 177 RTE_SET_USED(fc_conf); 178 return -ENOTSUP; 179 } 180 181 /** 182 * Query the number of statistics provided by ETHTOOL. 183 * 184 * @param dev 185 * Pointer to Ethernet device. 186 * 187 * @return 188 * Number of statistics on success, negative errno value otherwise and 189 * rte_errno is set. 190 */ 191 int 192 mlx5_os_get_stats_n(struct rte_eth_dev *dev) 193 { 194 RTE_SET_USED(dev); 195 return -ENOTSUP; 196 } 197 198 /** 199 * Init the structures to read device counters. 200 * 201 * @param dev 202 * Pointer to Ethernet device. 203 */ 204 void 205 mlx5_os_stats_init(struct rte_eth_dev *dev) 206 { 207 struct mlx5_priv *priv = dev->data->dev_private; 208 struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; 209 int ret; 210 211 /* Copy to base at first time. */ 212 ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); 213 if (ret) 214 DRV_LOG(ERR, "port %u cannot read device counters: %s", 215 dev->data->port_id, strerror(rte_errno)); 216 stats_ctrl->imissed = 0; 217 } 218 219 /** 220 * Read device counters table. 221 * 222 * @param dev 223 * Pointer to Ethernet device. 224 * @param[out] stats 225 * Counters table output buffer. 226 * 227 * @return 228 * 0 on success and stats is filled, negative errno value otherwise and 229 * rte_errno is set. 230 */ 231 int 232 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 233 { 234 RTE_SET_USED(dev); 235 RTE_SET_USED(stats); 236 return -ENOTSUP; 237 } 238 239 /** 240 * DPDK callback to retrieve physical link information. 241 * 242 * @param dev 243 * Pointer to Ethernet device structure. 244 * @param wait_to_complete 245 * Wait for request completion. 246 * 247 * @return 248 * 0 if link status was not updated, positive if it was, a negative errno 249 * value otherwise and rte_errno is set. 250 */ 251 int 252 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) 253 { 254 RTE_SET_USED(wait_to_complete); 255 struct mlx5_priv *priv; 256 mlx5_context_st *context_obj; 257 struct rte_eth_link dev_link; 258 int ret; 259 260 ret = 0; 261 if (!dev) { 262 rte_errno = EINVAL; 263 return -rte_errno; 264 } 265 priv = dev->data->dev_private; 266 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 267 dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1000 * 1000); 268 dev_link.link_status = 269 (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev)) 270 ? 1 : 0; 271 dev_link.link_duplex = 1; 272 if (dev->data->dev_link.link_speed != dev_link.link_speed || 273 dev->data->dev_link.link_duplex != dev_link.link_duplex || 274 dev->data->dev_link.link_autoneg != dev_link.link_autoneg || 275 dev->data->dev_link.link_status != dev_link.link_status) 276 ret = 1; 277 else 278 ret = 0; 279 dev->data->dev_link = dev_link; 280 return ret; 281 } 282 283 /** 284 * DPDK callback to bring the link DOWN. 285 * 286 * @param dev 287 * Pointer to Ethernet device structure. 288 * 289 * @return 290 * 0 on success, a negative errno value otherwise 291 */ 292 int 293 mlx5_set_link_down(struct rte_eth_dev *dev) 294 { 295 RTE_SET_USED(dev); 296 return -ENOTSUP; 297 } 298 299 /** 300 * DPDK callback to bring the link UP. 301 * 302 * @param dev 303 * Pointer to Ethernet device structure. 304 * 305 * @return 306 * 0 on success, a negative errno value otherwise 307 */ 308 int 309 mlx5_set_link_up(struct rte_eth_dev *dev) 310 { 311 RTE_SET_USED(dev); 312 return -ENOTSUP; 313 } 314 315 /** 316 * DPDK callback to retrieve plug-in module EEPROM information (type and size). 317 * 318 * @param dev 319 * Pointer to Ethernet device structure. 320 * @param[out] modinfo 321 * Storage for plug-in module EEPROM information. 322 * 323 * @return 324 * 0 on success, a negative errno value otherwise and rte_errno is set. 325 */ 326 int 327 mlx5_get_module_info(struct rte_eth_dev *dev, 328 struct rte_eth_dev_module_info *modinfo) 329 { 330 RTE_SET_USED(dev); 331 RTE_SET_USED(modinfo); 332 return -ENOTSUP; 333 } 334 335 /** 336 * DPDK callback to retrieve plug-in module EEPROM data. 337 * 338 * @param dev 339 * Pointer to Ethernet device structure. 340 * @param[out] info 341 * Storage for plug-in module EEPROM data. 342 * 343 * @return 344 * 0 on success, a negative errno value otherwise and rte_errno is set. 345 */ 346 int mlx5_get_module_eeprom(struct rte_eth_dev *dev, 347 struct rte_dev_eeprom_info *info) 348 { 349 RTE_SET_USED(dev); 350 RTE_SET_USED(info); 351 return -ENOTSUP; 352 } 353 354 /** 355 * Get device current raw clock counter 356 * 357 * @param dev 358 * Pointer to Ethernet device structure. 359 * @param[out] time 360 * Current raw clock counter of the device. 361 * 362 * @return 363 * 0 if the clock has correctly been read 364 * The value of errno in case of error 365 */ 366 int 367 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) 368 { 369 int err; 370 struct mlx5_devx_clock mlx5_clock; 371 struct mlx5_priv *priv = dev->data->dev_private; 372 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 373 374 err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock); 375 if (err != 0) { 376 DRV_LOG(WARNING, "Could not query the clock"); 377 return err; 378 } 379 *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer; 380 return 0; 381 } 382 383 /** 384 * Check if mlx5 device was removed. 385 * 386 * @param dev 387 * Pointer to Ethernet device structure. 388 * 389 * @return 390 * 1 when device is removed, otherwise 0. 391 */ 392 int 393 mlx5_is_removed(struct rte_eth_dev *dev) 394 { 395 struct mlx5_priv *priv = dev->data->dev_private; 396 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 397 398 if (*context_obj->shutdown_event_obj.p_flag) 399 return 1; 400 return 0; 401 } 402 403 /* 404 * Query dropless_rq private flag value provided by ETHTOOL. 405 * 406 * @param dev 407 * Pointer to Ethernet device. 408 * 409 * @return 410 * - 0 on success, flag is not set. 411 * - 1 on success, flag is set. 412 * - negative errno value otherwise and rte_errno is set. 413 */ 414 int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev) 415 { 416 RTE_SET_USED(dev); 417 return -ENOTSUP; 418 } 419 420 /** 421 * Unmaps HCA PCI BAR from the current process address space. 422 * 423 * @param dev 424 * Pointer to Ethernet device structure. 425 */ 426 void mlx5_txpp_unmap_hca_bar(struct rte_eth_dev *dev) 427 { 428 RTE_SET_USED(dev); 429 } 430 431 /** 432 * Maps HCA PCI BAR to the current process address space. 433 * Stores pointer in the process private structure allowing 434 * to read internal and real time counter directly from the HW. 435 * 436 * @param dev 437 * Pointer to Ethernet device structure. 438 * 439 * @return 440 * 0 on success and not NULL pointer to mapped area in process structure. 441 * negative otherwise and NULL pointer 442 */ 443 int mlx5_txpp_map_hca_bar(struct rte_eth_dev *dev) 444 { 445 RTE_SET_USED(dev); 446 rte_errno = ENOTSUP; 447 return -ENOTSUP; 448 } 449