This commit is contained in:
Cutyno 2024-10-30 23:29:11 +01:00 committed by GitHub
commit f4b4279776
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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,