0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/err.h>
0034 #include <linux/seq_file.h>
0035 #include <linux/slab.h>
0036
0037 struct file_operations;
0038
0039 #include <linux/debugfs.h>
0040 #include <linux/export.h>
0041
0042 #include "ipoib.h"
0043
0044 static struct dentry *ipoib_root;
0045
0046 static void format_gid(union ib_gid *gid, char *buf)
0047 {
0048 int i, n;
0049
0050 for (n = 0, i = 0; i < 8; ++i) {
0051 n += sprintf(buf + n, "%x",
0052 be16_to_cpu(((__be16 *) gid->raw)[i]));
0053 if (i < 7)
0054 buf[n++] = ':';
0055 }
0056 }
0057
0058 static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
0059 {
0060 struct ipoib_mcast_iter *iter;
0061 loff_t n = *pos;
0062
0063 iter = ipoib_mcast_iter_init(file->private);
0064 if (!iter)
0065 return NULL;
0066
0067 while (n--) {
0068 if (ipoib_mcast_iter_next(iter)) {
0069 kfree(iter);
0070 return NULL;
0071 }
0072 }
0073
0074 return iter;
0075 }
0076
0077 static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
0078 loff_t *pos)
0079 {
0080 struct ipoib_mcast_iter *iter = iter_ptr;
0081
0082 (*pos)++;
0083
0084 if (ipoib_mcast_iter_next(iter)) {
0085 kfree(iter);
0086 return NULL;
0087 }
0088
0089 return iter;
0090 }
0091
0092 static void ipoib_mcg_seq_stop(struct seq_file *file, void *iter_ptr)
0093 {
0094
0095 }
0096
0097 static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
0098 {
0099 struct ipoib_mcast_iter *iter = iter_ptr;
0100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
0101 union ib_gid mgid;
0102 unsigned long created;
0103 unsigned int queuelen, complete, send_only;
0104
0105 if (!iter)
0106 return 0;
0107
0108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
0109 &complete, &send_only);
0110
0111 format_gid(&mgid, gid_buf);
0112
0113 seq_printf(file,
0114 "GID: %s\n"
0115 " created: %10ld\n"
0116 " queuelen: %9d\n"
0117 " complete: %9s\n"
0118 " send_only: %8s\n"
0119 "\n",
0120 gid_buf, created, queuelen,
0121 complete ? "yes" : "no",
0122 send_only ? "yes" : "no");
0123
0124 return 0;
0125 }
0126
0127 static const struct seq_operations ipoib_mcg_sops = {
0128 .start = ipoib_mcg_seq_start,
0129 .next = ipoib_mcg_seq_next,
0130 .stop = ipoib_mcg_seq_stop,
0131 .show = ipoib_mcg_seq_show,
0132 };
0133
0134 DEFINE_SEQ_ATTRIBUTE(ipoib_mcg);
0135
0136 static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
0137 {
0138 struct ipoib_path_iter *iter;
0139 loff_t n = *pos;
0140
0141 iter = ipoib_path_iter_init(file->private);
0142 if (!iter)
0143 return NULL;
0144
0145 while (n--) {
0146 if (ipoib_path_iter_next(iter)) {
0147 kfree(iter);
0148 return NULL;
0149 }
0150 }
0151
0152 return iter;
0153 }
0154
0155 static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
0156 loff_t *pos)
0157 {
0158 struct ipoib_path_iter *iter = iter_ptr;
0159
0160 (*pos)++;
0161
0162 if (ipoib_path_iter_next(iter)) {
0163 kfree(iter);
0164 return NULL;
0165 }
0166
0167 return iter;
0168 }
0169
0170 static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
0171 {
0172
0173 }
0174
0175 static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
0176 {
0177 struct ipoib_path_iter *iter = iter_ptr;
0178 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
0179 struct ipoib_path path;
0180 int rate;
0181
0182 if (!iter)
0183 return 0;
0184
0185 ipoib_path_iter_read(iter, &path);
0186
0187 format_gid(&path.pathrec.dgid, gid_buf);
0188
0189 seq_printf(file,
0190 "GID: %s\n"
0191 " complete: %6s\n",
0192 gid_buf, sa_path_get_dlid(&path.pathrec) ? "yes" : "no");
0193
0194 if (sa_path_get_dlid(&path.pathrec)) {
0195 rate = ib_rate_to_mbps(path.pathrec.rate);
0196
0197 seq_printf(file,
0198 " DLID: 0x%04x\n"
0199 " SL: %12d\n"
0200 " rate: %8d.%d Gb/sec\n",
0201 be32_to_cpu(sa_path_get_dlid(&path.pathrec)),
0202 path.pathrec.sl,
0203 rate / 1000, rate % 1000);
0204 }
0205
0206 seq_putc(file, '\n');
0207
0208 return 0;
0209 }
0210
0211 static const struct seq_operations ipoib_path_sops = {
0212 .start = ipoib_path_seq_start,
0213 .next = ipoib_path_seq_next,
0214 .stop = ipoib_path_seq_stop,
0215 .show = ipoib_path_seq_show,
0216 };
0217
0218 DEFINE_SEQ_ATTRIBUTE(ipoib_path);
0219
0220 void ipoib_create_debug_files(struct net_device *dev)
0221 {
0222 struct ipoib_dev_priv *priv = ipoib_priv(dev);
0223 char name[IFNAMSIZ + sizeof("_path")];
0224
0225 snprintf(name, sizeof(name), "%s_mcg", dev->name);
0226 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
0227 ipoib_root, dev, &ipoib_mcg_fops);
0228
0229 snprintf(name, sizeof(name), "%s_path", dev->name);
0230 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
0231 ipoib_root, dev, &ipoib_path_fops);
0232 }
0233
0234 void ipoib_delete_debug_files(struct net_device *dev)
0235 {
0236 struct ipoib_dev_priv *priv = ipoib_priv(dev);
0237
0238 debugfs_remove(priv->mcg_dentry);
0239 debugfs_remove(priv->path_dentry);
0240 priv->mcg_dentry = priv->path_dentry = NULL;
0241 }
0242
0243 void ipoib_register_debugfs(void)
0244 {
0245 ipoib_root = debugfs_create_dir("ipoib", NULL);
0246 }
0247
0248 void ipoib_unregister_debugfs(void)
0249 {
0250 debugfs_remove(ipoib_root);
0251 }