@ -167,6 +167,8 @@ struct veth_port {
int promiscuous ;
int num_mcast ;
u64 mcast_addr [ VETH_MAX_MCAST ] ;
struct kobject kobject ;
} ;
static HvLpIndex this_lp ;
@ -350,6 +352,62 @@ static struct kobj_type veth_lpar_connection_ktype = {
. default_attrs = veth_cnx_default_attrs
} ;
struct veth_port_attribute {
struct attribute attr ;
ssize_t ( * show ) ( struct veth_port * , char * buf ) ;
ssize_t ( * store ) ( struct veth_port * , const char * buf ) ;
} ;
static ssize_t veth_port_attribute_show ( struct kobject * kobj ,
struct attribute * attr , char * buf )
{
struct veth_port_attribute * port_attr ;
struct veth_port * port ;
port_attr = container_of ( attr , struct veth_port_attribute , attr ) ;
port = container_of ( kobj , struct veth_port , kobject ) ;
if ( ! port_attr - > show )
return - EIO ;
return port_attr - > show ( port , buf ) ;
}
# define CUSTOM_PORT_ATTR(_name, _format, _expression) \
static ssize_t _name # # _show ( struct veth_port * port , char * buf ) \
{ \
return sprintf ( buf , _format , _expression ) ; \
} \
struct veth_port_attribute veth_port_attr_ # # _name = __ATTR_RO ( _name )
# define SIMPLE_PORT_ATTR(_name) \
CUSTOM_PORT_ATTR ( _name , " %lu \n " , ( unsigned long ) port - > _name )
SIMPLE_PORT_ATTR ( promiscuous ) ;
SIMPLE_PORT_ATTR ( num_mcast ) ;
CUSTOM_PORT_ATTR ( lpar_map , " 0x%X \n " , port - > lpar_map ) ;
CUSTOM_PORT_ATTR ( stopped_map , " 0x%X \n " , port - > stopped_map ) ;
CUSTOM_PORT_ATTR ( mac_addr , " 0x%lX \n " , port - > mac_addr ) ;
# define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr)
static struct attribute * veth_port_default_attrs [ ] = {
GET_PORT_ATTR ( mac_addr ) ,
GET_PORT_ATTR ( lpar_map ) ,
GET_PORT_ATTR ( stopped_map ) ,
GET_PORT_ATTR ( promiscuous ) ,
GET_PORT_ATTR ( num_mcast ) ,
NULL
} ;
static struct sysfs_ops veth_port_sysfs_ops = {
. show = veth_port_attribute_show
} ;
static struct kobj_type veth_port_ktype = {
. sysfs_ops = & veth_port_sysfs_ops ,
. default_attrs = veth_port_default_attrs
} ;
/*
* LPAR connection code
*/
@ -992,6 +1050,13 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
return NULL ;
}
kobject_init ( & port - > kobject ) ;
port - > kobject . parent = & dev - > class_dev . kobj ;
port - > kobject . ktype = & veth_port_ktype ;
kobject_set_name ( & port - > kobject , " veth_port " ) ;
if ( 0 ! = kobject_add ( & port - > kobject ) )
veth_error ( " Failed adding port for %s to sysfs. \n " , dev - > name ) ;
veth_info ( " %s attached to iSeries vlan %d (LPAR map = 0x%.4X) \n " ,
dev - > name , vlan , port - > lpar_map ) ;
@ -1486,6 +1551,8 @@ static int veth_remove(struct vio_dev *vdev)
}
veth_dev [ vdev - > unit_address ] = NULL ;
kobject_del ( & port - > kobject ) ;
kobject_put ( & port - > kobject ) ;
unregister_netdev ( dev ) ;
free_netdev ( dev ) ;