]>
Commit | Line | Data |
---|---|---|
4e43d779 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
8810df37 SD |
2 | /* |
3 | * Intel MIC Platform Software Stack (MPSS) | |
4 | * | |
5 | * Copyright(c) 2016 Intel Corporation. | |
6 | * | |
8810df37 | 7 | * Intel Virtio Over PCIe (VOP) driver. |
8810df37 SD |
8 | */ |
9 | #include <linux/debugfs.h> | |
10 | #include <linux/seq_file.h> | |
11 | ||
12 | #include "vop_main.h" | |
13 | ||
14 | static int vop_dp_show(struct seq_file *s, void *pos) | |
15 | { | |
16 | struct mic_device_desc *d; | |
17 | struct mic_device_ctrl *dc; | |
18 | struct mic_vqconfig *vqconfig; | |
19 | __u32 *features; | |
20 | __u8 *config; | |
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); | |
24 | int j, k; | |
25 | ||
26 | seq_printf(s, "Bootparam: magic 0x%x\n", | |
27 | bootparam->magic); | |
28 | seq_printf(s, "Bootparam: h2c_config_db %d\n", | |
29 | bootparam->h2c_config_db); | |
30 | seq_printf(s, "Bootparam: node_id %d\n", | |
31 | bootparam->node_id); | |
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); | |
40 | ||
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); | |
45 | ||
46 | /* end of list */ | |
47 | if (d->type == 0) | |
48 | break; | |
49 | ||
50 | if (d->type == -1) | |
51 | continue; | |
52 | ||
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); | |
58 | ||
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 ", | |
63 | vqconfig->address); | |
64 | seq_printf(s, "num %d ", vqconfig->num); | |
65 | seq_printf(s, "used address 0x%llx\n", | |
66 | vqconfig->used_address); | |
67 | } | |
68 | ||
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]); | |
72 | ||
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]); | |
76 | ||
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); | |
87 | } | |
88 | schedule_work(&vi->hotplug_work); | |
89 | return 0; | |
90 | } | |
91 | ||
2796b43f | 92 | DEFINE_SHOW_ATTRIBUTE(vop_dp); |
8810df37 SD |
93 | |
94 | static int vop_vdev_info_show(struct seq_file *s, void *unused) | |
95 | { | |
96 | struct vop_info *vi = s->private; | |
97 | struct list_head *pos, *tmp; | |
98 | struct vop_vdev *vdev; | |
99 | int i, j; | |
100 | ||
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", | |
105 | vdev->virtio_id, | |
106 | vop_vdevup(vdev) ? "UP" : "DOWN", | |
107 | vdev->in_bytes, | |
108 | vdev->out_bytes, | |
109 | vdev->in_bytes_dma, | |
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; | |
118 | ||
119 | if (!num) | |
120 | continue; | |
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); | |
136 | desc++; | |
137 | } | |
138 | avail = vrh->vring.avail; | |
139 | seq_printf(s, "avail flags 0x%x idx %d\n", | |
140 | vringh16_to_cpu(vrh, avail->flags), | |
141 | vringh16_to_cpu(vrh, | |
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", | |
148 | j, avail->ring[j]); | |
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, | |
159 | used->ring[j].id), | |
160 | vringh32_to_cpu(vrh, | |
161 | used->ring[j].len)); | |
162 | } | |
163 | } | |
164 | mutex_unlock(&vi->vop_mutex); | |
165 | ||
166 | return 0; | |
167 | } | |
168 | ||
2796b43f | 169 | DEFINE_SHOW_ATTRIBUTE(vop_vdev_info); |
8810df37 SD |
170 | |
171 | void vop_init_debugfs(struct vop_info *vi) | |
172 | { | |
173 | char name[16]; | |
174 | ||
175 | snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode); | |
176 | vi->dbg = debugfs_create_dir(name, NULL); | |
177 | if (!vi->dbg) { | |
178 | pr_err("can't create debugfs dir vop\n"); | |
179 | return; | |
180 | } | |
2796b43f YL |
181 | debugfs_create_file("dp", 0444, vi->dbg, vi, &vop_dp_fops); |
182 | debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vop_vdev_info_fops); | |
8810df37 SD |
183 | } |
184 | ||
185 | void vop_exit_debugfs(struct vop_info *vi) | |
186 | { | |
187 | debugfs_remove_recursive(vi->dbg); | |
188 | } |