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