1*3c819070SYishai Hadas // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2*3c819070SYishai Hadas /* 3*3c819070SYishai Hadas * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved 4*3c819070SYishai Hadas */ 5*3c819070SYishai Hadas 6*3c819070SYishai Hadas #include <rdma/uverbs_std_types.h> 7*3c819070SYishai Hadas #include <linux/pci-tph.h> 8*3c819070SYishai Hadas #include "dmah.h" 9*3c819070SYishai Hadas 10*3c819070SYishai Hadas #define UVERBS_MODULE_NAME mlx5_ib 11*3c819070SYishai Hadas #include <rdma/uverbs_named_ioctl.h> 12*3c819070SYishai Hadas 13*3c819070SYishai Hadas static int mlx5_ib_alloc_dmah(struct ib_dmah *ibdmah, 14*3c819070SYishai Hadas struct uverbs_attr_bundle *attrs) 15*3c819070SYishai Hadas { 16*3c819070SYishai Hadas struct mlx5_core_dev *mdev = to_mdev(ibdmah->device)->mdev; 17*3c819070SYishai Hadas struct mlx5_ib_dmah *dmah = to_mdmah(ibdmah); 18*3c819070SYishai Hadas u16 st_bits = BIT(IB_DMAH_CPU_ID_EXISTS) | 19*3c819070SYishai Hadas BIT(IB_DMAH_MEM_TYPE_EXISTS); 20*3c819070SYishai Hadas int err; 21*3c819070SYishai Hadas 22*3c819070SYishai Hadas /* PH is a must for TPH following PCIe spec 6.2-1.0 */ 23*3c819070SYishai Hadas if (!(ibdmah->valid_fields & BIT(IB_DMAH_PH_EXISTS))) 24*3c819070SYishai Hadas return -EINVAL; 25*3c819070SYishai Hadas 26*3c819070SYishai Hadas /* ST is optional; however, partial data for it is not allowed */ 27*3c819070SYishai Hadas if (ibdmah->valid_fields & st_bits) { 28*3c819070SYishai Hadas if ((ibdmah->valid_fields & st_bits) != st_bits) 29*3c819070SYishai Hadas return -EINVAL; 30*3c819070SYishai Hadas err = mlx5_st_alloc_index(mdev, ibdmah->mem_type, 31*3c819070SYishai Hadas ibdmah->cpu_id, &dmah->st_index); 32*3c819070SYishai Hadas if (err) 33*3c819070SYishai Hadas return err; 34*3c819070SYishai Hadas } 35*3c819070SYishai Hadas 36*3c819070SYishai Hadas return 0; 37*3c819070SYishai Hadas } 38*3c819070SYishai Hadas 39*3c819070SYishai Hadas static int mlx5_ib_dealloc_dmah(struct ib_dmah *ibdmah, 40*3c819070SYishai Hadas struct uverbs_attr_bundle *attrs) 41*3c819070SYishai Hadas { 42*3c819070SYishai Hadas struct mlx5_ib_dmah *dmah = to_mdmah(ibdmah); 43*3c819070SYishai Hadas struct mlx5_core_dev *mdev = to_mdev(ibdmah->device)->mdev; 44*3c819070SYishai Hadas 45*3c819070SYishai Hadas if (ibdmah->valid_fields & BIT(IB_DMAH_CPU_ID_EXISTS)) 46*3c819070SYishai Hadas return mlx5_st_dealloc_index(mdev, dmah->st_index); 47*3c819070SYishai Hadas 48*3c819070SYishai Hadas return 0; 49*3c819070SYishai Hadas } 50*3c819070SYishai Hadas 51*3c819070SYishai Hadas const struct ib_device_ops mlx5_ib_dev_dmah_ops = { 52*3c819070SYishai Hadas .alloc_dmah = mlx5_ib_alloc_dmah, 53*3c819070SYishai Hadas .dealloc_dmah = mlx5_ib_dealloc_dmah, 54*3c819070SYishai Hadas }; 55