252 lines · c
1/*2 * Copyright (c) 2004 Topspin Communications. All rights reserved.3 *4 * This software is available to you under a choice of one of two5 * licenses. You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 * Redistribution and use in source and binary forms, with or11 * without modification, are permitted provided that the following12 * conditions are met:13 *14 * - Redistributions of source code must retain the above15 * copyright notice, this list of conditions and the following16 * disclaimer.17 *18 * - Redistributions in binary form must reproduce the above19 * copyright notice, this list of conditions and the following20 * disclaimer in the documentation and/or other materials21 * provided with the distribution.22 *23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * SOFTWARE.31 */32 33#include <linux/err.h>34#include <linux/seq_file.h>35#include <linux/slab.h>36 37struct file_operations;38 39#include <linux/debugfs.h>40#include <linux/export.h>41 42#include "ipoib.h"43 44static struct dentry *ipoib_root;45 46static void format_gid(union ib_gid *gid, char *buf)47{48 int i, n;49 50 for (n = 0, i = 0; i < 8; ++i) {51 n += sprintf(buf + n, "%x",52 be16_to_cpu(((__be16 *) gid->raw)[i]));53 if (i < 7)54 buf[n++] = ':';55 }56}57 58static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)59{60 struct ipoib_mcast_iter *iter;61 loff_t n = *pos;62 63 iter = ipoib_mcast_iter_init(file->private);64 if (!iter)65 return NULL;66 67 while (n--) {68 if (ipoib_mcast_iter_next(iter)) {69 kfree(iter);70 return NULL;71 }72 }73 74 return iter;75}76 77static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,78 loff_t *pos)79{80 struct ipoib_mcast_iter *iter = iter_ptr;81 82 (*pos)++;83 84 if (ipoib_mcast_iter_next(iter)) {85 kfree(iter);86 return NULL;87 }88 89 return iter;90}91 92static void ipoib_mcg_seq_stop(struct seq_file *file, void *iter_ptr)93{94 /* nothing for now */95}96 97static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)98{99 struct ipoib_mcast_iter *iter = iter_ptr;100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];101 union ib_gid mgid;102 unsigned long created;103 unsigned int queuelen, complete, send_only;104 105 if (!iter)106 return 0;107 108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,109 &complete, &send_only);110 111 format_gid(&mgid, gid_buf);112 113 seq_printf(file,114 "GID: %s\n"115 " created: %10ld\n"116 " queuelen: %9d\n"117 " complete: %9s\n"118 " send_only: %8s\n"119 "\n",120 gid_buf, created, queuelen,121 complete ? "yes" : "no",122 send_only ? "yes" : "no");123 124 return 0;125}126 127static const struct seq_operations ipoib_mcg_sops = {128 .start = ipoib_mcg_seq_start,129 .next = ipoib_mcg_seq_next,130 .stop = ipoib_mcg_seq_stop,131 .show = ipoib_mcg_seq_show,132};133 134DEFINE_SEQ_ATTRIBUTE(ipoib_mcg);135 136static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)137{138 struct ipoib_path_iter *iter;139 loff_t n = *pos;140 141 iter = ipoib_path_iter_init(file->private);142 if (!iter)143 return NULL;144 145 while (n--) {146 if (ipoib_path_iter_next(iter)) {147 kfree(iter);148 return NULL;149 }150 }151 152 return iter;153}154 155static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,156 loff_t *pos)157{158 struct ipoib_path_iter *iter = iter_ptr;159 160 (*pos)++;161 162 if (ipoib_path_iter_next(iter)) {163 kfree(iter);164 return NULL;165 }166 167 return iter;168}169 170static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)171{172 /* nothing for now */173}174 175static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)176{177 struct ipoib_path_iter *iter = iter_ptr;178 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];179 struct ipoib_path path;180 int rate;181 182 if (!iter)183 return 0;184 185 ipoib_path_iter_read(iter, &path);186 187 format_gid(&path.pathrec.dgid, gid_buf);188 189 seq_printf(file,190 "GID: %s\n"191 " complete: %6s\n",192 gid_buf, sa_path_get_dlid(&path.pathrec) ? "yes" : "no");193 194 if (sa_path_get_dlid(&path.pathrec)) {195 rate = ib_rate_to_mbps(path.pathrec.rate);196 197 seq_printf(file,198 " DLID: 0x%04x\n"199 " SL: %12d\n"200 " rate: %8d.%d Gb/sec\n",201 be32_to_cpu(sa_path_get_dlid(&path.pathrec)),202 path.pathrec.sl,203 rate / 1000, rate % 1000);204 }205 206 seq_putc(file, '\n');207 208 return 0;209}210 211static const struct seq_operations ipoib_path_sops = {212 .start = ipoib_path_seq_start,213 .next = ipoib_path_seq_next,214 .stop = ipoib_path_seq_stop,215 .show = ipoib_path_seq_show,216};217 218DEFINE_SEQ_ATTRIBUTE(ipoib_path);219 220void ipoib_create_debug_files(struct net_device *dev)221{222 struct ipoib_dev_priv *priv = ipoib_priv(dev);223 char name[IFNAMSIZ + sizeof("_path")];224 225 snprintf(name, sizeof(name), "%s_mcg", dev->name);226 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,227 ipoib_root, dev, &ipoib_mcg_fops);228 229 snprintf(name, sizeof(name), "%s_path", dev->name);230 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,231 ipoib_root, dev, &ipoib_path_fops);232}233 234void ipoib_delete_debug_files(struct net_device *dev)235{236 struct ipoib_dev_priv *priv = ipoib_priv(dev);237 238 debugfs_remove(priv->mcg_dentry);239 debugfs_remove(priv->path_dentry);240 priv->mcg_dentry = priv->path_dentry = NULL;241}242 243void ipoib_register_debugfs(void)244{245 ipoib_root = debugfs_create_dir("ipoib", NULL);246}247 248void ipoib_unregister_debugfs(void)249{250 debugfs_remove(ipoib_root);251}252