blob: 10581600777ab38da39f209d352e2e43e5d4fa97 [file] [log] [blame]
Sudeep Dutt3a6a9202013-09-05 16:41:55 -07001/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/debugfs.h>
22#include <linux/pci.h>
23#include <linux/seq_file.h>
24
25#include <linux/mic_common.h>
Sudeep Dutt4aa79962013-09-27 09:49:42 -070026#include "../common/mic_dev.h"
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070027#include "mic_device.h"
28#include "mic_smpt.h"
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -070029#include "mic_virtio.h"
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070030
31/* Debugfs parent dir */
32static struct dentry *mic_dbg;
33
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070034static int mic_smpt_show(struct seq_file *s, void *pos)
35{
36 int i;
37 struct mic_device *mdev = s->private;
38 unsigned long flags;
39
40 seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -070041 mdev->id, "SMPT entry", "SW DMA addr", "RefCount");
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070042 seq_puts(s, "====================================================\n");
43
44 if (mdev->smpt) {
45 struct mic_smpt_info *smpt_info = mdev->smpt;
46 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
47 for (i = 0; i < smpt_info->info.num_reg; i++) {
48 seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -070049 " ", i, smpt_info->entry[i].dma_addr,
50 smpt_info->entry[i].ref_count);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070051 }
52 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
53 }
54 seq_puts(s, "====================================================\n");
55 return 0;
56}
57
58static int mic_smpt_debug_open(struct inode *inode, struct file *file)
59{
60 return single_open(file, mic_smpt_show, inode->i_private);
61}
62
63static int mic_smpt_debug_release(struct inode *inode, struct file *file)
64{
65 return single_release(inode, file);
66}
67
68static const struct file_operations smpt_file_ops = {
69 .owner = THIS_MODULE,
70 .open = mic_smpt_debug_open,
71 .read = seq_read,
72 .llseek = seq_lseek,
73 .release = mic_smpt_debug_release
74};
75
Sudeep Dutt3a6a9202013-09-05 16:41:55 -070076static int mic_post_code_show(struct seq_file *s, void *pos)
77{
78 struct mic_device *mdev = s->private;
79 u32 reg = mdev->ops->get_postcode(mdev);
80
81 seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff);
82 return 0;
83}
84
85static int mic_post_code_debug_open(struct inode *inode, struct file *file)
86{
87 return single_open(file, mic_post_code_show, inode->i_private);
88}
89
90static int mic_post_code_debug_release(struct inode *inode, struct file *file)
91{
92 return single_release(inode, file);
93}
94
95static const struct file_operations post_code_ops = {
96 .owner = THIS_MODULE,
97 .open = mic_post_code_debug_open,
98 .read = seq_read,
99 .llseek = seq_lseek,
100 .release = mic_post_code_debug_release
101};
102
103static int mic_dp_show(struct seq_file *s, void *pos)
104{
105 struct mic_device *mdev = s->private;
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700106 struct mic_device_desc *d;
107 struct mic_device_ctrl *dc;
108 struct mic_vqconfig *vqconfig;
109 __u32 *features;
110 __u8 *config;
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700111 struct mic_bootparam *bootparam = mdev->dp;
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700112 int i, j;
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700113
114 seq_printf(s, "Bootparam: magic 0x%x\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700115 bootparam->magic);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700116 seq_printf(s, "Bootparam: h2c_config_db %d\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700117 bootparam->h2c_config_db);
Sudeep Dutt74321d42015-04-29 05:32:38 -0700118 seq_printf(s, "Bootparam: node_id %d\n",
119 bootparam->node_id);
120 seq_printf(s, "Bootparam: c2h_scif_db %d\n",
121 bootparam->c2h_scif_db);
122 seq_printf(s, "Bootparam: h2c_scif_db %d\n",
123 bootparam->h2c_scif_db);
124 seq_printf(s, "Bootparam: scif_host_dma_addr 0x%llx\n",
125 bootparam->scif_host_dma_addr);
126 seq_printf(s, "Bootparam: scif_card_dma_addr 0x%llx\n",
127 bootparam->scif_card_dma_addr);
128
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700129
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700130 for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
131 i += mic_total_desc_size(d)) {
132 d = mdev->dp + i;
133 dc = (void *)d + mic_aligned_desc_size(d);
134
135 /* end of list */
136 if (d->type == 0)
137 break;
138
139 if (d->type == -1)
140 continue;
141
142 seq_printf(s, "Type %d ", d->type);
143 seq_printf(s, "Num VQ %d ", d->num_vq);
144 seq_printf(s, "Feature Len %d\n", d->feature_len);
145 seq_printf(s, "Config Len %d ", d->config_len);
146 seq_printf(s, "Shutdown Status %d\n", d->status);
147
148 for (j = 0; j < d->num_vq; j++) {
149 vqconfig = mic_vq_config(d) + j;
150 seq_printf(s, "vqconfig[%d]: ", j);
151 seq_printf(s, "address 0x%llx ", vqconfig->address);
152 seq_printf(s, "num %d ", vqconfig->num);
153 seq_printf(s, "used address 0x%llx\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700154 vqconfig->used_address);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700155 }
156
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700157 features = (__u32 *)mic_vq_features(d);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700158 seq_printf(s, "Features: Host 0x%x ", features[0]);
159 seq_printf(s, "Guest 0x%x\n", features[1]);
160
161 config = mic_vq_configspace(d);
162 for (j = 0; j < d->config_len; j++)
163 seq_printf(s, "config[%d]=%d\n", j, config[j]);
164
165 seq_puts(s, "Device control:\n");
166 seq_printf(s, "Config Change %d ", dc->config_change);
167 seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
168 seq_printf(s, "Guest Ack %d ", dc->guest_ack);
169 seq_printf(s, "Host ack %d\n", dc->host_ack);
170 seq_printf(s, "Used address updated %d ",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700171 dc->used_address_updated);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700172 seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
173 seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
174 seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
175 }
176
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700177 return 0;
178}
179
180static int mic_dp_debug_open(struct inode *inode, struct file *file)
181{
182 return single_open(file, mic_dp_show, inode->i_private);
183}
184
185static int mic_dp_debug_release(struct inode *inode, struct file *file)
186{
187 return single_release(inode, file);
188}
189
190static const struct file_operations dp_ops = {
191 .owner = THIS_MODULE,
192 .open = mic_dp_debug_open,
193 .read = seq_read,
194 .llseek = seq_lseek,
195 .release = mic_dp_debug_release
196};
197
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700198static int mic_vdev_info_show(struct seq_file *s, void *unused)
199{
200 struct mic_device *mdev = s->private;
201 struct list_head *pos, *tmp;
202 struct mic_vdev *mvdev;
203 int i, j;
204
205 mutex_lock(&mdev->mic_mutex);
206 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
207 mvdev = list_entry(pos, struct mic_vdev, list);
208 seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700209 mvdev->virtio_id,
210 mic_vdevup(mvdev) ? "UP" : "DOWN",
211 mvdev->in_bytes,
212 mvdev->out_bytes);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700213 for (i = 0; i < MIC_MAX_VRINGS; i++) {
214 struct vring_desc *desc;
215 struct vring_avail *avail;
216 struct vring_used *used;
217 struct mic_vringh *mvr = &mvdev->mvr[i];
218 struct vringh *vrh = &mvr->vrh;
219 int num = vrh->vring.num;
220 if (!num)
221 continue;
222 desc = vrh->vring.desc;
223 seq_printf(s, "vring i %d avail_idx %d",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700224 i, mvr->vring.info->avail_idx & (num - 1));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700225 seq_printf(s, " vring i %d avail_idx %d\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700226 i, mvr->vring.info->avail_idx);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700227 seq_printf(s, "vrh i %d weak_barriers %d",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700228 i, vrh->weak_barriers);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700229 seq_printf(s, " last_avail_idx %d last_used_idx %d",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700230 vrh->last_avail_idx, vrh->last_used_idx);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700231 seq_printf(s, " completed %d\n", vrh->completed);
232 for (j = 0; j < num; j++) {
233 seq_printf(s, "desc[%d] addr 0x%llx len %d",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700234 j, desc->addr, desc->len);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700235 seq_printf(s, " flags 0x%x next %d\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700236 desc->flags, desc->next);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700237 desc++;
238 }
239 avail = vrh->vring.avail;
240 seq_printf(s, "avail flags 0x%x idx %d\n",
Michael S. Tsirkin8a38f332014-12-12 01:55:03 +0200241 vringh16_to_cpu(vrh, avail->flags),
242 vringh16_to_cpu(vrh, avail->idx) & (num - 1));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700243 seq_printf(s, "avail flags 0x%x idx %d\n",
Michael S. Tsirkin8a38f332014-12-12 01:55:03 +0200244 vringh16_to_cpu(vrh, avail->flags),
245 vringh16_to_cpu(vrh, avail->idx));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700246 for (j = 0; j < num; j++)
247 seq_printf(s, "avail ring[%d] %d\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700248 j, avail->ring[j]);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700249 used = vrh->vring.used;
250 seq_printf(s, "used flags 0x%x idx %d\n",
Michael S. Tsirkin8a38f332014-12-12 01:55:03 +0200251 vringh16_to_cpu(vrh, used->flags),
252 vringh16_to_cpu(vrh, used->idx) & (num - 1));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700253 seq_printf(s, "used flags 0x%x idx %d\n",
Michael S. Tsirkin8a38f332014-12-12 01:55:03 +0200254 vringh16_to_cpu(vrh, used->flags),
255 vringh16_to_cpu(vrh, used->idx));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700256 for (j = 0; j < num; j++)
257 seq_printf(s, "used ring[%d] id %d len %d\n",
Michael S. Tsirkin8a38f332014-12-12 01:55:03 +0200258 j, vringh32_to_cpu(vrh,
259 used->ring[j].id),
260 vringh32_to_cpu(vrh,
261 used->ring[j].len));
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700262 }
263 }
264 mutex_unlock(&mdev->mic_mutex);
265
266 return 0;
267}
268
269static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
270{
271 return single_open(file, mic_vdev_info_show, inode->i_private);
272}
273
274static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
275{
276 return single_release(inode, file);
277}
278
279static const struct file_operations vdev_info_ops = {
280 .owner = THIS_MODULE,
281 .open = mic_vdev_info_debug_open,
282 .read = seq_read,
283 .llseek = seq_lseek,
284 .release = mic_vdev_info_debug_release
285};
286
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700287static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
288{
289 struct mic_device *mdev = s->private;
290 int reg;
291 int i, j;
292 u16 entry;
293 u16 vector;
Ashutosh Dixit1da2b3e2015-09-29 18:13:26 -0700294 struct pci_dev *pdev = mdev->pdev;
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700295
296 if (pci_dev_msi_enabled(pdev)) {
297 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
298 if (pdev->msix_enabled) {
299 entry = mdev->irq_info.msix_entries[i].entry;
300 vector = mdev->irq_info.msix_entries[i].vector;
301 } else {
302 entry = 0;
303 vector = pdev->irq;
304 }
305
306 reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry);
307
308 seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700309 "IRQ:", vector, "Entry:", entry, i, reg);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700310
311 seq_printf(s, "%-10s", "offset:");
312 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
313 seq_printf(s, "%4d ", j);
314 seq_puts(s, "\n");
315
316
317 seq_printf(s, "%-10s", "count:");
318 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
319 seq_printf(s, "%4d ",
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700320 (mdev->irq_info.mic_msi_map[i] &
321 BIT(j)) ? 1 : 0);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700322 seq_puts(s, "\n\n");
323 }
324 } else {
325 seq_puts(s, "MSI/MSIx interrupts not enabled\n");
326 }
327
328 return 0;
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700329}
330
331static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
332{
333 return single_open(file, mic_msi_irq_info_show, inode->i_private);
334}
335
336static int
337mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
338{
339 return single_release(inode, file);
340}
341
342static const struct file_operations msi_irq_info_ops = {
343 .owner = THIS_MODULE,
344 .open = mic_msi_irq_info_debug_open,
345 .read = seq_read,
346 .llseek = seq_lseek,
347 .release = mic_msi_irq_info_debug_release
348};
349
350/**
351 * mic_create_debug_dir - Initialize MIC debugfs entries.
352 */
353void mic_create_debug_dir(struct mic_device *mdev)
354{
Ashutosh Dixit1da2b3e2015-09-29 18:13:26 -0700355 char name[16];
356
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700357 if (!mic_dbg)
358 return;
359
Ashutosh Dixit1da2b3e2015-09-29 18:13:26 -0700360 scnprintf(name, sizeof(name), "mic%d", mdev->id);
361 mdev->dbg_dir = debugfs_create_dir(name, mic_dbg);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700362 if (!mdev->dbg_dir)
363 return;
364
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700365 debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &smpt_file_ops);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700366
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700367 debugfs_create_file("post_code", 0444, mdev->dbg_dir, mdev,
368 &post_code_ops);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700369
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700370 debugfs_create_file("dp", 0444, mdev->dbg_dir, mdev, &dp_ops);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700371
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700372 debugfs_create_file("vdev_info", 0444, mdev->dbg_dir, mdev,
373 &vdev_info_ops);
Ashutosh Dixitf69bcbf2013-09-05 16:42:18 -0700374
Ashutosh Dixitced2c602013-09-27 09:49:53 -0700375 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, mdev,
376 &msi_irq_info_ops);
Sudeep Dutt3a6a9202013-09-05 16:41:55 -0700377}
378
379/**
380 * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
381 */
382void mic_delete_debug_dir(struct mic_device *mdev)
383{
384 if (!mdev->dbg_dir)
385 return;
386
387 debugfs_remove_recursive(mdev->dbg_dir);
388}
389
390/**
391 * mic_init_debugfs - Initialize global debugfs entry.
392 */
393void __init mic_init_debugfs(void)
394{
395 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
396 if (!mic_dbg)
397 pr_err("can't create debugfs dir\n");
398}
399
400/**
401 * mic_exit_debugfs - Uninitialize global debugfs entry
402 */
403void mic_exit_debugfs(void)
404{
405 debugfs_remove(mic_dbg);
406}