1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
5 #include <linux/vdpa.h>
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>
16 static struct dentry
*dbfs_dir
;
18 void pds_vdpa_debugfs_create(void)
20 dbfs_dir
= debugfs_create_dir(PDS_VDPA_DRV_NAME
, NULL
);
23 void pds_vdpa_debugfs_destroy(void)
25 debugfs_remove_recursive(dbfs_dir
);
29 #define PRINT_SBIT_NAME(__seq, __f, __name) \
31 if ((__f) & (__name)) \
32 seq_printf(__seq, " %s", &#__name[16]); \
35 static void print_status_bits(struct seq_file
*seq
, u8 status
)
37 seq_puts(seq
, "status:");
38 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_ACKNOWLEDGE
);
39 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_DRIVER
);
40 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_DRIVER_OK
);
41 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_FEATURES_OK
);
42 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_NEEDS_RESET
);
43 PRINT_SBIT_NAME(seq
, status
, VIRTIO_CONFIG_S_FAILED
);
47 static void print_feature_bits_all(struct seq_file
*seq
, u64 features
)
51 seq_puts(seq
, "features:");
53 for (i
= 0; i
< (sizeof(u64
) * 8); i
++) {
54 u64 mask
= BIT_ULL(i
);
56 switch (features
& mask
) {
57 case BIT_ULL(VIRTIO_NET_F_CSUM
):
58 seq_puts(seq
, " VIRTIO_NET_F_CSUM");
60 case BIT_ULL(VIRTIO_NET_F_GUEST_CSUM
):
61 seq_puts(seq
, " VIRTIO_NET_F_GUEST_CSUM");
63 case BIT_ULL(VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
):
64 seq_puts(seq
, " VIRTIO_NET_F_CTRL_GUEST_OFFLOADS");
66 case BIT_ULL(VIRTIO_NET_F_MTU
):
67 seq_puts(seq
, " VIRTIO_NET_F_MTU");
69 case BIT_ULL(VIRTIO_NET_F_MAC
):
70 seq_puts(seq
, " VIRTIO_NET_F_MAC");
72 case BIT_ULL(VIRTIO_NET_F_GUEST_TSO4
):
73 seq_puts(seq
, " VIRTIO_NET_F_GUEST_TSO4");
75 case BIT_ULL(VIRTIO_NET_F_GUEST_TSO6
):
76 seq_puts(seq
, " VIRTIO_NET_F_GUEST_TSO6");
78 case BIT_ULL(VIRTIO_NET_F_GUEST_ECN
):
79 seq_puts(seq
, " VIRTIO_NET_F_GUEST_ECN");
81 case BIT_ULL(VIRTIO_NET_F_GUEST_UFO
):
82 seq_puts(seq
, " VIRTIO_NET_F_GUEST_UFO");
84 case BIT_ULL(VIRTIO_NET_F_HOST_TSO4
):
85 seq_puts(seq
, " VIRTIO_NET_F_HOST_TSO4");
87 case BIT_ULL(VIRTIO_NET_F_HOST_TSO6
):
88 seq_puts(seq
, " VIRTIO_NET_F_HOST_TSO6");
90 case BIT_ULL(VIRTIO_NET_F_HOST_ECN
):
91 seq_puts(seq
, " VIRTIO_NET_F_HOST_ECN");
93 case BIT_ULL(VIRTIO_NET_F_HOST_UFO
):
94 seq_puts(seq
, " VIRTIO_NET_F_HOST_UFO");
96 case BIT_ULL(VIRTIO_NET_F_MRG_RXBUF
):
97 seq_puts(seq
, " VIRTIO_NET_F_MRG_RXBUF");
99 case BIT_ULL(VIRTIO_NET_F_STATUS
):
100 seq_puts(seq
, " VIRTIO_NET_F_STATUS");
102 case BIT_ULL(VIRTIO_NET_F_CTRL_VQ
):
103 seq_puts(seq
, " VIRTIO_NET_F_CTRL_VQ");
105 case BIT_ULL(VIRTIO_NET_F_CTRL_RX
):
106 seq_puts(seq
, " VIRTIO_NET_F_CTRL_RX");
108 case BIT_ULL(VIRTIO_NET_F_CTRL_VLAN
):
109 seq_puts(seq
, " VIRTIO_NET_F_CTRL_VLAN");
111 case BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA
):
112 seq_puts(seq
, " VIRTIO_NET_F_CTRL_RX_EXTRA");
114 case BIT_ULL(VIRTIO_NET_F_GUEST_ANNOUNCE
):
115 seq_puts(seq
, " VIRTIO_NET_F_GUEST_ANNOUNCE");
117 case BIT_ULL(VIRTIO_NET_F_MQ
):
118 seq_puts(seq
, " VIRTIO_NET_F_MQ");
120 case BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR
):
121 seq_puts(seq
, " VIRTIO_NET_F_CTRL_MAC_ADDR");
123 case BIT_ULL(VIRTIO_NET_F_HASH_REPORT
):
124 seq_puts(seq
, " VIRTIO_NET_F_HASH_REPORT");
126 case BIT_ULL(VIRTIO_NET_F_RSS
):
127 seq_puts(seq
, " VIRTIO_NET_F_RSS");
129 case BIT_ULL(VIRTIO_NET_F_RSC_EXT
):
130 seq_puts(seq
, " VIRTIO_NET_F_RSC_EXT");
132 case BIT_ULL(VIRTIO_NET_F_STANDBY
):
133 seq_puts(seq
, " VIRTIO_NET_F_STANDBY");
135 case BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX
):
136 seq_puts(seq
, " VIRTIO_NET_F_SPEED_DUPLEX");
138 case BIT_ULL(VIRTIO_F_NOTIFY_ON_EMPTY
):
139 seq_puts(seq
, " VIRTIO_F_NOTIFY_ON_EMPTY");
141 case BIT_ULL(VIRTIO_F_ANY_LAYOUT
):
142 seq_puts(seq
, " VIRTIO_F_ANY_LAYOUT");
144 case BIT_ULL(VIRTIO_F_VERSION_1
):
145 seq_puts(seq
, " VIRTIO_F_VERSION_1");
147 case BIT_ULL(VIRTIO_F_ACCESS_PLATFORM
):
148 seq_puts(seq
, " VIRTIO_F_ACCESS_PLATFORM");
150 case BIT_ULL(VIRTIO_F_RING_PACKED
):
151 seq_puts(seq
, " VIRTIO_F_RING_PACKED");
153 case BIT_ULL(VIRTIO_F_ORDER_PLATFORM
):
154 seq_puts(seq
, " VIRTIO_F_ORDER_PLATFORM");
156 case BIT_ULL(VIRTIO_F_SR_IOV
):
157 seq_puts(seq
, " VIRTIO_F_SR_IOV");
162 seq_printf(seq
, " bit_%d", i
);
170 void pds_vdpa_debugfs_add_pcidev(struct pds_vdpa_aux
*vdpa_aux
)
172 vdpa_aux
->dentry
= debugfs_create_dir(pci_name(vdpa_aux
->padev
->vf_pdev
), dbfs_dir
);
175 static int identity_show(struct seq_file
*seq
, void *v
)
177 struct pds_vdpa_aux
*vdpa_aux
= seq
->private;
178 struct vdpa_mgmt_dev
*mgmt
;
181 seq_printf(seq
, "aux_dev: %s\n",
182 dev_name(&vdpa_aux
->padev
->aux_dev
.dev
));
184 mgmt
= &vdpa_aux
->vdpa_mdev
;
185 seq_printf(seq
, "max_vqs: %d\n", mgmt
->max_supported_vqs
);
186 seq_printf(seq
, "config_attr_mask: %#llx\n", mgmt
->config_attr_mask
);
187 hw_features
= le64_to_cpu(vdpa_aux
->ident
.hw_features
);
188 seq_printf(seq
, "hw_features: %#llx\n", hw_features
);
189 print_feature_bits_all(seq
, hw_features
);
193 DEFINE_SHOW_ATTRIBUTE(identity
);
195 void pds_vdpa_debugfs_add_ident(struct pds_vdpa_aux
*vdpa_aux
)
197 debugfs_create_file("identity", 0400, vdpa_aux
->dentry
,
198 vdpa_aux
, &identity_fops
);
201 static int config_show(struct seq_file
*seq
, void *v
)
203 struct pds_vdpa_device
*pdsv
= seq
->private;
204 struct virtio_net_config vc
;
207 memcpy_fromio(&vc
, pdsv
->vdpa_aux
->vd_mdev
.device
,
208 sizeof(struct virtio_net_config
));
210 seq_printf(seq
, "mac: %pM\n", vc
.mac
);
211 seq_printf(seq
, "max_virtqueue_pairs: %d\n",
212 __virtio16_to_cpu(true, vc
.max_virtqueue_pairs
));
213 seq_printf(seq
, "mtu: %d\n", __virtio16_to_cpu(true, vc
.mtu
));
214 seq_printf(seq
, "speed: %d\n", le32_to_cpu(vc
.speed
));
215 seq_printf(seq
, "duplex: %d\n", vc
.duplex
);
216 seq_printf(seq
, "rss_max_key_size: %d\n", vc
.rss_max_key_size
);
217 seq_printf(seq
, "rss_max_indirection_table_length: %d\n",
218 le16_to_cpu(vc
.rss_max_indirection_table_length
));
219 seq_printf(seq
, "supported_hash_types: %#x\n",
220 le32_to_cpu(vc
.supported_hash_types
));
221 seq_printf(seq
, "vn_status: %#x\n",
222 __virtio16_to_cpu(true, vc
.status
));
224 status
= vp_modern_get_status(&pdsv
->vdpa_aux
->vd_mdev
);
225 seq_printf(seq
, "dev_status: %#x\n", status
);
226 print_status_bits(seq
, status
);
227 seq_printf(seq
, "negotiated_features: %#llx\n", pdsv
->negotiated_features
);
228 print_feature_bits_all(seq
, pdsv
->negotiated_features
);
229 seq_printf(seq
, "vdpa_index: %d\n", pdsv
->vdpa_index
);
230 seq_printf(seq
, "num_vqs: %d\n", pdsv
->num_vqs
);
234 DEFINE_SHOW_ATTRIBUTE(config
);
236 static int vq_show(struct seq_file
*seq
, void *v
)
238 struct pds_vdpa_vq_info
*vq
= seq
->private;
240 seq_printf(seq
, "ready: %d\n", vq
->ready
);
241 seq_printf(seq
, "desc_addr: %#llx\n", vq
->desc_addr
);
242 seq_printf(seq
, "avail_addr: %#llx\n", vq
->avail_addr
);
243 seq_printf(seq
, "used_addr: %#llx\n", vq
->used_addr
);
244 seq_printf(seq
, "q_len: %d\n", vq
->q_len
);
245 seq_printf(seq
, "qid: %d\n", vq
->qid
);
247 seq_printf(seq
, "doorbell: %#llx\n", vq
->doorbell
);
248 seq_printf(seq
, "avail_idx: %d\n", vq
->avail_idx
);
249 seq_printf(seq
, "used_idx: %d\n", vq
->used_idx
);
250 seq_printf(seq
, "irq: %d\n", vq
->irq
);
251 seq_printf(seq
, "irq-name: %s\n", vq
->irq_name
);
255 DEFINE_SHOW_ATTRIBUTE(vq
);
257 void pds_vdpa_debugfs_add_vdpadev(struct pds_vdpa_aux
*vdpa_aux
)
261 debugfs_create_file("config", 0400, vdpa_aux
->dentry
, vdpa_aux
->pdsv
, &config_fops
);
263 for (i
= 0; i
< vdpa_aux
->pdsv
->num_vqs
; i
++) {
266 snprintf(name
, sizeof(name
), "vq%02d", i
);
267 debugfs_create_file(name
, 0400, vdpa_aux
->dentry
,
268 &vdpa_aux
->pdsv
->vqs
[i
], &vq_fops
);
272 void pds_vdpa_debugfs_del_vdpadev(struct pds_vdpa_aux
*vdpa_aux
)
274 debugfs_remove_recursive(vdpa_aux
->dentry
);
275 vdpa_aux
->dentry
= NULL
;
278 void pds_vdpa_debugfs_reset_vdpadev(struct pds_vdpa_aux
*vdpa_aux
)
280 /* we don't keep track of the entries, so remove it all
281 * then rebuild the basics
283 pds_vdpa_debugfs_del_vdpadev(vdpa_aux
);
284 pds_vdpa_debugfs_add_pcidev(vdpa_aux
);
285 pds_vdpa_debugfs_add_ident(vdpa_aux
);