@ -40,8 +40,14 @@
# define DRV_NAME "dummy"
# define DRV_VERSION "1.0"
# define MAX_DUMMIES 6
static int numdummies = 1 ;
static char * phy_name [ MAX_DUMMIES ] ;
struct dummydev_priv {
struct phy_device * phydev ;
} ;
/* fake multicast ability */
static void set_multicast_list ( struct net_device * dev )
@ -112,6 +118,16 @@ static int dummy_change_carrier(struct net_device *dev, bool new_carrier)
return 0 ;
}
static int dummy_dev_ioctl ( struct net_device * ndev , struct ifreq * ifrq , int cmd )
{
struct dummydev_priv * priv = netdev_priv ( ndev ) ;
if ( priv - > phydev )
return phy_mii_ioctl ( priv - > phydev , ifrq , cmd ) ;
else
return - EOPNOTSUPP ;
}
static const struct net_device_ops dummy_netdev_ops = {
. ndo_init = dummy_dev_init ,
. ndo_uninit = dummy_dev_uninit ,
@ -121,6 +137,7 @@ static const struct net_device_ops dummy_netdev_ops = {
. ndo_set_mac_address = eth_mac_addr ,
. ndo_get_stats64 = dummy_get_stats64 ,
. ndo_change_carrier = dummy_change_carrier ,
. ndo_do_ioctl = dummy_dev_ioctl ,
} ;
static void dummy_get_drvinfo ( struct net_device * dev ,
@ -176,17 +193,54 @@ static struct rtnl_link_ops dummy_link_ops __read_mostly = {
/* Number of dummy devices to be set up by this module. */
module_param ( numdummies , int , 0 ) ;
MODULE_PARM_DESC ( numdummies , " Number of dummy pseudo devices " ) ;
module_param_array ( phy_name , charp , NULL , 0444 ) ;
MODULE_PARM_DESC ( phy_name , " Attach a PHY with given name to the net_device " ) ;
static int match_first_device ( struct device * dev , void * data )
{
const char * name = data ;
printk ( KERN_INFO " Checking PHY bus device %p(%s) \n " , dev , dev_name ( dev ) ) ;
return ! strcmp ( dev_name ( dev ) , name ) ;
}
static struct device * get_mdio_by_name ( const char * name )
{
struct device * phy ;
phy = bus_find_device ( & mdio_bus_type , NULL , ( void * ) name ,
match_first_device ) ;
printk ( KERN_INFO " Found PHY bus device at %p \n " , phy ) ;
return phy ;
}
static int __init dummy_init_one ( void )
static int __init dummy_init_one ( int i )
{
struct device * pdev ;
struct net_device * dev_dummy ;
struct dummydev_priv * priv ;
int err ;
dev_dummy = alloc_netdev ( 0 , " dummy%d " , NET_NAME_UNKNOWN , dummy_setup ) ;
dev_dummy = alloc_netdev ( sizeof ( struct dummydev_priv ) , " dummy%d " ,
NET_NAME_UNKNOWN , dummy_setup ) ;
if ( ! dev_dummy )
return - ENOMEM ;
priv = netdev_priv ( dev_dummy ) ;
dev_dummy - > rtnl_link_ops = & dummy_link_ops ;
if ( i < MAX_DUMMIES & & phy_name [ i ] ) {
/* find + attach PHY according to name given as module
* parameter */
pdev = get_mdio_by_name ( phy_name [ i ] ) ;
if ( ! pdev ) {
dev_err ( & dev_dummy - > dev , " Cannot find PHY '%s' \n " , phy_name [ i ] ) ;
err = - EINVAL ;
goto err ;
}
priv - > phydev = to_phy_device ( pdev ) ;
}
err = register_netdevice ( dev_dummy ) ;
if ( err < 0 )
goto err ;
@ -207,7 +261,7 @@ static int __init dummy_init_module(void)
goto out ;
for ( i = 0 ; i < numdummies & & ! err ; i + + ) {
err = dummy_init_one ( ) ;
err = dummy_init_one ( i ) ;
cond_resched ( ) ;
}
if ( err < 0 )