From bedbef8ad3e75a304af6361af235302bcc61d06b Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 14 May 2024 06:39:01 +0000
Subject: [PATCH] 修改内核路径
---
kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c | 230 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 176 insertions(+), 54 deletions(-)
diff --git a/kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c b/kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 190c22c..dcde496 100644
--- a/kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -2,11 +2,11 @@
/* Copyright (C) 2018 Microchip Technology Inc. */
#include <linux/netdevice.h>
-#include "lan743x_main.h"
-#include "lan743x_ethtool.h"
#include <linux/net_tstamp.h>
#include <linux/pci.h>
#include <linux/phy.h>
+#include "lan743x_main.h"
+#include "lan743x_ethtool.h"
/* eeprom */
#define LAN743X_EEPROM_MAGIC (0x74A5)
@@ -14,60 +14,137 @@
#define EEPROM_INDICATOR_1 (0xA5)
#define EEPROM_INDICATOR_2 (0xAA)
#define EEPROM_MAC_OFFSET (0x01)
-#define MAX_EEPROM_SIZE 512
+#define MAX_EEPROM_SIZE (512)
+#define MAX_OTP_SIZE (1024)
#define OTP_INDICATOR_1 (0xF3)
#define OTP_INDICATOR_2 (0xF7)
+
+static int lan743x_otp_power_up(struct lan743x_adapter *adapter)
+{
+ u32 reg_value;
+
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
+
+ if (reg_value & OTP_PWR_DN_PWRDN_N_) {
+ /* clear it and wait to be cleared */
+ reg_value &= ~OTP_PWR_DN_PWRDN_N_;
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
+
+ usleep_range(100, 20000);
+ }
+
+ return 0;
+}
+
+static void lan743x_otp_power_down(struct lan743x_adapter *adapter)
+{
+ u32 reg_value;
+
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
+ if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
+ /* set power down bit */
+ reg_value |= OTP_PWR_DN_PWRDN_N_;
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
+ }
+}
+
+static void lan743x_otp_set_address(struct lan743x_adapter *adapter,
+ u32 address)
+{
+ lan743x_csr_write(adapter, OTP_ADDR_HIGH, (address >> 8) & 0x03);
+ lan743x_csr_write(adapter, OTP_ADDR_LOW, address & 0xFF);
+}
+
+static void lan743x_otp_read_go(struct lan743x_adapter *adapter)
+{
+ lan743x_csr_write(adapter, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
+ lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
+}
+
+static int lan743x_otp_wait_till_not_busy(struct lan743x_adapter *adapter)
+{
+ unsigned long timeout;
+ u32 reg_val;
+
+ timeout = jiffies + HZ;
+ do {
+ if (time_after(jiffies, timeout)) {
+ netif_warn(adapter, drv, adapter->netdev,
+ "Timeout on OTP_STATUS completion\n");
+ return -EIO;
+ }
+ udelay(1);
+ reg_val = lan743x_csr_read(adapter, OTP_STATUS);
+ } while (reg_val & OTP_STATUS_BUSY_);
+
+ return 0;
+}
+
+static int lan743x_otp_read(struct lan743x_adapter *adapter, u32 offset,
+ u32 length, u8 *data)
+{
+ int ret;
+ int i;
+
+ if (offset + length > MAX_OTP_SIZE)
+ return -EINVAL;
+
+ ret = lan743x_otp_power_up(adapter);
+ if (ret < 0)
+ return ret;
+
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < length; i++) {
+ lan743x_otp_set_address(adapter, offset + i);
+
+ lan743x_otp_read_go(adapter);
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
+ data[i] = lan743x_csr_read(adapter, OTP_READ_DATA);
+ }
+
+ lan743x_otp_power_down(adapter);
+
+ return 0;
+}
static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
u32 length, u8 *data)
{
- unsigned long timeout;
- u32 buf;
+ int ret;
int i;
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
+ if (offset + length > MAX_OTP_SIZE)
+ return -EINVAL;
- if (buf & OTP_PWR_DN_PWRDN_N_) {
- /* clear it and wait to be cleared */
- lan743x_csr_write(adapter, OTP_PWR_DN, 0);
+ ret = lan743x_otp_power_up(adapter);
+ if (ret < 0)
+ return ret;
- timeout = jiffies + HZ;
- do {
- udelay(1);
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
- if (time_after(jiffies, timeout)) {
- netif_warn(adapter, drv, adapter->netdev,
- "timeout on OTP_PWR_DN completion\n");
- return -EIO;
- }
- } while (buf & OTP_PWR_DN_PWRDN_N_);
- }
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
/* set to BYTE program mode */
lan743x_csr_write(adapter, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
for (i = 0; i < length; i++) {
- lan743x_csr_write(adapter, OTP_ADDR1,
- ((offset + i) >> 8) &
- OTP_ADDR1_15_11_MASK_);
- lan743x_csr_write(adapter, OTP_ADDR2,
- ((offset + i) &
- OTP_ADDR2_10_3_MASK_));
+ lan743x_otp_set_address(adapter, offset + i);
+
lan743x_csr_write(adapter, OTP_PRGM_DATA, data[i]);
lan743x_csr_write(adapter, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
- timeout = jiffies + HZ;
- do {
- udelay(1);
- buf = lan743x_csr_read(adapter, OTP_STATUS);
- if (time_after(jiffies, timeout)) {
- netif_warn(adapter, drv, adapter->netdev,
- "Timeout on OTP_STATUS completion\n");
- return -EIO;
- }
- } while (buf & OTP_STATUS_BUSY_);
+ ret = lan743x_otp_wait_till_not_busy(adapter);
+ if (ret < 0)
+ return ret;
}
+
+ lan743x_otp_power_down(adapter);
return 0;
}
@@ -120,6 +197,9 @@
u32 val;
int i;
+ if (offset + length > MAX_EEPROM_SIZE)
+ return -EINVAL;
+
retval = lan743x_eeprom_confirm_not_busy(adapter);
if (retval)
return retval;
@@ -147,6 +227,9 @@
int retval;
u32 val;
int i;
+
+ if (offset + length > MAX_EEPROM_SIZE)
+ return -EINVAL;
retval = lan743x_eeprom_confirm_not_busy(adapter);
if (retval)
@@ -207,6 +290,11 @@
static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev)
{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
+ return MAX_OTP_SIZE;
+
return MAX_EEPROM_SIZE;
}
@@ -214,8 +302,14 @@
struct ethtool_eeprom *ee, u8 *data)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
+ int ret = 0;
- return lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
+ ret = lan743x_otp_read(adapter, ee->offset, ee->len, data);
+ else
+ ret = lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
+
+ return ret;
}
static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
@@ -224,17 +318,18 @@
struct lan743x_adapter *adapter = netdev_priv(netdev);
int ret = -EINVAL;
- if (ee->magic == LAN743X_EEPROM_MAGIC)
- ret = lan743x_eeprom_write(adapter, ee->offset, ee->len,
- data);
- /* Beware! OTP is One Time Programming ONLY!
- * So do some strict condition check before messing up
- */
- else if ((ee->magic == LAN743X_OTP_MAGIC) &&
- (ee->offset == 0) &&
- (ee->len == MAX_EEPROM_SIZE) &&
- (data[0] == OTP_INDICATOR_1))
- ret = lan743x_otp_write(adapter, ee->offset, ee->len, data);
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
+ /* Beware! OTP is One Time Programming ONLY! */
+ if (ee->magic == LAN743X_OTP_MAGIC) {
+ ret = lan743x_otp_write(adapter, ee->offset,
+ ee->len, data);
+ }
+ } else {
+ if (ee->magic == LAN743X_EEPROM_MAGIC) {
+ ret = lan743x_eeprom_write(adapter, ee->offset,
+ ee->len, data);
+ }
+ }
return ret;
}
@@ -360,6 +455,10 @@
STAT_TX_COUNTER_ROLLOVER_STATUS
};
+static const char lan743x_priv_flags_strings[][ETH_GSTRING_LEN] = {
+ "OTP_ACCESS",
+};
+
static void lan743x_ethtool_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
@@ -374,6 +473,10 @@
sizeof(lan743x_set1_sw_cnt_strings)],
lan743x_set2_hw_cnt_strings,
sizeof(lan743x_set2_hw_cnt_strings));
+ break;
+ case ETH_SS_PRIV_FLAGS:
+ memcpy(data, lan743x_priv_flags_strings,
+ sizeof(lan743x_priv_flags_strings));
break;
}
}
@@ -399,6 +502,22 @@
}
}
+static u32 lan743x_ethtool_get_priv_flags(struct net_device *netdev)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ return adapter->flags;
+}
+
+static int lan743x_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
+{
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
+
+ adapter->flags = flags;
+
+ return 0;
+}
+
static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
@@ -411,6 +530,8 @@
ret += ARRAY_SIZE(lan743x_set2_hw_cnt_strings);
return ret;
}
+ case ETH_SS_PRIV_FLAGS:
+ return ARRAY_SIZE(lan743x_priv_flags_strings);
default:
return -EOPNOTSUPP;
}
@@ -427,7 +548,7 @@
case TCP_V4_FLOW:case UDP_V4_FLOW:
case TCP_V6_FLOW:case UDP_V6_FLOW:
rxnfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case IPV4_FLOW: case IPV6_FLOW:
rxnfc->data |= RXH_IP_SRC | RXH_IP_DST;
return 0;
@@ -659,9 +780,7 @@
wol->supported = 0;
wol->wolopts = 0;
-
- if (netdev->phydev)
- phy_ethtool_get_wol(netdev->phydev, wol);
+ phy_ethtool_get_wol(netdev->phydev, wol);
wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
@@ -690,8 +809,9 @@
device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
- return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol)
- : -ENETDOWN;
+ phy_ethtool_set_wol(netdev->phydev, wol);
+
+ return 0;
}
#endif /* CONFIG_PM */
@@ -706,6 +826,8 @@
.set_eeprom = lan743x_ethtool_set_eeprom,
.get_strings = lan743x_ethtool_get_strings,
.get_ethtool_stats = lan743x_ethtool_get_ethtool_stats,
+ .get_priv_flags = lan743x_ethtool_get_priv_flags,
+ .set_priv_flags = lan743x_ethtool_set_priv_flags,
.get_sset_count = lan743x_ethtool_get_sset_count,
.get_rxnfc = lan743x_ethtool_get_rxnfc,
.get_rxfh_key_size = lan743x_ethtool_get_rxfh_key_size,
--
Gitblit v1.6.2