@ -516,6 +516,87 @@ int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
return 0 ;
}
int asix_set_eeprom ( struct net_device * net , struct ethtool_eeprom * eeprom ,
u8 * data )
{
struct usbnet * dev = netdev_priv ( net ) ;
u16 * eeprom_buff ;
int first_word , last_word ;
int i ;
int ret ;
netdev_dbg ( net , " write EEPROM len %d, offset %d, magic 0x%x \n " ,
eeprom - > len , eeprom - > offset , eeprom - > magic ) ;
if ( eeprom - > len = = 0 )
return - EINVAL ;
if ( eeprom - > magic ! = AX_EEPROM_MAGIC )
return - EINVAL ;
first_word = eeprom - > offset > > 1 ;
last_word = ( eeprom - > offset + eeprom - > len - 1 ) > > 1 ;
eeprom_buff = kmalloc ( sizeof ( u16 ) * ( last_word - first_word + 1 ) ,
GFP_KERNEL ) ;
if ( ! eeprom_buff )
return - ENOMEM ;
/* align data to 16 bit boundaries, read the missing data from
the EEPROM */
if ( eeprom - > offset & 1 ) {
ret = asix_read_cmd ( dev , AX_CMD_READ_EEPROM , first_word , 0 , 2 ,
& ( eeprom_buff [ 0 ] ) ) ;
if ( ret < 0 ) {
netdev_err ( net , " Failed to read EEPROM at offset 0x%02x. \n " , first_word ) ;
goto free ;
}
}
if ( ( eeprom - > offset + eeprom - > len ) & 1 ) {
ret = asix_read_cmd ( dev , AX_CMD_READ_EEPROM , last_word , 0 , 2 ,
& ( eeprom_buff [ last_word - first_word ] ) ) ;
if ( ret < 0 ) {
netdev_err ( net , " Failed to read EEPROM at offset 0x%02x. \n " , last_word ) ;
goto free ;
}
}
memcpy ( ( u8 * ) eeprom_buff + ( eeprom - > offset & 1 ) , data , eeprom - > len ) ;
/* write data to EEPROM */
ret = asix_write_cmd ( dev , AX_CMD_WRITE_ENABLE , 0x0000 , 0 , 0 , NULL ) ;
if ( ret < 0 ) {
netdev_err ( net , " Failed to enable EEPROM write \n " ) ;
goto free ;
}
msleep ( 20 ) ;
for ( i = first_word ; i < = last_word ; i + + ) {
netdev_dbg ( net , " write to EEPROM at offset 0x%02x, data 0x%04x \n " ,
i , eeprom_buff [ i - first_word ] ) ;
ret = asix_write_cmd ( dev , AX_CMD_WRITE_EEPROM , i ,
eeprom_buff [ i - first_word ] , 0 , NULL ) ;
if ( ret < 0 ) {
netdev_err ( net , " Failed to write EEPROM at offset 0x%02x. \n " ,
i ) ;
goto free ;
}
msleep ( 20 ) ;
}
ret = asix_write_cmd ( dev , AX_CMD_WRITE_DISABLE , 0x0000 , 0 , 0 , NULL ) ;
if ( ret < 0 ) {
netdev_err ( net , " Failed to disable EEPROM write \n " ) ;
goto free ;
}
ret = 0 ;
free :
kfree ( eeprom_buff ) ;
return ret ;
}
void asix_get_drvinfo ( struct net_device * net , struct ethtool_drvinfo * info )
{
/* Inherit standard device info */