18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 28c2ecf20Sopenharmony_ci/* Copyright (c) 2020 Mellanox Technologies Ltd. */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/module.h> 58c2ecf20Sopenharmony_ci#include <linux/mlx5/driver.h> 68c2ecf20Sopenharmony_ci#include <linux/mlx5/device.h> 78c2ecf20Sopenharmony_ci#include "mlx5_vdpa_ifc.h" 88c2ecf20Sopenharmony_ci#include "mlx5_vnet.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ciMODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); 118c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Mellanox VDPA driver"); 128c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic bool required_caps_supported(struct mlx5_core_dev *mdev) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci u8 event_mode; 178c2ecf20Sopenharmony_ci u64 got; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci got = MLX5_CAP_GEN_64(mdev, general_obj_types); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci if (!(got & MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q)) 228c2ecf20Sopenharmony_ci return false; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci event_mode = MLX5_CAP_DEV_VDPA_EMULATION(mdev, event_mode); 258c2ecf20Sopenharmony_ci if (!(event_mode & MLX5_VIRTIO_Q_EVENT_MODE_QP_MODE)) 268c2ecf20Sopenharmony_ci return false; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, eth_frame_offload_type)) 298c2ecf20Sopenharmony_ci return false; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci return true; 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic void *mlx5_vdpa_add(struct mlx5_core_dev *mdev) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci struct mlx5_vdpa_dev *vdev; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci if (mlx5_core_is_pf(mdev)) 398c2ecf20Sopenharmony_ci return NULL; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci if (!required_caps_supported(mdev)) { 428c2ecf20Sopenharmony_ci dev_info(mdev->device, "virtio net emulation not supported\n"); 438c2ecf20Sopenharmony_ci return NULL; 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci vdev = mlx5_vdpa_add_dev(mdev); 468c2ecf20Sopenharmony_ci if (IS_ERR(vdev)) 478c2ecf20Sopenharmony_ci return NULL; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci return vdev; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic void mlx5_vdpa_remove(struct mlx5_core_dev *mdev, void *context) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci struct mlx5_vdpa_dev *vdev = context; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci mlx5_vdpa_remove_dev(vdev); 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic struct mlx5_interface mlx5_vdpa_interface = { 608c2ecf20Sopenharmony_ci .add = mlx5_vdpa_add, 618c2ecf20Sopenharmony_ci .remove = mlx5_vdpa_remove, 628c2ecf20Sopenharmony_ci .protocol = MLX5_INTERFACE_PROTOCOL_VDPA, 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic int __init mlx5_vdpa_init(void) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci return mlx5_register_interface(&mlx5_vdpa_interface); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic void __exit mlx5_vdpa_exit(void) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci mlx5_unregister_interface(&mlx5_vdpa_interface); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cimodule_init(mlx5_vdpa_init); 768c2ecf20Sopenharmony_cimodule_exit(mlx5_vdpa_exit); 77