@ -1266,6 +1266,85 @@ int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
return 0 ;
}
static void gelic_net_get_wol ( struct net_device * netdev ,
struct ethtool_wolinfo * wol )
{
if ( 0 < = ps3_compare_firmware_version ( 2 , 2 , 0 ) )
wol - > supported = WAKE_MAGIC ;
else
wol - > supported = 0 ;
wol - > wolopts = ps3_sys_manager_get_wol ( ) ? wol - > supported : 0 ;
memset ( & wol - > sopass , 0 , sizeof ( wol - > sopass ) ) ;
}
static int gelic_net_set_wol ( struct net_device * netdev ,
struct ethtool_wolinfo * wol )
{
int status ;
struct gelic_card * card ;
u64 v1 , v2 ;
if ( ps3_compare_firmware_version ( 2 , 2 , 0 ) < 0 | |
! capable ( CAP_NET_ADMIN ) )
return - EPERM ;
if ( wol - > wolopts & ~ WAKE_MAGIC )
return - EINVAL ;
card = netdev_card ( netdev ) ;
if ( wol - > wolopts & WAKE_MAGIC ) {
status = lv1_net_control ( bus_id ( card ) , dev_id ( card ) ,
GELIC_LV1_SET_WOL ,
GELIC_LV1_WOL_MAGIC_PACKET ,
0 , GELIC_LV1_WOL_MP_ENABLE ,
& v1 , & v2 ) ;
if ( status ) {
pr_info ( " %s: enabling WOL failed %d \n " , __func__ ,
status ) ;
status = - EIO ;
goto done ;
}
status = lv1_net_control ( bus_id ( card ) , dev_id ( card ) ,
GELIC_LV1_SET_WOL ,
GELIC_LV1_WOL_ADD_MATCH_ADDR ,
0 , GELIC_LV1_WOL_MATCH_ALL ,
& v1 , & v2 ) ;
if ( ! status )
ps3_sys_manager_set_wol ( 1 ) ;
else {
pr_info ( " %s: enabling WOL filter failed %d \n " ,
__func__ , status ) ;
status = - EIO ;
}
} else {
status = lv1_net_control ( bus_id ( card ) , dev_id ( card ) ,
GELIC_LV1_SET_WOL ,
GELIC_LV1_WOL_MAGIC_PACKET ,
0 , GELIC_LV1_WOL_MP_DISABLE ,
& v1 , & v2 ) ;
if ( status ) {
pr_info ( " %s: disabling WOL failed %d \n " , __func__ ,
status ) ;
status = - EIO ;
goto done ;
}
status = lv1_net_control ( bus_id ( card ) , dev_id ( card ) ,
GELIC_LV1_SET_WOL ,
GELIC_LV1_WOL_DELETE_MATCH_ADDR ,
0 , GELIC_LV1_WOL_MATCH_ALL ,
& v1 , & v2 ) ;
if ( ! status )
ps3_sys_manager_set_wol ( 0 ) ;
else {
pr_info ( " %s: removing WOL filter failed %d \n " ,
__func__ , status ) ;
status = - EIO ;
}
}
done :
return status ;
}
static struct ethtool_ops gelic_ether_ethtool_ops = {
. get_drvinfo = gelic_net_get_drvinfo ,
. get_settings = gelic_ether_get_settings ,
@ -1274,6 +1353,8 @@ static struct ethtool_ops gelic_ether_ethtool_ops = {
. set_tx_csum = ethtool_op_set_tx_csum ,
. get_rx_csum = gelic_net_get_rx_csum ,
. set_rx_csum = gelic_net_set_rx_csum ,
. get_wol = gelic_net_get_wol ,
. set_wol = gelic_net_set_wol ,
} ;
/**