diff options
-rw-r--r-- | drivers/net/iseries_veth.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 25481ea67474..9536962f5cd2 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -167,6 +167,8 @@ struct veth_port { | |||
167 | int promiscuous; | 167 | int promiscuous; |
168 | int num_mcast; | 168 | int num_mcast; |
169 | u64 mcast_addr[VETH_MAX_MCAST]; | 169 | u64 mcast_addr[VETH_MAX_MCAST]; |
170 | |||
171 | struct kobject kobject; | ||
170 | }; | 172 | }; |
171 | 173 | ||
172 | static HvLpIndex this_lp; | 174 | static HvLpIndex this_lp; |
@@ -350,6 +352,62 @@ static struct kobj_type veth_lpar_connection_ktype = { | |||
350 | .default_attrs = veth_cnx_default_attrs | 352 | .default_attrs = veth_cnx_default_attrs |
351 | }; | 353 | }; |
352 | 354 | ||
355 | struct veth_port_attribute { | ||
356 | struct attribute attr; | ||
357 | ssize_t (*show)(struct veth_port *, char *buf); | ||
358 | ssize_t (*store)(struct veth_port *, const char *buf); | ||
359 | }; | ||
360 | |||
361 | static ssize_t veth_port_attribute_show(struct kobject *kobj, | ||
362 | struct attribute *attr, char *buf) | ||
363 | { | ||
364 | struct veth_port_attribute *port_attr; | ||
365 | struct veth_port *port; | ||
366 | |||
367 | port_attr = container_of(attr, struct veth_port_attribute, attr); | ||
368 | port = container_of(kobj, struct veth_port, kobject); | ||
369 | |||
370 | if (!port_attr->show) | ||
371 | return -EIO; | ||
372 | |||
373 | return port_attr->show(port, buf); | ||
374 | } | ||
375 | |||
376 | #define CUSTOM_PORT_ATTR(_name, _format, _expression) \ | ||
377 | static ssize_t _name##_show(struct veth_port *port, char *buf) \ | ||
378 | { \ | ||
379 | return sprintf(buf, _format, _expression); \ | ||
380 | } \ | ||
381 | struct veth_port_attribute veth_port_attr_##_name = __ATTR_RO(_name) | ||
382 | |||
383 | #define SIMPLE_PORT_ATTR(_name) \ | ||
384 | CUSTOM_PORT_ATTR(_name, "%lu\n", (unsigned long)port->_name) | ||
385 | |||
386 | SIMPLE_PORT_ATTR(promiscuous); | ||
387 | SIMPLE_PORT_ATTR(num_mcast); | ||
388 | CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map); | ||
389 | CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map); | ||
390 | CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr); | ||
391 | |||
392 | #define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr) | ||
393 | static struct attribute *veth_port_default_attrs[] = { | ||
394 | GET_PORT_ATTR(mac_addr), | ||
395 | GET_PORT_ATTR(lpar_map), | ||
396 | GET_PORT_ATTR(stopped_map), | ||
397 | GET_PORT_ATTR(promiscuous), | ||
398 | GET_PORT_ATTR(num_mcast), | ||
399 | NULL | ||
400 | }; | ||
401 | |||
402 | static struct sysfs_ops veth_port_sysfs_ops = { | ||
403 | .show = veth_port_attribute_show | ||
404 | }; | ||
405 | |||
406 | static struct kobj_type veth_port_ktype = { | ||
407 | .sysfs_ops = &veth_port_sysfs_ops, | ||
408 | .default_attrs = veth_port_default_attrs | ||
409 | }; | ||
410 | |||
353 | /* | 411 | /* |
354 | * LPAR connection code | 412 | * LPAR connection code |
355 | */ | 413 | */ |
@@ -992,6 +1050,13 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) | |||
992 | return NULL; | 1050 | return NULL; |
993 | } | 1051 | } |
994 | 1052 | ||
1053 | kobject_init(&port->kobject); | ||
1054 | port->kobject.parent = &dev->class_dev.kobj; | ||
1055 | port->kobject.ktype = &veth_port_ktype; | ||
1056 | kobject_set_name(&port->kobject, "veth_port"); | ||
1057 | if (0 != kobject_add(&port->kobject)) | ||
1058 | veth_error("Failed adding port for %s to sysfs.\n", dev->name); | ||
1059 | |||
995 | veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n", | 1060 | veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n", |
996 | dev->name, vlan, port->lpar_map); | 1061 | dev->name, vlan, port->lpar_map); |
997 | 1062 | ||
@@ -1486,6 +1551,8 @@ static int veth_remove(struct vio_dev *vdev) | |||
1486 | } | 1551 | } |
1487 | 1552 | ||
1488 | veth_dev[vdev->unit_address] = NULL; | 1553 | veth_dev[vdev->unit_address] = NULL; |
1554 | kobject_del(&port->kobject); | ||
1555 | kobject_put(&port->kobject); | ||
1489 | unregister_netdev(dev); | 1556 | unregister_netdev(dev); |
1490 | free_netdev(dev); | 1557 | free_netdev(dev); |
1491 | 1558 | ||