aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c177
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c72
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c26
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c7
5 files changed, 235 insertions, 62 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0095acc0fbbe..9923a15a9996 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -179,6 +179,7 @@ struct ipoib_dev_priv {
179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
180 struct list_head fs_list; 180 struct list_head fs_list;
181 struct dentry *mcg_dentry; 181 struct dentry *mcg_dentry;
182 struct dentry *path_dentry;
182#endif 183#endif
183}; 184};
184 185
@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev);
270 271
271#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 272#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
272struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); 273struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
273void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); 274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, 275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
276 union ib_gid *gid, 276 union ib_gid *gid,
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
278 unsigned int *queuelen, 278 unsigned int *queuelen,
279 unsigned int *complete, 279 unsigned int *complete,
280 unsigned int *send_only); 280 unsigned int *send_only);
281
282struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
283int ipoib_path_iter_next(struct ipoib_path_iter *iter);
284void ipoib_path_iter_read(struct ipoib_path_iter *iter,
285 struct ipoib_path *path);
281#endif 286#endif
282 287
283int ipoib_mcast_attach(struct net_device *dev, u16 mlid, 288int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
299int ipoib_pkey_dev_delay_open(struct net_device *dev); 304int ipoib_pkey_dev_delay_open(struct net_device *dev);
300 305
301#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 306#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
302int ipoib_create_debug_file(struct net_device *dev); 307void ipoib_create_debug_files(struct net_device *dev);
303void ipoib_delete_debug_file(struct net_device *dev); 308void ipoib_delete_debug_files(struct net_device *dev);
304int ipoib_register_debugfs(void); 309int ipoib_register_debugfs(void);
305void ipoib_unregister_debugfs(void); 310void ipoib_unregister_debugfs(void);
306#else 311#else
307static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; } 312static inline void ipoib_create_debug_files(struct net_device *dev) { }
308static inline void ipoib_delete_debug_file(struct net_device *dev) { } 313static inline void ipoib_delete_debug_files(struct net_device *dev) { }
309static inline int ipoib_register_debugfs(void) { return 0; } 314static inline int ipoib_register_debugfs(void) { return 0; }
310static inline void ipoib_unregister_debugfs(void) { } 315static inline void ipoib_unregister_debugfs(void) { }
311#endif 316#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f775e7..685258e34034 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;
43 43
44static struct dentry *ipoib_root; 44static struct dentry *ipoib_root;
45 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
46static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) 58static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
47{ 59{
48 struct ipoib_mcast_iter *iter; 60 struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
54 66
55 while (n--) { 67 while (n--) {
56 if (ipoib_mcast_iter_next(iter)) { 68 if (ipoib_mcast_iter_next(iter)) {
57 ipoib_mcast_iter_free(iter); 69 kfree(iter);
58 return NULL; 70 return NULL;
59 } 71 }
60 } 72 }
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
70 (*pos)++; 82 (*pos)++;
71 83
72 if (ipoib_mcast_iter_next(iter)) { 84 if (ipoib_mcast_iter_next(iter)) {
73 ipoib_mcast_iter_free(iter); 85 kfree(iter);
74 return NULL; 86 return NULL;
75 } 87 }
76 88
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
87 struct ipoib_mcast_iter *iter = iter_ptr; 99 struct ipoib_mcast_iter *iter = iter_ptr;
88 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; 100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
89 union ib_gid mgid; 101 union ib_gid mgid;
90 int i, n;
91 unsigned long created; 102 unsigned long created;
92 unsigned int queuelen, complete, send_only; 103 unsigned int queuelen, complete, send_only;
93 104
94 if (iter) { 105 if (!iter)
95 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, 106 return 0;
96 &complete, &send_only);
97 107
98 for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { 108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
99 n += sprintf(gid_buf + n, "%x", 109 &complete, &send_only);
100 be16_to_cpu(((__be16 *) mgid.raw)[i]));
101 if (i < sizeof mgid / 2 - 1)
102 gid_buf[n++] = ':';
103 }
104 }
105 110
106 seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf); 111 format_gid(&mgid, gid_buf);
107 112
108 seq_printf(file, 113 seq_printf(file,
109 " created: %10ld queuelen: %4d complete: %d send_only: %d\n", 114 "GID: %s\n"
110 created, queuelen, complete, send_only); 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");
111 123
112 return 0; 124 return 0;
113} 125}
114 126
115static struct seq_operations ipoib_seq_ops = { 127static struct seq_operations ipoib_mcg_seq_ops = {
116 .start = ipoib_mcg_seq_start, 128 .start = ipoib_mcg_seq_start,
117 .next = ipoib_mcg_seq_next, 129 .next = ipoib_mcg_seq_next,
118 .stop = ipoib_mcg_seq_stop, 130 .stop = ipoib_mcg_seq_stop,
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
124 struct seq_file *seq; 136 struct seq_file *seq;
125 int ret; 137 int ret;
126 138
127 ret = seq_open(file, &ipoib_seq_ops); 139 ret = seq_open(file, &ipoib_mcg_seq_ops);
128 if (ret) 140 if (ret)
129 return ret; 141 return ret;
130 142
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
134 return 0; 146 return 0;
135} 147}
136 148
137static struct file_operations ipoib_fops = { 149static struct file_operations ipoib_mcg_fops = {
138 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
139 .open = ipoib_mcg_open, 151 .open = ipoib_mcg_open,
140 .read = seq_read, 152 .read = seq_read,
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = {
142 .release = seq_release 154 .release = seq_release
143}; 155};
144 156
145int ipoib_create_debug_file(struct net_device *dev) 157static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
158{
159 struct ipoib_path_iter *iter;
160 loff_t n = *pos;
161
162 iter = ipoib_path_iter_init(file->private);
163 if (!iter)
164 return NULL;
165
166 while (n--) {
167 if (ipoib_path_iter_next(iter)) {
168 kfree(iter);
169 return NULL;
170 }
171 }
172
173 return iter;
174}
175
176static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
177 loff_t *pos)
178{
179 struct ipoib_path_iter *iter = iter_ptr;
180
181 (*pos)++;
182
183 if (ipoib_path_iter_next(iter)) {
184 kfree(iter);
185 return NULL;
186 }
187
188 return iter;
189}
190
191static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
192{
193 /* nothing for now */
194}
195
196static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
197{
198 struct ipoib_path_iter *iter = iter_ptr;
199 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
200 struct ipoib_path path;
201 int rate;
202
203 if (!iter)
204 return 0;
205
206 ipoib_path_iter_read(iter, &path);
207
208 format_gid(&path.pathrec.dgid, gid_buf);
209
210 seq_printf(file,
211 "GID: %s\n"
212 " complete: %6s\n",
213 gid_buf, path.pathrec.dlid ? "yes" : "no");
214
215 if (path.pathrec.dlid) {
216 rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
217
218 seq_printf(file,
219 " DLID: 0x%04x\n"
220 " SL: %12d\n"
221 " rate: %*d%s Gb/sec\n",
222 be16_to_cpu(path.pathrec.dlid),
223 path.pathrec.sl,
224 10 - ((rate % 10) ? 2 : 0),
225 rate / 10, rate % 10 ? ".5" : "");
226 }
227
228 seq_putc(file, '\n');
229
230 return 0;
231}
232
233static struct seq_operations ipoib_path_seq_ops = {
234 .start = ipoib_path_seq_start,
235 .next = ipoib_path_seq_next,
236 .stop = ipoib_path_seq_stop,
237 .show = ipoib_path_seq_show,
238};
239
240static int ipoib_path_open(struct inode *inode, struct file *file)
241{
242 struct seq_file *seq;
243 int ret;
244
245 ret = seq_open(file, &ipoib_path_seq_ops);
246 if (ret)
247 return ret;
248
249 seq = file->private_data;
250 seq->private = inode->u.generic_ip;
251
252 return 0;
253}
254
255static struct file_operations ipoib_path_fops = {
256 .owner = THIS_MODULE,
257 .open = ipoib_path_open,
258 .read = seq_read,
259 .llseek = seq_lseek,
260 .release = seq_release
261};
262
263void ipoib_create_debug_files(struct net_device *dev)
146{ 264{
147 struct ipoib_dev_priv *priv = netdev_priv(dev); 265 struct ipoib_dev_priv *priv = netdev_priv(dev);
148 char name[IFNAMSIZ + sizeof "_mcg"]; 266 char name[IFNAMSIZ + sizeof "_path"];
149 267
150 snprintf(name, sizeof name, "%s_mcg", dev->name); 268 snprintf(name, sizeof name, "%s_mcg", dev->name);
151
152 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, 269 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
153 ipoib_root, dev, &ipoib_fops); 270 ipoib_root, dev, &ipoib_mcg_fops);
154 271 if (!priv->mcg_dentry)
155 return priv->mcg_dentry ? 0 : -ENOMEM; 272 ipoib_warn(priv, "failed to create mcg debug file\n");
273
274 snprintf(name, sizeof name, "%s_path", dev->name);
275 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
276 ipoib_root, dev, &ipoib_path_fops);
277 if (!priv->path_dentry)
278 ipoib_warn(priv, "failed to create path debug file\n");
156} 279}
157 280
158void ipoib_delete_debug_file(struct net_device *dev) 281void ipoib_delete_debug_files(struct net_device *dev)
159{ 282{
160 struct ipoib_dev_priv *priv = netdev_priv(dev); 283 struct ipoib_dev_priv *priv = netdev_priv(dev);
161 284
162 if (priv->mcg_dentry) 285 if (priv->mcg_dentry)
163 debugfs_remove(priv->mcg_dentry); 286 debugfs_remove(priv->mcg_dentry);
287 if (priv->path_dentry)
288 debugfs_remove(priv->path_dentry);
164} 289}
165 290
166int ipoib_register_debugfs(void) 291int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce0296273e76..2fa30751f362 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); 58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
59#endif 59#endif
60 60
61struct ipoib_path_iter {
62 struct net_device *dev;
63 struct ipoib_path path;
64};
65
61static const u8 ipv4_bcast_addr[] = { 66static const u8 ipv4_bcast_addr[] = {
62 0x00, 0xff, 0xff, 0xff, 67 0x00, 0xff, 0xff, 0xff,
63 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 68 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
250 kfree(path); 255 kfree(path);
251} 256}
252 257
258#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
259
260struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
261{
262 struct ipoib_path_iter *iter;
263
264 iter = kmalloc(sizeof *iter, GFP_KERNEL);
265 if (!iter)
266 return NULL;
267
268 iter->dev = dev;
269 memset(iter->path.pathrec.dgid.raw, 0, 16);
270
271 if (ipoib_path_iter_next(iter)) {
272 kfree(iter);
273 return NULL;
274 }
275
276 return iter;
277}
278
279int ipoib_path_iter_next(struct ipoib_path_iter *iter)
280{
281 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
282 struct rb_node *n;
283 struct ipoib_path *path;
284 int ret = 1;
285
286 spin_lock_irq(&priv->lock);
287
288 n = rb_first(&priv->path_tree);
289
290 while (n) {
291 path = rb_entry(n, struct ipoib_path, rb_node);
292
293 if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
294 sizeof (union ib_gid)) < 0) {
295 iter->path = *path;
296 ret = 0;
297 break;
298 }
299
300 n = rb_next(n);
301 }
302
303 spin_unlock_irq(&priv->lock);
304
305 return ret;
306}
307
308void ipoib_path_iter_read(struct ipoib_path_iter *iter,
309 struct ipoib_path *path)
310{
311 *path = iter->path;
312}
313
314#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
315
253void ipoib_flush_paths(struct net_device *dev) 316void ipoib_flush_paths(struct net_device *dev)
254{ 317{
255 struct ipoib_dev_priv *priv = netdev_priv(dev); 318 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
763{ 826{
764 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; 827 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
765 828
766 ipoib_delete_debug_file(dev); 829 ipoib_delete_debug_files(dev);
767 830
768 /* Delete any child interfaces first */ 831 /* Delete any child interfaces first */
769 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { 832 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format,
972 goto register_failed; 1035 goto register_failed;
973 } 1036 }
974 1037
975 if (ipoib_create_debug_file(priv->dev)) 1038 ipoib_create_debug_files(priv->dev);
976 goto debug_failed;
977 1039
978 if (ipoib_add_pkey_attr(priv->dev)) 1040 if (ipoib_add_pkey_attr(priv->dev))
979 goto sysfs_failed; 1041 goto sysfs_failed;
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format,
987 return priv->dev; 1049 return priv->dev;
988 1050
989sysfs_failed: 1051sysfs_failed:
990 ipoib_delete_debug_file(priv->dev); 1052 ipoib_delete_debug_files(priv->dev);
991
992debug_failed:
993 unregister_netdev(priv->dev); 1053 unregister_netdev(priv->dev);
994 1054
995register_failed: 1055register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3ecf78a9493a..c33ed87f9dff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
120 if (mcast->ah) 120 if (mcast->ah)
121 ipoib_put_ah(mcast->ah); 121 ipoib_put_ah(mcast->ah);
122 122
123 while (!skb_queue_empty(&mcast->pkt_queue)) { 123 while (!skb_queue_empty(&mcast->pkt_queue))
124 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 124 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
125
126 skb->dev = dev;
127 dev_kfree_skb_any(skb);
128 }
129 125
130 kfree(mcast); 126 kfree(mcast);
131} 127}
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status,
317 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 313 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
318 314
319 /* Flush out any queued packets */ 315 /* Flush out any queued packets */
320 while (!skb_queue_empty(&mcast->pkt_queue)) { 316 while (!skb_queue_empty(&mcast->pkt_queue))
321 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 317 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
322
323 skb->dev = dev;
324
325 dev_kfree_skb_any(skb);
326 }
327 318
328 /* Clear the busy flag so we try again */ 319 /* Clear the busy flag so we try again */
329 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 320 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
928 return NULL; 919 return NULL;
929 920
930 iter->dev = dev; 921 iter->dev = dev;
931 memset(iter->mgid.raw, 0, sizeof iter->mgid); 922 memset(iter->mgid.raw, 0, 16);
932 923
933 if (ipoib_mcast_iter_next(iter)) { 924 if (ipoib_mcast_iter_next(iter)) {
934 ipoib_mcast_iter_free(iter); 925 kfree(iter);
935 return NULL; 926 return NULL;
936 } 927 }
937 928
938 return iter; 929 return iter;
939} 930}
940 931
941void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
942{
943 kfree(iter);
944}
945
946int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) 932int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
947{ 933{
948 struct ipoib_dev_priv *priv = netdev_priv(iter->dev); 934 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730e60c2..d280b341a37f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
113 113
114 priv->parent = ppriv->dev; 114 priv->parent = ppriv->dev;
115 115
116 if (ipoib_create_debug_file(priv->dev)) 116 ipoib_create_debug_files(priv->dev);
117 goto debug_failed;
118 117
119 if (ipoib_add_pkey_attr(priv->dev)) 118 if (ipoib_add_pkey_attr(priv->dev))
120 goto sysfs_failed; 119 goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
130 return 0; 129 return 0;
131 130
132sysfs_failed: 131sysfs_failed:
133 ipoib_delete_debug_file(priv->dev); 132 ipoib_delete_debug_files(priv->dev);
134
135debug_failed:
136 unregister_netdev(priv->dev); 133 unregister_netdev(priv->dev);
137 134
138register_failed: 135register_failed: