xref: /linux/drivers/accel/amdxdna/aie4_sriov.c (revision 0eaed89c18aeedf0898baf2dbf5ff027c6795152)
1*c02697cbSDavid Zhang // SPDX-License-Identifier: GPL-2.0
2*c02697cbSDavid Zhang /*
3*c02697cbSDavid Zhang  * Copyright (C) 2026, Advanced Micro Devices, Inc.
4*c02697cbSDavid Zhang  */
5*c02697cbSDavid Zhang 
6*c02697cbSDavid Zhang #include <drm/amdxdna_accel.h>
7*c02697cbSDavid Zhang #include <drm/drm_print.h>
8*c02697cbSDavid Zhang #include <linux/pci.h>
9*c02697cbSDavid Zhang 
10*c02697cbSDavid Zhang #include "aie.h"
11*c02697cbSDavid Zhang #include "aie4_msg_priv.h"
12*c02697cbSDavid Zhang #include "aie4_pci.h"
13*c02697cbSDavid Zhang #include "amdxdna_mailbox.h"
14*c02697cbSDavid Zhang #include "amdxdna_mailbox_helper.h"
15*c02697cbSDavid Zhang #include "amdxdna_pci_drv.h"
16*c02697cbSDavid Zhang 
17*c02697cbSDavid Zhang static int aie4_destroy_vfs(struct amdxdna_dev_hdl *ndev)
18*c02697cbSDavid Zhang {
19*c02697cbSDavid Zhang 	DECLARE_AIE_MSG(aie4_msg_destroy_vfs, AIE4_MSG_OP_DESTROY_VFS);
20*c02697cbSDavid Zhang 	int ret;
21*c02697cbSDavid Zhang 
22*c02697cbSDavid Zhang 	ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
23*c02697cbSDavid Zhang 	if (ret)
24*c02697cbSDavid Zhang 		XDNA_ERR(ndev->aie.xdna, "destroy vfs op failed: %d", ret);
25*c02697cbSDavid Zhang 
26*c02697cbSDavid Zhang 	return ret;
27*c02697cbSDavid Zhang }
28*c02697cbSDavid Zhang 
29*c02697cbSDavid Zhang static int aie4_create_vfs(struct amdxdna_dev_hdl *ndev, int num_vfs)
30*c02697cbSDavid Zhang {
31*c02697cbSDavid Zhang 	DECLARE_AIE_MSG(aie4_msg_create_vfs, AIE4_MSG_OP_CREATE_VFS);
32*c02697cbSDavid Zhang 	int ret;
33*c02697cbSDavid Zhang 
34*c02697cbSDavid Zhang 	req.vf_cnt = num_vfs;
35*c02697cbSDavid Zhang 	ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
36*c02697cbSDavid Zhang 	if (ret)
37*c02697cbSDavid Zhang 		XDNA_ERR(ndev->aie.xdna, "create vfs op failed: %d", ret);
38*c02697cbSDavid Zhang 
39*c02697cbSDavid Zhang 	return ret;
40*c02697cbSDavid Zhang }
41*c02697cbSDavid Zhang 
42*c02697cbSDavid Zhang int aie4_sriov_stop(struct amdxdna_dev_hdl *ndev)
43*c02697cbSDavid Zhang {
44*c02697cbSDavid Zhang 	struct amdxdna_dev *xdna = ndev->aie.xdna;
45*c02697cbSDavid Zhang 	struct pci_dev *pdev = to_pci_dev(xdna->ddev.dev);
46*c02697cbSDavid Zhang 	int ret;
47*c02697cbSDavid Zhang 
48*c02697cbSDavid Zhang 	if (!pci_num_vf(pdev))
49*c02697cbSDavid Zhang 		return 0;
50*c02697cbSDavid Zhang 
51*c02697cbSDavid Zhang 	ret = pci_vfs_assigned(pdev);
52*c02697cbSDavid Zhang 	if (ret) {
53*c02697cbSDavid Zhang 		XDNA_ERR(xdna, "VFs are still assigned to VMs");
54*c02697cbSDavid Zhang 		return -EPERM;
55*c02697cbSDavid Zhang 	}
56*c02697cbSDavid Zhang 
57*c02697cbSDavid Zhang 	pci_disable_sriov(pdev);
58*c02697cbSDavid Zhang 	return aie4_destroy_vfs(ndev);
59*c02697cbSDavid Zhang }
60*c02697cbSDavid Zhang 
61*c02697cbSDavid Zhang static int aie4_sriov_start(struct amdxdna_dev_hdl *ndev, int num_vfs)
62*c02697cbSDavid Zhang {
63*c02697cbSDavid Zhang 	struct amdxdna_dev *xdna = ndev->aie.xdna;
64*c02697cbSDavid Zhang 	struct pci_dev *pdev = to_pci_dev(xdna->ddev.dev);
65*c02697cbSDavid Zhang 	int ret;
66*c02697cbSDavid Zhang 
67*c02697cbSDavid Zhang 	ret = aie4_create_vfs(ndev, num_vfs);
68*c02697cbSDavid Zhang 	if (ret)
69*c02697cbSDavid Zhang 		return ret;
70*c02697cbSDavid Zhang 
71*c02697cbSDavid Zhang 	ret = pci_enable_sriov(pdev, num_vfs);
72*c02697cbSDavid Zhang 	if (ret) {
73*c02697cbSDavid Zhang 		XDNA_ERR(xdna, "configure VFs failed, ret: %d", ret);
74*c02697cbSDavid Zhang 		aie4_destroy_vfs(ndev);
75*c02697cbSDavid Zhang 		return ret;
76*c02697cbSDavid Zhang 	}
77*c02697cbSDavid Zhang 
78*c02697cbSDavid Zhang 	return num_vfs;
79*c02697cbSDavid Zhang }
80*c02697cbSDavid Zhang 
81*c02697cbSDavid Zhang int aie4_sriov_configure(struct amdxdna_dev *xdna, int num_vfs)
82*c02697cbSDavid Zhang {
83*c02697cbSDavid Zhang 	struct amdxdna_dev_hdl *ndev = xdna->dev_handle;
84*c02697cbSDavid Zhang 
85*c02697cbSDavid Zhang 	drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
86*c02697cbSDavid Zhang 
87*c02697cbSDavid Zhang 	return (num_vfs) ? aie4_sriov_start(ndev, num_vfs) : aie4_sriov_stop(ndev);
88*c02697cbSDavid Zhang }
89