]> Git Repo - linux.git/blob - drivers/vdpa/pds/cmds.c
Merge patch series "riscv: Extension parsing fixes"
[linux.git] / drivers / vdpa / pds / cmds.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
3
4 #include <linux/vdpa.h>
5 #include <linux/virtio_pci_modern.h>
6
7 #include <linux/pds/pds_common.h>
8 #include <linux/pds/pds_core_if.h>
9 #include <linux/pds/pds_adminq.h>
10 #include <linux/pds/pds_auxbus.h>
11
12 #include "vdpa_dev.h"
13 #include "aux_drv.h"
14 #include "cmds.h"
15
16 int pds_vdpa_init_hw(struct pds_vdpa_device *pdsv)
17 {
18         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
19         struct device *dev = &padev->aux_dev.dev;
20         union pds_core_adminq_cmd cmd = {
21                 .vdpa_init.opcode = PDS_VDPA_CMD_INIT,
22                 .vdpa_init.vdpa_index = pdsv->vdpa_index,
23                 .vdpa_init.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
24         };
25         union pds_core_adminq_comp comp = {};
26         int err;
27
28         /* Initialize the vdpa/virtio device */
29         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_init),
30                                     &comp, 0);
31         if (err)
32                 dev_dbg(dev, "Failed to init hw, status %d: %pe\n",
33                         comp.status, ERR_PTR(err));
34
35         return err;
36 }
37
38 int pds_vdpa_cmd_reset(struct pds_vdpa_device *pdsv)
39 {
40         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
41         struct device *dev = &padev->aux_dev.dev;
42         union pds_core_adminq_cmd cmd = {
43                 .vdpa.opcode = PDS_VDPA_CMD_RESET,
44                 .vdpa.vdpa_index = pdsv->vdpa_index,
45                 .vdpa.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
46         };
47         union pds_core_adminq_comp comp = {};
48         int err;
49
50         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa), &comp, 0);
51         if (err)
52                 dev_dbg(dev, "Failed to reset hw, status %d: %pe\n",
53                         comp.status, ERR_PTR(err));
54
55         return err;
56 }
57
58 int pds_vdpa_cmd_set_status(struct pds_vdpa_device *pdsv, u8 status)
59 {
60         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
61         struct device *dev = &padev->aux_dev.dev;
62         union pds_core_adminq_cmd cmd = {
63                 .vdpa_status.opcode = PDS_VDPA_CMD_STATUS_UPDATE,
64                 .vdpa_status.vdpa_index = pdsv->vdpa_index,
65                 .vdpa_status.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
66                 .vdpa_status.status = status,
67         };
68         union pds_core_adminq_comp comp = {};
69         int err;
70
71         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_status), &comp, 0);
72         if (err)
73                 dev_dbg(dev, "Failed to set status to %#x, error status %d: %pe\n",
74                         status, comp.status, ERR_PTR(err));
75
76         return err;
77 }
78
79 int pds_vdpa_cmd_set_mac(struct pds_vdpa_device *pdsv, u8 *mac)
80 {
81         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
82         struct device *dev = &padev->aux_dev.dev;
83         union pds_core_adminq_cmd cmd = {
84                 .vdpa_setattr.opcode = PDS_VDPA_CMD_SET_ATTR,
85                 .vdpa_setattr.vdpa_index = pdsv->vdpa_index,
86                 .vdpa_setattr.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
87                 .vdpa_setattr.attr = PDS_VDPA_ATTR_MAC,
88         };
89         union pds_core_adminq_comp comp = {};
90         int err;
91
92         ether_addr_copy(cmd.vdpa_setattr.mac, mac);
93         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_setattr),
94                                     &comp, 0);
95         if (err)
96                 dev_dbg(dev, "Failed to set mac address %pM, status %d: %pe\n",
97                         mac, comp.status, ERR_PTR(err));
98
99         return err;
100 }
101
102 int pds_vdpa_cmd_set_max_vq_pairs(struct pds_vdpa_device *pdsv, u16 max_vqp)
103 {
104         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
105         struct device *dev = &padev->aux_dev.dev;
106         union pds_core_adminq_cmd cmd = {
107                 .vdpa_setattr.opcode = PDS_VDPA_CMD_SET_ATTR,
108                 .vdpa_setattr.vdpa_index = pdsv->vdpa_index,
109                 .vdpa_setattr.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
110                 .vdpa_setattr.attr = PDS_VDPA_ATTR_MAX_VQ_PAIRS,
111                 .vdpa_setattr.max_vq_pairs = cpu_to_le16(max_vqp),
112         };
113         union pds_core_adminq_comp comp = {};
114         int err;
115
116         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_setattr),
117                                     &comp, 0);
118         if (err)
119                 dev_dbg(dev, "Failed to set max vq pairs %u, status %d: %pe\n",
120                         max_vqp, comp.status, ERR_PTR(err));
121
122         return err;
123 }
124
125 int pds_vdpa_cmd_init_vq(struct pds_vdpa_device *pdsv, u16 qid, u16 invert_idx,
126                          struct pds_vdpa_vq_info *vq_info)
127 {
128         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
129         struct device *dev = &padev->aux_dev.dev;
130         union pds_core_adminq_cmd cmd = {
131                 .vdpa_vq_init.opcode = PDS_VDPA_CMD_VQ_INIT,
132                 .vdpa_vq_init.vdpa_index = pdsv->vdpa_index,
133                 .vdpa_vq_init.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
134                 .vdpa_vq_init.qid = cpu_to_le16(qid),
135                 .vdpa_vq_init.len = cpu_to_le16(ilog2(vq_info->q_len)),
136                 .vdpa_vq_init.desc_addr = cpu_to_le64(vq_info->desc_addr),
137                 .vdpa_vq_init.avail_addr = cpu_to_le64(vq_info->avail_addr),
138                 .vdpa_vq_init.used_addr = cpu_to_le64(vq_info->used_addr),
139                 .vdpa_vq_init.intr_index = cpu_to_le16(qid),
140                 .vdpa_vq_init.avail_index = cpu_to_le16(vq_info->avail_idx ^ invert_idx),
141                 .vdpa_vq_init.used_index = cpu_to_le16(vq_info->used_idx ^ invert_idx),
142         };
143         union pds_core_adminq_comp comp = {};
144         int err;
145
146         dev_dbg(dev, "%s: qid %d len %d desc_addr %#llx avail_addr %#llx used_addr %#llx\n",
147                 __func__, qid, ilog2(vq_info->q_len),
148                 vq_info->desc_addr, vq_info->avail_addr, vq_info->used_addr);
149
150         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_vq_init),
151                                     &comp, 0);
152         if (err)
153                 dev_dbg(dev, "Failed to init vq %d, status %d: %pe\n",
154                         qid, comp.status, ERR_PTR(err));
155
156         return err;
157 }
158
159 int pds_vdpa_cmd_reset_vq(struct pds_vdpa_device *pdsv, u16 qid, u16 invert_idx,
160                           struct pds_vdpa_vq_info *vq_info)
161 {
162         struct pds_auxiliary_dev *padev = pdsv->vdpa_aux->padev;
163         struct device *dev = &padev->aux_dev.dev;
164         union pds_core_adminq_cmd cmd = {
165                 .vdpa_vq_reset.opcode = PDS_VDPA_CMD_VQ_RESET,
166                 .vdpa_vq_reset.vdpa_index = pdsv->vdpa_index,
167                 .vdpa_vq_reset.vf_id = cpu_to_le16(pdsv->vdpa_aux->vf_id),
168                 .vdpa_vq_reset.qid = cpu_to_le16(qid),
169         };
170         union pds_core_adminq_comp comp = {};
171         int err;
172
173         err = pds_client_adminq_cmd(padev, &cmd, sizeof(cmd.vdpa_vq_reset),
174                                     &comp, 0);
175         if (err) {
176                 dev_dbg(dev, "Failed to reset vq %d, status %d: %pe\n",
177                         qid, comp.status, ERR_PTR(err));
178                 return err;
179         }
180
181         vq_info->avail_idx = le16_to_cpu(comp.vdpa_vq_reset.avail_index) ^ invert_idx;
182         vq_info->used_idx = le16_to_cpu(comp.vdpa_vq_reset.used_index) ^ invert_idx;
183
184         return 0;
185 }
This page took 0.041904 seconds and 4 git commands to generate.