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 <rte_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->ctx; 42 memcpy(mac, context_obj->mlx5_dev.eth_mac, RTE_ETHER_ADDR_LEN); 43 return 0; 44 } 45 46 /** 47 * Get device MTU. 48 * 49 * @param dev 50 * Pointer to Ethernet device. 51 * @param[out] mtu 52 * MTU value output buffer. 53 * 54 * @return 55 * 0 on success, a negative errno value otherwise and rte_errno is set. 56 */ 57 int 58 mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu) 59 { 60 struct mlx5_priv *priv; 61 mlx5_context_st *context_obj; 62 63 if (!dev) { 64 rte_errno = EINVAL; 65 return -rte_errno; 66 } 67 priv = dev->data->dev_private; 68 context_obj = (mlx5_context_st *)priv->sh->ctx; 69 *mtu = context_obj->mlx5_dev.mtu_bytes; 70 return 0; 71 } 72 73 /** 74 * Set device MTU. 75 * 76 * @param dev 77 * Pointer to Ethernet device. 78 * @param mtu 79 * MTU value to set. 80 * 81 * @return 82 * 0 on success, a negative errno value otherwise and rte_errno is set. 83 */ 84 int 85 mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 86 { 87 RTE_SET_USED(dev); 88 RTE_SET_USED(mtu); 89 return -ENOTSUP; 90 } 91 92 /* 93 * Unregister callback handler safely. The handler may be active 94 * while we are trying to unregister it, in this case code -EAGAIN 95 * is returned by rte_intr_callback_unregister(). This routine checks 96 * the return code and tries to unregister handler again. 97 * 98 * @param handle 99 * interrupt handle 100 * @param cb_fn 101 * pointer to callback routine 102 * @cb_arg 103 * opaque callback parameter 104 */ 105 void 106 mlx5_intr_callback_unregister(const struct rte_intr_handle *handle, 107 rte_intr_callback_fn cb_fn, void *cb_arg) 108 { 109 RTE_SET_USED(handle); 110 RTE_SET_USED(cb_fn); 111 RTE_SET_USED(cb_arg); 112 } 113 114 /** 115 * DPDK callback to get flow control status. 116 * 117 * @param dev 118 * Pointer to Ethernet device structure. 119 * @param[out] fc_conf 120 * Flow control output buffer. 121 * 122 * @return 123 * 0 on success, a negative errno value otherwise and rte_errno is set. 124 */ 125 int 126 mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 127 { 128 RTE_SET_USED(dev); 129 RTE_SET_USED(fc_conf); 130 return -ENOTSUP; 131 } 132 133 /** 134 * DPDK callback to modify flow control parameters. 135 * 136 * @param dev 137 * Pointer to Ethernet device structure. 138 * @param[in] fc_conf 139 * Flow control parameters. 140 * 141 * @return 142 * 0 on success, a negative errno value otherwise and rte_errno is set. 143 */ 144 int 145 mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 146 { 147 RTE_SET_USED(dev); 148 RTE_SET_USED(fc_conf); 149 return -ENOTSUP; 150 } 151 152 /** 153 * Query the number of statistics provided by ETHTOOL. 154 * 155 * @param dev 156 * Pointer to Ethernet device. 157 * 158 * @return 159 * Number of statistics on success, negative errno value otherwise and 160 * rte_errno is set. 161 */ 162 int 163 mlx5_os_get_stats_n(struct rte_eth_dev *dev) 164 { 165 RTE_SET_USED(dev); 166 return -ENOTSUP; 167 } 168 169 /** 170 * Init the structures to read device counters. 171 * 172 * @param dev 173 * Pointer to Ethernet device. 174 */ 175 void 176 mlx5_os_stats_init(struct rte_eth_dev *dev) 177 { 178 RTE_SET_USED(dev); 179 } 180 181 /** 182 * Read device counters table. 183 * 184 * @param dev 185 * Pointer to Ethernet device. 186 * @param[out] stats 187 * Counters table output buffer. 188 * 189 * @return 190 * 0 on success and stats is filled, negative errno value otherwise and 191 * rte_errno is set. 192 */ 193 int 194 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 195 { 196 RTE_SET_USED(dev); 197 RTE_SET_USED(stats); 198 return -ENOTSUP; 199 } 200 201 /** 202 * DPDK callback to retrieve physical link information. 203 * 204 * @param dev 205 * Pointer to Ethernet device structure. 206 * @param wait_to_complete 207 * Wait for request completion. 208 * 209 * @return 210 * 0 if link status was not updated, positive if it was, a negative errno 211 * value otherwise and rte_errno is set. 212 */ 213 int 214 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) 215 { 216 RTE_SET_USED(wait_to_complete); 217 struct mlx5_priv *priv; 218 mlx5_context_st *context_obj; 219 struct rte_eth_link dev_link; 220 int ret; 221 222 ret = 0; 223 if (!dev) { 224 rte_errno = EINVAL; 225 return -rte_errno; 226 } 227 priv = dev->data->dev_private; 228 context_obj = (mlx5_context_st *)priv->sh->ctx; 229 dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1024 * 1024); 230 dev_link.link_status = 231 (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev)) 232 ? 1 : 0; 233 dev_link.link_duplex = 1; 234 if (dev->data->dev_link.link_speed != dev_link.link_speed || 235 dev->data->dev_link.link_duplex != dev_link.link_duplex || 236 dev->data->dev_link.link_autoneg != dev_link.link_autoneg || 237 dev->data->dev_link.link_status != dev_link.link_status) 238 ret = 1; 239 else 240 ret = 0; 241 dev->data->dev_link = dev_link; 242 return ret; 243 } 244 245 /** 246 * DPDK callback to bring the link DOWN. 247 * 248 * @param dev 249 * Pointer to Ethernet device structure. 250 * 251 * @return 252 * 0 on success, a negative errno value otherwise 253 */ 254 int 255 mlx5_set_link_down(struct rte_eth_dev *dev) 256 { 257 RTE_SET_USED(dev); 258 return -ENOTSUP; 259 } 260 261 /** 262 * DPDK callback to bring the link UP. 263 * 264 * @param dev 265 * Pointer to Ethernet device structure. 266 * 267 * @return 268 * 0 on success, a negative errno value otherwise 269 */ 270 int 271 mlx5_set_link_up(struct rte_eth_dev *dev) 272 { 273 RTE_SET_USED(dev); 274 return -ENOTSUP; 275 } 276 277 /** 278 * DPDK callback to retrieve plug-in module EEPROM information (type and size). 279 * 280 * @param dev 281 * Pointer to Ethernet device structure. 282 * @param[out] modinfo 283 * Storage for plug-in module EEPROM information. 284 * 285 * @return 286 * 0 on success, a negative errno value otherwise and rte_errno is set. 287 */ 288 int 289 mlx5_get_module_info(struct rte_eth_dev *dev, 290 struct rte_eth_dev_module_info *modinfo) 291 { 292 RTE_SET_USED(dev); 293 RTE_SET_USED(modinfo); 294 return -ENOTSUP; 295 } 296 297 /** 298 * DPDK callback to retrieve plug-in module EEPROM data. 299 * 300 * @param dev 301 * Pointer to Ethernet device structure. 302 * @param[out] info 303 * Storage for plug-in module EEPROM data. 304 * 305 * @return 306 * 0 on success, a negative errno value otherwise and rte_errno is set. 307 */ 308 int mlx5_get_module_eeprom(struct rte_eth_dev *dev, 309 struct rte_dev_eeprom_info *info) 310 { 311 RTE_SET_USED(dev); 312 RTE_SET_USED(info); 313 return -ENOTSUP; 314 } 315 316 /** 317 * Get device current raw clock counter 318 * 319 * @param dev 320 * Pointer to Ethernet device structure. 321 * @param[out] time 322 * Current raw clock counter of the device. 323 * 324 * @return 325 * 0 if the clock has correctly been read 326 * The value of errno in case of error 327 */ 328 int 329 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) 330 { 331 int err; 332 struct mlx5_devx_clock mlx5_clock; 333 struct mlx5_priv *priv = dev->data->dev_private; 334 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->ctx; 335 336 err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock); 337 if (err != 0) { 338 DRV_LOG(WARNING, "Could not query the clock"); 339 return err; 340 } 341 *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer; 342 return 0; 343 } 344