xref: /openbmc/linux/drivers/infiniband/hw/mlx4/sysfs.c (revision 99ee4df6)
1 /*
2  * Copyright (c) 2012 Mellanox Technologies.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        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 OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 /*#include "core_priv.h"*/
34 #include "mlx4_ib.h"
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
38 
39 #include <rdma/ib_mad.h>
40 /*show_admin_alias_guid returns the administratively assigned value of that GUID.
41  * Values returned in buf parameter string:
42  *	0			- requests opensm to assign a value.
43  *	ffffffffffffffff	- delete this entry.
44  *	other			- value assigned by administrator.
45  */
46 static ssize_t show_admin_alias_guid(struct device *dev,
47 			      struct device_attribute *attr, char *buf)
48 {
49 	int record_num;/*0-15*/
50 	int guid_index_in_rec; /*0 - 7*/
51 	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
52 		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
53 	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
54 	struct mlx4_ib_dev *mdev = port->dev;
55 
56 	record_num = mlx4_ib_iov_dentry->entry_num / 8 ;
57 	guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8 ;
58 
59 	return sprintf(buf, "%llx\n",
60 		       be64_to_cpu(*(__be64 *)&mdev->sriov.alias_guid.
61 				   ports_guid[port->num - 1].
62 				   all_rec_per_port[record_num].
63 				   all_recs[8 * guid_index_in_rec]));
64 }
65 
66 /* store_admin_alias_guid stores the (new) administratively assigned value of that GUID.
67  * Values in buf parameter string:
68  *	0			- requests opensm to assign a value.
69  *	0xffffffffffffffff	- delete this entry.
70  *	other			- guid value assigned by the administrator.
71  */
72 static ssize_t store_admin_alias_guid(struct device *dev,
73 				      struct device_attribute *attr,
74 				      const char *buf, size_t count)
75 {
76 	int record_num;/*0-15*/
77 	int guid_index_in_rec; /*0 - 7*/
78 	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
79 		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
80 	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
81 	struct mlx4_ib_dev *mdev = port->dev;
82 	u64 sysadmin_ag_val;
83 	unsigned long flags;
84 
85 	record_num = mlx4_ib_iov_dentry->entry_num / 8;
86 	guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8;
87 	if (0 == record_num && 0 == guid_index_in_rec) {
88 		pr_err("GUID 0 block 0 is RO\n");
89 		return count;
90 	}
91 	spin_lock_irqsave(&mdev->sriov.alias_guid.ag_work_lock, flags);
92 	sscanf(buf, "%llx", &sysadmin_ag_val);
93 	*(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1].
94 		all_rec_per_port[record_num].
95 		all_recs[GUID_REC_SIZE * guid_index_in_rec] =
96 			cpu_to_be64(sysadmin_ag_val);
97 
98 	/* Change the state to be pending for update */
99 	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status
100 		= MLX4_GUID_INFO_STATUS_IDLE ;
101 	switch (sysadmin_ag_val) {
102 	case MLX4_GUID_FOR_DELETE_VAL:
103 		mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
104 			= MLX4_GUID_SYSADMIN_ASSIGN;
105 		break;
106 	/* The sysadmin requests the SM to re-assign */
107 	case MLX4_NOT_SET_GUID:
108 		mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
109 			= MLX4_GUID_DRIVER_ASSIGN;
110 		break;
111 	/* The sysadmin requests a specific value.*/
112 	default:
113 		mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
114 			= MLX4_GUID_SYSADMIN_ASSIGN;
115 		break;
116 	}
117 
118 	/* set the record index */
119 	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes
120 		|= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec);
121 
122 	spin_unlock_irqrestore(&mdev->sriov.alias_guid.ag_work_lock, flags);
123 	mlx4_ib_init_alias_guid_work(mdev, port->num - 1);
124 
125 	return count;
126 }
127 
128 static ssize_t show_port_gid(struct device *dev,
129 			     struct device_attribute *attr,
130 			     char *buf)
131 {
132 	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
133 		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
134 	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
135 	struct mlx4_ib_dev *mdev = port->dev;
136 	union ib_gid gid;
137 	ssize_t ret;
138 
139 	ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num,
140 				  mlx4_ib_iov_dentry->entry_num, &gid, 1);
141 	if (ret)
142 		return ret;
143 	ret = sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
144 		      be16_to_cpu(((__be16 *) gid.raw)[0]),
145 		      be16_to_cpu(((__be16 *) gid.raw)[1]),
146 		      be16_to_cpu(((__be16 *) gid.raw)[2]),
147 		      be16_to_cpu(((__be16 *) gid.raw)[3]),
148 		      be16_to_cpu(((__be16 *) gid.raw)[4]),
149 		      be16_to_cpu(((__be16 *) gid.raw)[5]),
150 		      be16_to_cpu(((__be16 *) gid.raw)[6]),
151 		      be16_to_cpu(((__be16 *) gid.raw)[7]));
152 	return ret;
153 }
154 
155 static ssize_t show_phys_port_pkey(struct device *dev,
156 				   struct device_attribute *attr,
157 				   char *buf)
158 {
159 	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
160 		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
161 	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
162 	struct mlx4_ib_dev *mdev = port->dev;
163 	u16 pkey;
164 	ssize_t ret;
165 
166 	ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num,
167 				   mlx4_ib_iov_dentry->entry_num, &pkey, 1);
168 	if (ret)
169 		return ret;
170 
171 	return sprintf(buf, "0x%04x\n", pkey);
172 }
173 
174 #define DENTRY_REMOVE(_dentry)						\
175 do {									\
176 	sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr);	\
177 } while (0);
178 
179 static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry,
180 			      char *_name, struct kobject *_kobj,
181 			      ssize_t (*show)(struct device *dev,
182 					      struct device_attribute *attr,
183 					      char *buf),
184 			      ssize_t (*store)(struct device *dev,
185 					       struct device_attribute *attr,
186 					       const char *buf, size_t count)
187 			      )
188 {
189 	int ret = 0;
190 	struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry;
191 
192 	vdentry->ctx = _ctx;
193 	vdentry->dentry.show = show;
194 	vdentry->dentry.store = store;
195 	sysfs_attr_init(&vdentry->dentry.attr);
196 	vdentry->dentry.attr.name = vdentry->name;
197 	vdentry->dentry.attr.mode = 0;
198 	vdentry->kobj = _kobj;
199 	snprintf(vdentry->name, 15, "%s", _name);
200 
201 	if (vdentry->dentry.store)
202 		vdentry->dentry.attr.mode |= S_IWUSR;
203 
204 	if (vdentry->dentry.show)
205 		vdentry->dentry.attr.mode |= S_IRUGO;
206 
207 	ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr);
208 	if (ret) {
209 		pr_err("failed to create %s\n", vdentry->dentry.attr.name);
210 		vdentry->ctx = NULL;
211 		return ret;
212 	}
213 
214 	return ret;
215 }
216 
217 int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
218 		struct attribute *attr)
219 {
220 	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
221 	int ret;
222 
223 	ret = sysfs_create_file(port->mcgs_parent, attr);
224 	if (ret)
225 		pr_err("failed to create %s\n", attr->name);
226 
227 	return ret;
228 }
229 
230 void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
231 		struct attribute *attr)
232 {
233 	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
234 
235 	sysfs_remove_file(port->mcgs_parent, attr);
236 }
237 
238 static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
239 {
240 	int i;
241 	char buff[10];
242 	struct mlx4_ib_iov_port *port = NULL;
243 	int ret = 0 ;
244 	struct ib_port_attr attr;
245 
246 	/* get the physical gid and pkey table sizes.*/
247 	ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1);
248 	if (ret)
249 		goto err;
250 
251 	port = &device->iov_ports[port_num - 1];
252 	port->dev = device;
253 	port->num = port_num;
254 	/* Directory structure:
255 	 * iov -
256 	 *   port num -
257 	 *	admin_guids
258 	 *	gids (operational)
259 	 *	mcg_table
260 	 */
261 	port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar),
262 				 GFP_KERNEL);
263 	if (!port->dentr_ar) {
264 		ret = -ENOMEM;
265 		goto err;
266 	}
267 	sprintf(buff, "%d", port_num);
268 	port->cur_port = kobject_create_and_add(buff,
269 				 kobject_get(device->ports_parent));
270 	if (!port->cur_port) {
271 		ret = -ENOMEM;
272 		goto kobj_create_err;
273 	}
274 	/* admin GUIDs */
275 	port->admin_alias_parent = kobject_create_and_add("admin_guids",
276 						  kobject_get(port->cur_port));
277 	if (!port->admin_alias_parent) {
278 		ret = -ENOMEM;
279 		goto err_admin_guids;
280 	}
281 	for (i = 0 ; i < attr.gid_tbl_len; i++) {
282 		sprintf(buff, "%d", i);
283 		port->dentr_ar->dentries[i].entry_num = i;
284 		ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i],
285 					  buff, port->admin_alias_parent,
286 					  show_admin_alias_guid, store_admin_alias_guid);
287 		if (ret)
288 			goto err_admin_alias_parent;
289 	}
290 
291 	/* gids subdirectory (operational gids) */
292 	port->gids_parent = kobject_create_and_add("gids",
293 						  kobject_get(port->cur_port));
294 	if (!port->gids_parent) {
295 		ret = -ENOMEM;
296 		goto err_gids;
297 	}
298 
299 	for (i = 0 ; i < attr.gid_tbl_len; i++) {
300 		sprintf(buff, "%d", i);
301 		port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i;
302 		ret = create_sysfs_entry(port,
303 					 &port->dentr_ar->dentries[attr.gid_tbl_len + i],
304 					 buff,
305 					 port->gids_parent, show_port_gid, NULL);
306 		if (ret)
307 			goto err_gids_parent;
308 	}
309 
310 	/* physical port pkey table */
311 	port->pkeys_parent =
312 		kobject_create_and_add("pkeys", kobject_get(port->cur_port));
313 	if (!port->pkeys_parent) {
314 		ret = -ENOMEM;
315 		goto err_pkeys;
316 	}
317 
318 	for (i = 0 ; i < attr.pkey_tbl_len; i++) {
319 		sprintf(buff, "%d", i);
320 		port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i;
321 		ret = create_sysfs_entry(port,
322 					 &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i],
323 					 buff, port->pkeys_parent,
324 					 show_phys_port_pkey, NULL);
325 		if (ret)
326 			goto err_pkeys_parent;
327 	}
328 
329 	/* MCGs table */
330 	port->mcgs_parent =
331 		kobject_create_and_add("mcgs", kobject_get(port->cur_port));
332 	if (!port->mcgs_parent) {
333 		ret = -ENOMEM;
334 		goto err_mcgs;
335 	}
336 	return 0;
337 
338 err_mcgs:
339 	kobject_put(port->cur_port);
340 
341 err_pkeys_parent:
342 	kobject_put(port->pkeys_parent);
343 
344 err_pkeys:
345 	kobject_put(port->cur_port);
346 
347 err_gids_parent:
348 	kobject_put(port->gids_parent);
349 
350 err_gids:
351 	kobject_put(port->cur_port);
352 
353 err_admin_alias_parent:
354 	kobject_put(port->admin_alias_parent);
355 
356 err_admin_guids:
357 	kobject_put(port->cur_port);
358 	kobject_put(port->cur_port); /* once more for create_and_add buff */
359 
360 kobj_create_err:
361 	kobject_put(device->ports_parent);
362 	kfree(port->dentr_ar);
363 
364 err:
365 	pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
366 	       port_num, ret);
367 	return ret;
368 }
369 
370 static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max)
371 {
372 	char base_name[9];
373 
374 	/* pci_name format is: bus:dev:func -> xxxx:yy:zz.n */
375 	strlcpy(name, pci_name(dev->dev->persist->pdev), max);
376 	strncpy(base_name, name, 8); /*till xxxx:yy:*/
377 	base_name[8] = '\0';
378 	/* with no ARI only 3 last bits are used so when the fn is higher than 8
379 	 * need to add it to the dev num, so count in the last number will be
380 	 * modulo 8 */
381 	sprintf(name, "%s%.2d.%d", base_name, (i/8), (i%8));
382 }
383 
384 struct mlx4_port {
385 	struct kobject         kobj;
386 	struct mlx4_ib_dev    *dev;
387 	struct attribute_group pkey_group;
388 	struct attribute_group gid_group;
389 	struct device_attribute	enable_smi_admin;
390 	struct device_attribute	smi_enabled;
391 	int		       slave;
392 	u8                     port_num;
393 };
394 
395 
396 static void mlx4_port_release(struct kobject *kobj)
397 {
398 	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
399 	struct attribute *a;
400 	int i;
401 
402 	for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
403 		kfree(a);
404 	kfree(p->pkey_group.attrs);
405 	for (i = 0; (a = p->gid_group.attrs[i]); ++i)
406 		kfree(a);
407 	kfree(p->gid_group.attrs);
408 	kfree(p);
409 }
410 
411 struct port_attribute {
412 	struct attribute attr;
413 	ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf);
414 	ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
415 			 const char *buf, size_t count);
416 };
417 
418 static ssize_t port_attr_show(struct kobject *kobj,
419 			      struct attribute *attr, char *buf)
420 {
421 	struct port_attribute *port_attr =
422 		container_of(attr, struct port_attribute, attr);
423 	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
424 
425 	if (!port_attr->show)
426 		return -EIO;
427 	return port_attr->show(p, port_attr, buf);
428 }
429 
430 static ssize_t port_attr_store(struct kobject *kobj,
431 			       struct attribute *attr,
432 			       const char *buf, size_t size)
433 {
434 	struct port_attribute *port_attr =
435 		container_of(attr, struct port_attribute, attr);
436 	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
437 
438 	if (!port_attr->store)
439 		return -EIO;
440 	return port_attr->store(p, port_attr, buf, size);
441 }
442 
443 static const struct sysfs_ops port_sysfs_ops = {
444 	.show = port_attr_show,
445 	.store = port_attr_store,
446 };
447 
448 static struct kobj_type port_type = {
449 	.release    = mlx4_port_release,
450 	.sysfs_ops  = &port_sysfs_ops,
451 };
452 
453 struct port_table_attribute {
454 	struct port_attribute	attr;
455 	char			name[8];
456 	int			index;
457 };
458 
459 static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
460 			      char *buf)
461 {
462 	struct port_table_attribute *tab_attr =
463 		container_of(attr, struct port_table_attribute, attr);
464 	ssize_t ret = -ENODEV;
465 
466 	if (p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index] >=
467 	    (p->dev->dev->caps.pkey_table_len[p->port_num]))
468 		ret = sprintf(buf, "none\n");
469 	else
470 		ret = sprintf(buf, "%d\n",
471 			      p->dev->pkeys.virt2phys_pkey[p->slave]
472 			      [p->port_num - 1][tab_attr->index]);
473 	return ret;
474 }
475 
476 static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
477 			       const char *buf, size_t count)
478 {
479 	struct port_table_attribute *tab_attr =
480 		container_of(attr, struct port_table_attribute, attr);
481 	int idx;
482 	int err;
483 
484 	/* do not allow remapping Dom0 virtual pkey table */
485 	if (p->slave == mlx4_master_func_num(p->dev->dev))
486 		return -EINVAL;
487 
488 	if (!strncasecmp(buf, "no", 2))
489 		idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1;
490 	else if (sscanf(buf, "%i", &idx) != 1 ||
491 		 idx >= p->dev->dev->caps.pkey_table_len[p->port_num] ||
492 		 idx < 0)
493 		return -EINVAL;
494 
495 	p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1]
496 				    [tab_attr->index] = idx;
497 	mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num,
498 			     tab_attr->index, idx);
499 	err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num);
500 	if (err) {
501 		pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
502 		       " port %d, index %d\n", p->slave, p->port_num, idx);
503 		return err;
504 	}
505 	return count;
506 }
507 
508 static ssize_t show_port_gid_idx(struct mlx4_port *p,
509 				 struct port_attribute *attr, char *buf)
510 {
511 	return sprintf(buf, "%d\n", p->slave);
512 }
513 
514 static struct attribute **
515 alloc_group_attrs(ssize_t (*show)(struct mlx4_port *,
516 				  struct port_attribute *, char *buf),
517 		  ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
518 				   const char *buf, size_t count),
519 		  int len)
520 {
521 	struct attribute **tab_attr;
522 	struct port_table_attribute *element;
523 	int i;
524 
525 	tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL);
526 	if (!tab_attr)
527 		return NULL;
528 
529 	for (i = 0; i < len; i++) {
530 		element = kzalloc(sizeof (struct port_table_attribute),
531 				  GFP_KERNEL);
532 		if (!element)
533 			goto err;
534 		if (snprintf(element->name, sizeof (element->name),
535 			     "%d", i) >= sizeof (element->name)) {
536 			kfree(element);
537 			goto err;
538 		}
539 		sysfs_attr_init(&element->attr.attr);
540 		element->attr.attr.name  = element->name;
541 		if (store) {
542 			element->attr.attr.mode  = S_IWUSR | S_IRUGO;
543 			element->attr.store	 = store;
544 		} else
545 			element->attr.attr.mode  = S_IRUGO;
546 
547 		element->attr.show       = show;
548 		element->index		 = i;
549 		tab_attr[i] = &element->attr.attr;
550 	}
551 	return tab_attr;
552 
553 err:
554 	while (--i >= 0)
555 		kfree(tab_attr[i]);
556 	kfree(tab_attr);
557 	return NULL;
558 }
559 
560 static ssize_t sysfs_show_smi_enabled(struct device *dev,
561 				      struct device_attribute *attr, char *buf)
562 {
563 	struct mlx4_port *p =
564 		container_of(attr, struct mlx4_port, smi_enabled);
565 	ssize_t len = 0;
566 
567 	if (mlx4_vf_smi_enabled(p->dev->dev, p->slave, p->port_num))
568 		len = sprintf(buf, "%d\n", 1);
569 	else
570 		len = sprintf(buf, "%d\n", 0);
571 
572 	return len;
573 }
574 
575 static ssize_t sysfs_show_enable_smi_admin(struct device *dev,
576 					   struct device_attribute *attr,
577 					   char *buf)
578 {
579 	struct mlx4_port *p =
580 		container_of(attr, struct mlx4_port, enable_smi_admin);
581 	ssize_t len = 0;
582 
583 	if (mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave, p->port_num))
584 		len = sprintf(buf, "%d\n", 1);
585 	else
586 		len = sprintf(buf, "%d\n", 0);
587 
588 	return len;
589 }
590 
591 static ssize_t sysfs_store_enable_smi_admin(struct device *dev,
592 					    struct device_attribute *attr,
593 					    const char *buf, size_t count)
594 {
595 	struct mlx4_port *p =
596 		container_of(attr, struct mlx4_port, enable_smi_admin);
597 	int enable;
598 
599 	if (sscanf(buf, "%i", &enable) != 1 ||
600 	    enable < 0 || enable > 1)
601 		return -EINVAL;
602 
603 	if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable))
604 		return -EINVAL;
605 	return count;
606 }
607 
608 static int add_vf_smi_entries(struct mlx4_port *p)
609 {
610 	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
611 			IB_LINK_LAYER_ETHERNET;
612 	int ret;
613 
614 	/* do not display entries if eth transport, or if master */
615 	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
616 		return 0;
617 
618 	sysfs_attr_init(&p->smi_enabled.attr);
619 	p->smi_enabled.show = sysfs_show_smi_enabled;
620 	p->smi_enabled.store = NULL;
621 	p->smi_enabled.attr.name = "smi_enabled";
622 	p->smi_enabled.attr.mode = 0444;
623 	ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr);
624 	if (ret) {
625 		pr_err("failed to create smi_enabled\n");
626 		return ret;
627 	}
628 
629 	sysfs_attr_init(&p->enable_smi_admin.attr);
630 	p->enable_smi_admin.show = sysfs_show_enable_smi_admin;
631 	p->enable_smi_admin.store = sysfs_store_enable_smi_admin;
632 	p->enable_smi_admin.attr.name = "enable_smi_admin";
633 	p->enable_smi_admin.attr.mode = 0644;
634 	ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr);
635 	if (ret) {
636 		pr_err("failed to create enable_smi_admin\n");
637 		sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
638 		return ret;
639 	}
640 	return 0;
641 }
642 
643 static void remove_vf_smi_entries(struct mlx4_port *p)
644 {
645 	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
646 			IB_LINK_LAYER_ETHERNET;
647 
648 	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
649 		return;
650 
651 	sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
652 	sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr);
653 }
654 
655 static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
656 {
657 	struct mlx4_port *p;
658 	int i;
659 	int ret;
660 
661 	p = kzalloc(sizeof *p, GFP_KERNEL);
662 	if (!p)
663 		return -ENOMEM;
664 
665 	p->dev = dev;
666 	p->port_num = port_num;
667 	p->slave = slave;
668 
669 	ret = kobject_init_and_add(&p->kobj, &port_type,
670 				   kobject_get(dev->dev_ports_parent[slave]),
671 				   "%d", port_num);
672 	if (ret)
673 		goto err_alloc;
674 
675 	p->pkey_group.name  = "pkey_idx";
676 	p->pkey_group.attrs =
677 		alloc_group_attrs(show_port_pkey, store_port_pkey,
678 				  dev->dev->caps.pkey_table_len[port_num]);
679 	if (!p->pkey_group.attrs) {
680 		ret = -ENOMEM;
681 		goto err_alloc;
682 	}
683 
684 	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
685 	if (ret)
686 		goto err_free_pkey;
687 
688 	p->gid_group.name  = "gid_idx";
689 	p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
690 	if (!p->gid_group.attrs) {
691 		ret = -ENOMEM;
692 		goto err_free_pkey;
693 	}
694 
695 	ret = sysfs_create_group(&p->kobj, &p->gid_group);
696 	if (ret)
697 		goto err_free_gid;
698 
699 	ret = add_vf_smi_entries(p);
700 	if (ret)
701 		goto err_free_gid;
702 
703 	list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
704 	return 0;
705 
706 err_free_gid:
707 	kfree(p->gid_group.attrs[0]);
708 	kfree(p->gid_group.attrs);
709 
710 err_free_pkey:
711 	for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
712 		kfree(p->pkey_group.attrs[i]);
713 	kfree(p->pkey_group.attrs);
714 
715 err_alloc:
716 	kobject_put(dev->dev_ports_parent[slave]);
717 	kfree(p);
718 	return ret;
719 }
720 
721 static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
722 {
723 	char name[32];
724 	int err;
725 	int port;
726 	struct kobject *p, *t;
727 	struct mlx4_port *mport;
728 	struct mlx4_active_ports actv_ports;
729 
730 	get_name(dev, name, slave, sizeof name);
731 
732 	dev->pkeys.device_parent[slave] =
733 		kobject_create_and_add(name, kobject_get(dev->iov_parent));
734 
735 	if (!dev->pkeys.device_parent[slave]) {
736 		err = -ENOMEM;
737 		goto fail_dev;
738 	}
739 
740 	INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]);
741 
742 	dev->dev_ports_parent[slave] =
743 		kobject_create_and_add("ports",
744 				       kobject_get(dev->pkeys.device_parent[slave]));
745 
746 	if (!dev->dev_ports_parent[slave]) {
747 		err = -ENOMEM;
748 		goto err_ports;
749 	}
750 
751 	actv_ports = mlx4_get_active_ports(dev->dev, slave);
752 
753 	for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
754 		if (!test_bit(port - 1, actv_ports.ports))
755 			continue;
756 		err = add_port(dev, port, slave);
757 		if (err)
758 			goto err_add;
759 	}
760 	return 0;
761 
762 err_add:
763 	list_for_each_entry_safe(p, t,
764 				 &dev->pkeys.pkey_port_list[slave],
765 				 entry) {
766 		list_del(&p->entry);
767 		mport = container_of(p, struct mlx4_port, kobj);
768 		sysfs_remove_group(p, &mport->pkey_group);
769 		sysfs_remove_group(p, &mport->gid_group);
770 		remove_vf_smi_entries(mport);
771 		kobject_put(p);
772 	}
773 	kobject_put(dev->dev_ports_parent[slave]);
774 
775 err_ports:
776 	kobject_put(dev->pkeys.device_parent[slave]);
777 	/* extra put for the device_parent create_and_add */
778 	kobject_put(dev->pkeys.device_parent[slave]);
779 
780 fail_dev:
781 	kobject_put(dev->iov_parent);
782 	return err;
783 }
784 
785 static int register_pkey_tree(struct mlx4_ib_dev *device)
786 {
787 	int i;
788 
789 	if (!mlx4_is_master(device->dev))
790 		return 0;
791 
792 	for (i = 0; i <= device->dev->persist->num_vfs; ++i)
793 		register_one_pkey_tree(device, i);
794 
795 	return 0;
796 }
797 
798 static void unregister_pkey_tree(struct mlx4_ib_dev *device)
799 {
800 	int slave;
801 	struct kobject *p, *t;
802 	struct mlx4_port *port;
803 
804 	if (!mlx4_is_master(device->dev))
805 		return;
806 
807 	for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
808 		list_for_each_entry_safe(p, t,
809 					 &device->pkeys.pkey_port_list[slave],
810 					 entry) {
811 			list_del(&p->entry);
812 			port = container_of(p, struct mlx4_port, kobj);
813 			sysfs_remove_group(p, &port->pkey_group);
814 			sysfs_remove_group(p, &port->gid_group);
815 			remove_vf_smi_entries(port);
816 			kobject_put(p);
817 			kobject_put(device->dev_ports_parent[slave]);
818 		}
819 		kobject_put(device->dev_ports_parent[slave]);
820 		kobject_put(device->pkeys.device_parent[slave]);
821 		kobject_put(device->pkeys.device_parent[slave]);
822 		kobject_put(device->iov_parent);
823 	}
824 }
825 
826 int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *dev)
827 {
828 	int i;
829 	int ret = 0;
830 
831 	if (!mlx4_is_master(dev->dev))
832 		return 0;
833 
834 	dev->iov_parent =
835 		kobject_create_and_add("iov",
836 				       kobject_get(dev->ib_dev.ports_parent->parent));
837 	if (!dev->iov_parent) {
838 		ret = -ENOMEM;
839 		goto err;
840 	}
841 	dev->ports_parent =
842 		kobject_create_and_add("ports",
843 				       kobject_get(dev->iov_parent));
844 	if (!dev->ports_parent) {
845 		ret = -ENOMEM;
846 		goto err_ports;
847 	}
848 
849 	for (i = 1; i <= dev->ib_dev.phys_port_cnt; ++i) {
850 		ret = add_port_entries(dev, i);
851 		if (ret)
852 			goto err_add_entries;
853 	}
854 
855 	ret = register_pkey_tree(dev);
856 	if (ret)
857 		goto err_add_entries;
858 	return 0;
859 
860 err_add_entries:
861 	kobject_put(dev->ports_parent);
862 
863 err_ports:
864 	kobject_put(dev->iov_parent);
865 err:
866 	kobject_put(dev->ib_dev.ports_parent->parent);
867 	pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret);
868 	return ret;
869 }
870 
871 static void unregister_alias_guid_tree(struct mlx4_ib_dev *device)
872 {
873 	struct mlx4_ib_iov_port *p;
874 	int i;
875 
876 	if (!mlx4_is_master(device->dev))
877 		return;
878 
879 	for (i = 0; i < device->dev->caps.num_ports; i++) {
880 		p = &device->iov_ports[i];
881 		kobject_put(p->admin_alias_parent);
882 		kobject_put(p->gids_parent);
883 		kobject_put(p->pkeys_parent);
884 		kobject_put(p->mcgs_parent);
885 		kobject_put(p->cur_port);
886 		kobject_put(p->cur_port);
887 		kobject_put(p->cur_port);
888 		kobject_put(p->cur_port);
889 		kobject_put(p->cur_port);
890 		kobject_put(p->dev->ports_parent);
891 		kfree(p->dentr_ar);
892 	}
893 }
894 
895 void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device)
896 {
897 	unregister_alias_guid_tree(device);
898 	unregister_pkey_tree(device);
899 	kobject_put(device->ports_parent);
900 	kobject_put(device->iov_parent);
901 	kobject_put(device->iov_parent);
902 	kobject_put(device->ib_dev.ports_parent->parent);
903 }
904