Commit | Line | Data |
---|---|---|
fd88b31a HS |
1 | /* |
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | |
3 | * | |
4 | * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved. | |
5 | * | |
6 | * This software is available to you under a choice of one of two | |
7 | * licenses. You may choose to be licensed under the terms of the GNU | |
8 | * General Public License (GPL) Version 2, available from the file | |
9 | * COPYING in the main directory of this source tree, or the | |
10 | * OpenIB.org BSD license below: | |
11 | * | |
12 | * Redistribution and use in source and binary forms, with or | |
13 | * without modification, are permitted provided that the following | |
14 | * conditions are met: | |
15 | * | |
16 | * - Redistributions of source code must retain the above | |
17 | * copyright notice, this list of conditions and the following | |
18 | * disclaimer. | |
19 | * | |
20 | * - Redistributions in binary form must reproduce the above | |
21 | * copyright notice, this list of conditions and the following | |
22 | * disclaimer in the documentation and/or other materials | |
23 | * provided with the distribution. | |
24 | * | |
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
32 | * SOFTWARE. | |
33 | */ | |
34 | ||
35 | #include <linux/seq_file.h> | |
36 | #include <linux/debugfs.h> | |
37 | #include <linux/string_helpers.h> | |
38 | #include <linux/sort.h> | |
39 | ||
40 | #include "cxgb4.h" | |
41 | #include "t4_regs.h" | |
42 | #include "t4fw_api.h" | |
43 | #include "cxgb4_debugfs.h" | |
44 | #include "l2t.h" | |
45 | ||
46 | static ssize_t mem_read(struct file *file, char __user *buf, size_t count, | |
47 | loff_t *ppos) | |
48 | { | |
49 | loff_t pos = *ppos; | |
50 | loff_t avail = file_inode(file)->i_size; | |
51 | unsigned int mem = (uintptr_t)file->private_data & 3; | |
52 | struct adapter *adap = file->private_data - mem; | |
53 | __be32 *data; | |
54 | int ret; | |
55 | ||
56 | if (pos < 0) | |
57 | return -EINVAL; | |
58 | if (pos >= avail) | |
59 | return 0; | |
60 | if (count > avail - pos) | |
61 | count = avail - pos; | |
62 | ||
63 | data = t4_alloc_mem(count); | |
64 | if (!data) | |
65 | return -ENOMEM; | |
66 | ||
67 | spin_lock(&adap->win0_lock); | |
68 | ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ); | |
69 | spin_unlock(&adap->win0_lock); | |
70 | if (ret) { | |
71 | t4_free_mem(data); | |
72 | return ret; | |
73 | } | |
74 | ret = copy_to_user(buf, data, count); | |
75 | ||
76 | t4_free_mem(data); | |
77 | if (ret) | |
78 | return -EFAULT; | |
79 | ||
80 | *ppos = pos + count; | |
81 | return count; | |
82 | } | |
83 | ||
84 | static const struct file_operations mem_debugfs_fops = { | |
85 | .owner = THIS_MODULE, | |
86 | .open = simple_open, | |
87 | .read = mem_read, | |
88 | .llseek = default_llseek, | |
89 | }; | |
90 | ||
91 | static void add_debugfs_mem(struct adapter *adap, const char *name, | |
92 | unsigned int idx, unsigned int size_mb) | |
93 | { | |
94 | struct dentry *de; | |
95 | ||
96 | de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, | |
97 | (void *)adap + idx, &mem_debugfs_fops); | |
98 | if (de && de->d_inode) | |
99 | de->d_inode->i_size = size_mb << 20; | |
100 | } | |
101 | ||
102 | /* Add an array of Debug FS files. | |
103 | */ | |
104 | void add_debugfs_files(struct adapter *adap, | |
105 | struct t4_debugfs_entry *files, | |
106 | unsigned int nfiles) | |
107 | { | |
108 | int i; | |
109 | ||
110 | /* debugfs support is best effort */ | |
111 | for (i = 0; i < nfiles; i++) | |
112 | debugfs_create_file(files[i].name, files[i].mode, | |
113 | adap->debugfs_root, | |
114 | (void *)adap + files[i].data, | |
115 | files[i].ops); | |
116 | } | |
117 | ||
118 | int t4_setup_debugfs(struct adapter *adap) | |
119 | { | |
120 | int i; | |
121 | u32 size; | |
122 | ||
123 | static struct t4_debugfs_entry t4_debugfs_files[] = { | |
124 | { "l2t", &t4_l2t_fops, S_IRUSR, 0}, | |
125 | }; | |
126 | ||
127 | add_debugfs_files(adap, | |
128 | t4_debugfs_files, | |
129 | ARRAY_SIZE(t4_debugfs_files)); | |
130 | ||
6559a7e8 HS |
131 | i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); |
132 | if (i & EDRAM0_ENABLE_F) { | |
133 | size = t4_read_reg(adap, MA_EDRAM0_BAR_A); | |
134 | add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM0_SIZE_G(size)); | |
fd88b31a | 135 | } |
6559a7e8 HS |
136 | if (i & EDRAM1_ENABLE_F) { |
137 | size = t4_read_reg(adap, MA_EDRAM1_BAR_A); | |
138 | add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM1_SIZE_G(size)); | |
fd88b31a HS |
139 | } |
140 | if (is_t4(adap->params.chip)) { | |
6559a7e8 HS |
141 | size = t4_read_reg(adap, MA_EXT_MEMORY_BAR_A); |
142 | if (i & EXT_MEM_ENABLE_F) | |
fd88b31a | 143 | add_debugfs_mem(adap, "mc", MEM_MC, |
6559a7e8 | 144 | EXT_MEM_SIZE_G(size)); |
fd88b31a | 145 | } else { |
6559a7e8 HS |
146 | if (i & EXT_MEM0_ENABLE_F) { |
147 | size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); | |
fd88b31a | 148 | add_debugfs_mem(adap, "mc0", MEM_MC0, |
6559a7e8 | 149 | EXT_MEM0_SIZE_G(size)); |
fd88b31a | 150 | } |
6559a7e8 HS |
151 | if (i & EXT_MEM1_ENABLE_F) { |
152 | size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); | |
fd88b31a | 153 | add_debugfs_mem(adap, "mc1", MEM_MC1, |
6559a7e8 | 154 | EXT_MEM1_SIZE_G(size)); |
fd88b31a HS |
155 | } |
156 | } | |
157 | return 0; | |
158 | } |