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 struct mlx5_priv *priv = dev->data->dev_private; 207 struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; 208 int ret; 209 210 /* Copy to base at first time. */ 211 ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); 212 if (ret) 213 DRV_LOG(ERR, "port %u cannot read device counters: %s", 214 dev->data->port_id, strerror(rte_errno)); 215 stats_ctrl->imissed = 0; 216 } 217 218 /** 219 * Read device counters table. 220 * 221 * @param dev 222 * Pointer to Ethernet device. 223 * @param[out] stats 224 * Counters table output buffer. 225 * 226 * @return 227 * 0 on success and stats is filled, negative errno value otherwise and 228 * rte_errno is set. 229 */ 230 int 231 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 232 { 233 RTE_SET_USED(dev); 234 RTE_SET_USED(stats); 235 return -ENOTSUP; 236 } 237 238 /** 239 * DPDK callback to retrieve physical link information. 240 * 241 * @param dev 242 * Pointer to Ethernet device structure. 243 * @param wait_to_complete 244 * Wait for request completion. 245 * 246 * @return 247 * 0 if link status was not updated, positive if it was, a negative errno 248 * value otherwise and rte_errno is set. 249 */ 250 int 251 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) 252 { 253 RTE_SET_USED(wait_to_complete); 254 struct mlx5_priv *priv; 255 mlx5_context_st *context_obj; 256 struct rte_eth_link dev_link; 257 int ret; 258 259 ret = 0; 260 if (!dev) { 261 rte_errno = EINVAL; 262 return -rte_errno; 263 } 264 priv = dev->data->dev_private; 265 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 266 dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1000 * 1000); 267 dev_link.link_status = 268 (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev)) 269 ? 1 : 0; 270 dev_link.link_duplex = 1; 271 if (dev->data->dev_link.link_speed != dev_link.link_speed || 272 dev->data->dev_link.link_duplex != dev_link.link_duplex || 273 dev->data->dev_link.link_autoneg != dev_link.link_autoneg || 274 dev->data->dev_link.link_status != dev_link.link_status) 275 ret = 1; 276 else 277 ret = 0; 278 dev->data->dev_link = dev_link; 279 return ret; 280 } 281 282 /** 283 * DPDK callback to bring the link DOWN. 284 * 285 * @param dev 286 * Pointer to Ethernet device structure. 287 * 288 * @return 289 * 0 on success, a negative errno value otherwise 290 */ 291 int 292 mlx5_set_link_down(struct rte_eth_dev *dev) 293 { 294 RTE_SET_USED(dev); 295 return -ENOTSUP; 296 } 297 298 /** 299 * DPDK callback to bring the link UP. 300 * 301 * @param dev 302 * Pointer to Ethernet device structure. 303 * 304 * @return 305 * 0 on success, a negative errno value otherwise 306 */ 307 int 308 mlx5_set_link_up(struct rte_eth_dev *dev) 309 { 310 RTE_SET_USED(dev); 311 return -ENOTSUP; 312 } 313 314 /** 315 * DPDK callback to retrieve plug-in module EEPROM information (type and size). 316 * 317 * @param dev 318 * Pointer to Ethernet device structure. 319 * @param[out] modinfo 320 * Storage for plug-in module EEPROM information. 321 * 322 * @return 323 * 0 on success, a negative errno value otherwise and rte_errno is set. 324 */ 325 int 326 mlx5_get_module_info(struct rte_eth_dev *dev, 327 struct rte_eth_dev_module_info *modinfo) 328 { 329 RTE_SET_USED(dev); 330 RTE_SET_USED(modinfo); 331 return -ENOTSUP; 332 } 333 334 /** 335 * DPDK callback to retrieve plug-in module EEPROM data. 336 * 337 * @param dev 338 * Pointer to Ethernet device structure. 339 * @param[out] info 340 * Storage for plug-in module EEPROM data. 341 * 342 * @return 343 * 0 on success, a negative errno value otherwise and rte_errno is set. 344 */ 345 int mlx5_get_module_eeprom(struct rte_eth_dev *dev, 346 struct rte_dev_eeprom_info *info) 347 { 348 RTE_SET_USED(dev); 349 RTE_SET_USED(info); 350 return -ENOTSUP; 351 } 352 353 /** 354 * Get device current raw clock counter 355 * 356 * @param dev 357 * Pointer to Ethernet device structure. 358 * @param[out] time 359 * Current raw clock counter of the device. 360 * 361 * @return 362 * 0 if the clock has correctly been read 363 * The value of errno in case of error 364 */ 365 int 366 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) 367 { 368 int err; 369 struct mlx5_devx_clock mlx5_clock; 370 struct mlx5_priv *priv = dev->data->dev_private; 371 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 372 373 err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock); 374 if (err != 0) { 375 DRV_LOG(WARNING, "Could not query the clock"); 376 return err; 377 } 378 *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer; 379 return 0; 380 } 381 382 /** 383 * Check if mlx5 device was removed. 384 * 385 * @param dev 386 * Pointer to Ethernet device structure. 387 * 388 * @return 389 * 1 when device is removed, otherwise 0. 390 */ 391 int 392 mlx5_is_removed(struct rte_eth_dev *dev) 393 { 394 struct mlx5_priv *priv = dev->data->dev_private; 395 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx; 396 397 if (*context_obj->shutdown_event_obj.p_flag) 398 return 1; 399 return 0; 400 } 401 402 /* 403 * Query dropless_rq private flag value provided by ETHTOOL. 404 * 405 * @param dev 406 * Pointer to Ethernet device. 407 * 408 * @return 409 * - 0 on success, flag is not set. 410 * - 1 on success, flag is set. 411 * - negative errno value otherwise and rte_errno is set. 412 */ 413 int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev) 414 { 415 RTE_SET_USED(dev); 416 return -ENOTSUP; 417 } 418