1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel MIC Platform Software Stack (MPSS)
5 * Copyright(c) 2016 Intel Corporation.
7 * Intel Virtio Over PCIe (VOP) driver.
9 #include <linux/debugfs.h>
10 #include <linux/seq_file.h>
14 static int vop_dp_show(struct seq_file
*s
, void *pos
)
16 struct mic_device_desc
*d
;
17 struct mic_device_ctrl
*dc
;
18 struct mic_vqconfig
*vqconfig
;
21 struct vop_info
*vi
= s
->private;
22 struct vop_device
*vpdev
= vi
->vpdev
;
23 struct mic_bootparam
*bootparam
= vpdev
->hw_ops
->get_dp(vpdev
);
26 seq_printf(s
, "Bootparam: magic 0x%x\n",
28 seq_printf(s
, "Bootparam: h2c_config_db %d\n",
29 bootparam
->h2c_config_db
);
30 seq_printf(s
, "Bootparam: node_id %d\n",
32 seq_printf(s
, "Bootparam: c2h_scif_db %d\n",
33 bootparam
->c2h_scif_db
);
34 seq_printf(s
, "Bootparam: h2c_scif_db %d\n",
35 bootparam
->h2c_scif_db
);
36 seq_printf(s
, "Bootparam: scif_host_dma_addr 0x%llx\n",
37 bootparam
->scif_host_dma_addr
);
38 seq_printf(s
, "Bootparam: scif_card_dma_addr 0x%llx\n",
39 bootparam
->scif_card_dma_addr
);
41 for (j
= sizeof(*bootparam
);
42 j
< MIC_DP_SIZE
; j
+= mic_total_desc_size(d
)) {
43 d
= (void *)bootparam
+ j
;
44 dc
= (void *)d
+ mic_aligned_desc_size(d
);
53 seq_printf(s
, "Type %d ", d
->type
);
54 seq_printf(s
, "Num VQ %d ", d
->num_vq
);
55 seq_printf(s
, "Feature Len %d\n", d
->feature_len
);
56 seq_printf(s
, "Config Len %d ", d
->config_len
);
57 seq_printf(s
, "Shutdown Status %d\n", d
->status
);
59 for (k
= 0; k
< d
->num_vq
; k
++) {
60 vqconfig
= mic_vq_config(d
) + k
;
61 seq_printf(s
, "vqconfig[%d]: ", k
);
62 seq_printf(s
, "address 0x%llx ",
64 seq_printf(s
, "num %d ", vqconfig
->num
);
65 seq_printf(s
, "used address 0x%llx\n",
66 vqconfig
->used_address
);
69 features
= (__u32
*)mic_vq_features(d
);
70 seq_printf(s
, "Features: Host 0x%x ", features
[0]);
71 seq_printf(s
, "Guest 0x%x\n", features
[1]);
73 config
= mic_vq_configspace(d
);
74 for (k
= 0; k
< d
->config_len
; k
++)
75 seq_printf(s
, "config[%d]=%d\n", k
, config
[k
]);
77 seq_puts(s
, "Device control:\n");
78 seq_printf(s
, "Config Change %d ", dc
->config_change
);
79 seq_printf(s
, "Vdev reset %d\n", dc
->vdev_reset
);
80 seq_printf(s
, "Guest Ack %d ", dc
->guest_ack
);
81 seq_printf(s
, "Host ack %d\n", dc
->host_ack
);
82 seq_printf(s
, "Used address updated %d ",
83 dc
->used_address_updated
);
84 seq_printf(s
, "Vdev 0x%llx\n", dc
->vdev
);
85 seq_printf(s
, "c2h doorbell %d ", dc
->c2h_vdev_db
);
86 seq_printf(s
, "h2c doorbell %d\n", dc
->h2c_vdev_db
);
88 schedule_work(&vi
->hotplug_work
);
92 DEFINE_SHOW_ATTRIBUTE(vop_dp
);
94 static int vop_vdev_info_show(struct seq_file
*s
, void *unused
)
96 struct vop_info
*vi
= s
->private;
97 struct list_head
*pos
, *tmp
;
98 struct vop_vdev
*vdev
;
101 mutex_lock(&vi
->vop_mutex
);
102 list_for_each_safe(pos
, tmp
, &vi
->vdev_list
) {
103 vdev
= list_entry(pos
, struct vop_vdev
, list
);
104 seq_printf(s
, "VDEV type %d state %s in %ld out %ld in_dma %ld out_dma %ld\n",
106 vop_vdevup(vdev
) ? "UP" : "DOWN",
110 vdev
->out_bytes_dma
);
111 for (i
= 0; i
< MIC_MAX_VRINGS
; i
++) {
112 struct vring_desc
*desc
;
113 struct vring_avail
*avail
;
114 struct vring_used
*used
;
115 struct vop_vringh
*vvr
= &vdev
->vvr
[i
];
116 struct vringh
*vrh
= &vvr
->vrh
;
117 int num
= vrh
->vring
.num
;
121 desc
= vrh
->vring
.desc
;
122 seq_printf(s
, "vring i %d avail_idx %d",
123 i
, vvr
->vring
.info
->avail_idx
& (num
- 1));
124 seq_printf(s
, " vring i %d avail_idx %d\n",
125 i
, vvr
->vring
.info
->avail_idx
);
126 seq_printf(s
, "vrh i %d weak_barriers %d",
127 i
, vrh
->weak_barriers
);
128 seq_printf(s
, " last_avail_idx %d last_used_idx %d",
129 vrh
->last_avail_idx
, vrh
->last_used_idx
);
130 seq_printf(s
, " completed %d\n", vrh
->completed
);
131 for (j
= 0; j
< num
; j
++) {
132 seq_printf(s
, "desc[%d] addr 0x%llx len %d",
133 j
, desc
->addr
, desc
->len
);
134 seq_printf(s
, " flags 0x%x next %d\n",
135 desc
->flags
, desc
->next
);
138 avail
= vrh
->vring
.avail
;
139 seq_printf(s
, "avail flags 0x%x idx %d\n",
140 vringh16_to_cpu(vrh
, avail
->flags
),
142 avail
->idx
) & (num
- 1));
143 seq_printf(s
, "avail flags 0x%x idx %d\n",
144 vringh16_to_cpu(vrh
, avail
->flags
),
145 vringh16_to_cpu(vrh
, avail
->idx
));
146 for (j
= 0; j
< num
; j
++)
147 seq_printf(s
, "avail ring[%d] %d\n",
149 used
= vrh
->vring
.used
;
150 seq_printf(s
, "used flags 0x%x idx %d\n",
151 vringh16_to_cpu(vrh
, used
->flags
),
152 vringh16_to_cpu(vrh
, used
->idx
) & (num
- 1));
153 seq_printf(s
, "used flags 0x%x idx %d\n",
154 vringh16_to_cpu(vrh
, used
->flags
),
155 vringh16_to_cpu(vrh
, used
->idx
));
156 for (j
= 0; j
< num
; j
++)
157 seq_printf(s
, "used ring[%d] id %d len %d\n",
158 j
, vringh32_to_cpu(vrh
,
164 mutex_unlock(&vi
->vop_mutex
);
169 DEFINE_SHOW_ATTRIBUTE(vop_vdev_info
);
171 void vop_init_debugfs(struct vop_info
*vi
)
175 snprintf(name
, sizeof(name
), "%s%d", KBUILD_MODNAME
, vi
->vpdev
->dnode
);
176 vi
->dbg
= debugfs_create_dir(name
, NULL
);
177 debugfs_create_file("dp", 0444, vi
->dbg
, vi
, &vop_dp_fops
);
178 debugfs_create_file("vdev_info", 0444, vi
->dbg
, vi
, &vop_vdev_info_fops
);
181 void vop_exit_debugfs(struct vop_info
*vi
)
183 debugfs_remove_recursive(vi
->dbg
);