mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
Add LAN78XX OTP_ACCESS flag support
With this flag we can now use ethtool to access OTP: ethtool --set-priv-flags eth0 OTP_ACCESS on ethtool -e eth0 # this will read OTP if OTP_ACCESS is on, else EEPROM When writing to OTP we need to set OTP_ACCESS on and write with the correct magic 0x7873 for OTP
This commit is contained in:
parent
c2ee9f594d
commit
f33fb4f77c
@ -85,6 +85,7 @@
|
|||||||
#define EEPROM_INDICATOR (0xA5)
|
#define EEPROM_INDICATOR (0xA5)
|
||||||
#define EEPROM_MAC_OFFSET (0x01)
|
#define EEPROM_MAC_OFFSET (0x01)
|
||||||
#define MAX_EEPROM_SIZE 512
|
#define MAX_EEPROM_SIZE 512
|
||||||
|
#define MAX_OTP_SIZE 512
|
||||||
#define OTP_INDICATOR_1 (0xF3)
|
#define OTP_INDICATOR_1 (0xF3)
|
||||||
#define OTP_INDICATOR_2 (0xF7)
|
#define OTP_INDICATOR_2 (0xF7)
|
||||||
|
|
||||||
@ -172,6 +173,7 @@
|
|||||||
#define INT_EP_GPIO_2 (2)
|
#define INT_EP_GPIO_2 (2)
|
||||||
#define INT_EP_GPIO_1 (1)
|
#define INT_EP_GPIO_1 (1)
|
||||||
#define INT_EP_GPIO_0 (0)
|
#define INT_EP_GPIO_0 (0)
|
||||||
|
#define LAN78XX_NET_FLAG_OTP BIT(0)
|
||||||
|
|
||||||
static const char lan78xx_gstrings[][ETH_GSTRING_LEN] = {
|
static const char lan78xx_gstrings[][ETH_GSTRING_LEN] = {
|
||||||
"RX FCS Errors",
|
"RX FCS Errors",
|
||||||
@ -446,6 +448,7 @@ struct lan78xx_net {
|
|||||||
unsigned int burst_cap;
|
unsigned int burst_cap;
|
||||||
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u32 priv_flags;
|
||||||
|
|
||||||
wait_queue_head_t *wait;
|
wait_queue_head_t *wait;
|
||||||
unsigned char suspend_count;
|
unsigned char suspend_count;
|
||||||
@ -1542,6 +1545,10 @@ static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb)
|
|||||||
|
|
||||||
static int lan78xx_ethtool_get_eeprom_len(struct net_device *netdev)
|
static int lan78xx_ethtool_get_eeprom_len(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
|
struct lan78xx_net *dev = netdev_priv(netdev);
|
||||||
|
|
||||||
|
if (dev->priv_flags & LAN78XX_NET_FLAG_OTP)
|
||||||
|
return MAX_OTP_SIZE;
|
||||||
return MAX_EEPROM_SIZE;
|
return MAX_EEPROM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,9 +1562,10 @@ static int lan78xx_ethtool_get_eeprom(struct net_device *netdev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ee->magic = LAN78XX_EEPROM_MAGIC;
|
if (dev->priv_flags & LAN78XX_NET_FLAG_OTP)
|
||||||
|
ret = lan78xx_read_raw_otp(dev, ee->offset, ee->len, data);
|
||||||
ret = lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
|
else
|
||||||
|
ret = lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data);
|
||||||
|
|
||||||
usb_autopm_put_interface(dev->intf);
|
usb_autopm_put_interface(dev->intf);
|
||||||
|
|
||||||
@ -1577,30 +1585,39 @@ static int lan78xx_ethtool_set_eeprom(struct net_device *netdev,
|
|||||||
/* Invalid EEPROM_INDICATOR at offset zero will result in a failure
|
/* Invalid EEPROM_INDICATOR at offset zero will result in a failure
|
||||||
* to load data from EEPROM
|
* to load data from EEPROM
|
||||||
*/
|
*/
|
||||||
if (ee->magic == LAN78XX_EEPROM_MAGIC)
|
if (dev->priv_flags & LAN78XX_NET_FLAG_OTP) {
|
||||||
ret = lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data);
|
/* Beware! OTP is One Time Programming ONLY! */
|
||||||
else if ((ee->magic == LAN78XX_OTP_MAGIC) &&
|
if (ee->magic == LAN78XX_OTP_MAGIC)
|
||||||
(ee->offset == 0) &&
|
ret = lan78xx_write_raw_otp(dev, ee->offset, ee->len, data);
|
||||||
(ee->len == 512) &&
|
} else {
|
||||||
(data[0] == OTP_INDICATOR_1))
|
if (ee->magic == LAN78XX_EEPROM_MAGIC)
|
||||||
ret = lan78xx_write_raw_otp(dev, ee->offset, ee->len, data);
|
ret = lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data);
|
||||||
|
}
|
||||||
|
|
||||||
usb_autopm_put_interface(dev->intf);
|
usb_autopm_put_interface(dev->intf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char lan78xx_priv_flags_strings[][ETH_GSTRING_LEN] = {
|
||||||
|
"OTP_ACCESS",
|
||||||
|
};
|
||||||
|
|
||||||
static void lan78xx_get_strings(struct net_device *netdev, u32 stringset,
|
static void lan78xx_get_strings(struct net_device *netdev, u32 stringset,
|
||||||
u8 *data)
|
u8 *data)
|
||||||
{
|
{
|
||||||
if (stringset == ETH_SS_STATS)
|
if (stringset == ETH_SS_STATS)
|
||||||
memcpy(data, lan78xx_gstrings, sizeof(lan78xx_gstrings));
|
memcpy(data, lan78xx_gstrings, sizeof(lan78xx_gstrings));
|
||||||
|
else if (stringset == ETH_SS_PRIV_FLAGS)
|
||||||
|
memcpy(data, lan78xx_priv_flags_strings, sizeof(lan78xx_priv_flags_strings));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lan78xx_get_sset_count(struct net_device *netdev, int sset)
|
static int lan78xx_get_sset_count(struct net_device *netdev, int sset)
|
||||||
{
|
{
|
||||||
if (sset == ETH_SS_STATS)
|
if (sset == ETH_SS_STATS)
|
||||||
return ARRAY_SIZE(lan78xx_gstrings);
|
return ARRAY_SIZE(lan78xx_gstrings);
|
||||||
|
else if (sset == ETH_SS_PRIV_FLAGS)
|
||||||
|
return ARRAY_SIZE(lan78xx_priv_flags_strings);
|
||||||
else
|
else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
@ -1617,6 +1634,22 @@ static void lan78xx_get_stats(struct net_device *netdev,
|
|||||||
mutex_unlock(&dev->stats.access_lock);
|
mutex_unlock(&dev->stats.access_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 lan78xx_ethtool_get_priv_flags(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct lan78xx_net *dev = netdev_priv(netdev);
|
||||||
|
|
||||||
|
return dev->priv_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lan78xx_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
||||||
|
{
|
||||||
|
struct lan78xx_net *dev = netdev_priv(netdev);
|
||||||
|
|
||||||
|
dev->priv_flags = flags;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void lan78xx_get_wol(struct net_device *netdev,
|
static void lan78xx_get_wol(struct net_device *netdev,
|
||||||
struct ethtool_wolinfo *wol)
|
struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
@ -1905,6 +1938,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = {
|
|||||||
.get_eeprom = lan78xx_ethtool_get_eeprom,
|
.get_eeprom = lan78xx_ethtool_get_eeprom,
|
||||||
.set_eeprom = lan78xx_ethtool_set_eeprom,
|
.set_eeprom = lan78xx_ethtool_set_eeprom,
|
||||||
.get_ethtool_stats = lan78xx_get_stats,
|
.get_ethtool_stats = lan78xx_get_stats,
|
||||||
|
.get_priv_flags = lan78xx_ethtool_get_priv_flags,
|
||||||
|
.set_priv_flags = lan78xx_ethtool_set_priv_flags,
|
||||||
.get_sset_count = lan78xx_get_sset_count,
|
.get_sset_count = lan78xx_get_sset_count,
|
||||||
.get_strings = lan78xx_get_strings,
|
.get_strings = lan78xx_get_strings,
|
||||||
.get_wol = lan78xx_get_wol,
|
.get_wol = lan78xx_get_wol,
|
||||||
|
Loading…
Reference in New Issue
Block a user