From f63cd4c03ea42695d5f9b0e1798edd196923aae6 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 22 Mar 2024 06:08:33 +0000
Subject: [PATCH] pcie lan read mac form eeprom

---
 kernel/include/linux/pci.h                       |    3 
 kernel/include/linux/device/driver.h             |   14 +++
 kernel/drivers/net/ethernet/realtek/r8169_main.c |   46 +++++++++--
 kernel/drivers/misc/eeprom/at24.c                |  147 ++++++++++++++++++++++++++++++++++++
 4 files changed, 200 insertions(+), 10 deletions(-)

diff --git a/kernel/drivers/misc/eeprom/at24.c b/kernel/drivers/misc/eeprom/at24.c
index 305ffad..d02bf9c 100644
--- a/kernel/drivers/misc/eeprom/at24.c
+++ b/kernel/drivers/misc/eeprom/at24.c
@@ -120,6 +120,8 @@
 module_param_named(write_timeout, at24_write_timeout, uint, 0);
 MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
 
+struct at24_data *at24_private=NULL;
+
 struct at24_chip_data {
 	u32 byte_len;
 	u8 flags;
@@ -464,6 +466,147 @@
 	return 0;
 }
 
+
+
+static ssize_t at24_read_private(struct at24_data *at24,
+		char *buf, loff_t off, size_t count)
+{
+	ssize_t retval = 0;
+
+	if (unlikely(!count))
+		return count;
+
+	if (off + count > at24->byte_len)
+		return -EINVAL;
+	
+	/*
+	 * Read data from chip, protecting against concurrent updates
+	 * from this host, but not from other I2C masters.
+	 */
+	mutex_lock(&at24->lock);
+
+	while (count) {
+		ssize_t	status;
+
+		//status = at24_eeprom_read_i2c(at24, buf, off, count);
+		status = at24_regmap_read(at24, buf, off, count);
+		if (status <= 0) {
+			if (retval == 0)
+				retval = status;
+			break;
+		}
+		buf += status;
+		off += status;
+		count -= status;
+		retval += status;
+	}
+
+	mutex_unlock(&at24->lock);
+
+	return retval;
+}
+
+#if 0
+static unsigned char AscToHex(unsigned char aChar)
+{
+    if((aChar>=0x30)&&(aChar<=0x39))
+        aChar -= 0x30;
+    else if((aChar>=0x41)&&(aChar<=0x46))
+        aChar -= 0x37;
+    else if((aChar>=0x61)&&(aChar<=0x66))
+        aChar -= 0x57;
+    else aChar = 0xff;
+
+    return aChar; 
+}
+#endif
+
+#if 0
+ssize_t at24_mac_read(unsigned char* addr)
+{
+	char buf[20];
+	char buf_tmp[12];
+	int i;
+	ssize_t ret;	
+	if (at24_private == NULL)
+	{
+		printk("ben %s: at24_private==null error\n", __func__);
+		return 0;
+	}
+	memset(buf, 0x00, 20);
+	memset(buf_tmp, 0x00, 12);
+	ret = at24_read(at24_private, 0, buf, 12);
+	if (ret > 0)
+	{	
+		for(i=0; i<12; i++)
+		{
+			buf_tmp[i] = AscToHex(buf[i]);
+		}
+		addr[0] = (buf_tmp[0] << 4) | buf_tmp[1];
+		addr[1] = (buf_tmp[2] << 4) | buf_tmp[3];
+		addr[2] = (buf_tmp[4] << 4) | buf_tmp[5];
+		addr[3] = (buf_tmp[6] << 4) | buf_tmp[7];
+		addr[4] = (buf_tmp[8] << 4) | buf_tmp[9];
+		addr[5] = (buf_tmp[10] << 4) | buf_tmp[11]; 	
+	}
+	return ret;
+}
+#endif
+
+ssize_t at24_mac_read(unsigned char* addr)
+{
+	char buf[20];
+	char buf_tmp[12];
+	ssize_t ret;	
+	if (at24_private == NULL)
+	{
+		printk("ben: at24_mac_read at24_private==null error");
+		return 0;
+	}
+	memset(buf, 0x00, 20);
+	memset(buf_tmp, 0x00, 12);
+	ret = at24_read_private(at24_private, buf, 0, 6);
+	if (ret > 0)
+	{	
+		addr[0] = buf[0];
+		addr[1] = buf[1];
+		addr[2] = buf[2];
+		addr[3] = buf[3];
+		addr[4] = buf[4];
+		addr[5] = buf[5];	
+	}
+	printk("at24_mac_read ...............\n");
+	return ret;
+}
+EXPORT_SYMBOL(at24_mac_read);
+
+ssize_t at24_mac1_read(unsigned char* mac)
+{
+	char buf[20];
+	char buf_tmp[12];
+	ssize_t ret;
+	if (at24_private == NULL)
+	{
+		printk("zcl: at24_mac_read at24_private==null error");
+		return 0;
+	}
+	memset(buf, 0x00, 20);
+	memset(buf_tmp, 0x00, 12);
+	ret = at24_read_private(at24_private, buf, 0x10, 6);
+	if (ret > 0)
+	{
+		*mac = buf[0];
+		*(mac + 1) = buf[1];
+		*(mac + 2) = buf[2];
+		*(mac + 3) = buf[3];
+		*(mac + 4) = buf[4];
+		*(mac + 5) = buf[5];
+	}
+	printk("at24_mac1_read ...............\n");
+	return ret;
+}
+EXPORT_SYMBOL(at24_mac1_read);
+
 static int at24_write(void *priv, unsigned int off, void *val, size_t count)
 {
 	struct at24_data *at24;
@@ -684,6 +827,7 @@
 	if (!at24)
 		return -ENOMEM;
 
+	at24_private = at24;
 	mutex_init(&at24->lock);
 	at24->byte_len = byte_len;
 	at24->page_size = page_size;
@@ -845,7 +989,8 @@
 	at24_io_limit = rounddown_pow_of_two(at24_io_limit);
 	return i2c_add_driver(&at24_driver);
 }
-module_init(at24_init);
+//module_init(at24_init);
+postcore_initcall_sync(at24_init);
 
 static void __exit at24_exit(void)
 {
diff --git a/kernel/drivers/net/ethernet/realtek/r8169_main.c b/kernel/drivers/net/ethernet/realtek/r8169_main.c
index 28850f7..8c2c32a 100644
--- a/kernel/drivers/net/ethernet/realtek/r8169_main.c
+++ b/kernel/drivers/net/ethernet/realtek/r8169_main.c
@@ -158,7 +158,6 @@
 	{ PCI_VDEVICE(REALTEK,	0x8129) },
 	{ PCI_VDEVICE(REALTEK,	0x8136), RTL_CFG_NO_GBIT },
 	{ PCI_VDEVICE(REALTEK,	0x8161) },
-	{ PCI_VDEVICE(REALTEK,	0x8162) },
 	{ PCI_VDEVICE(REALTEK,	0x8167) },
 	{ PCI_VDEVICE(REALTEK,	0x8168) },
 	{ PCI_VDEVICE(NCUBE,	0x8168) },
@@ -4184,6 +4183,7 @@
 static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 				struct sk_buff *skb, u32 *opts)
 {
+	u32 transport_offset = (u32)skb_transport_offset(skb);
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	u32 mss = shinfo->gso_size;
 
@@ -4200,7 +4200,7 @@
 			WARN_ON_ONCE(1);
 		}
 
-		opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT;
+		opts[0] |= transport_offset << GTTCPHO_SHIFT;
 		opts[1] |= mss << TD1_MSS_SHIFT;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
@@ -4228,7 +4228,7 @@
 		else
 			WARN_ON_ONCE(1);
 
-		opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT;
+		opts[1] |= transport_offset << TCPHO_SHIFT;
 	} else {
 		unsigned int padto = rtl_quirk_packet_padto(tp, skb);
 
@@ -4401,13 +4401,14 @@
 						struct net_device *dev,
 						netdev_features_t features)
 {
+	int transport_offset = skb_transport_offset(skb);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
 	if (skb_is_gso(skb)) {
 		if (tp->mac_version == RTL_GIGA_MAC_VER_34)
 			features = rtl8168evl_fix_tso(skb, features);
 
-		if (skb_transport_offset(skb) > GTTCPHO_MAX &&
+		if (transport_offset > GTTCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_ALL_TSO;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -4418,7 +4419,7 @@
 		if (rtl_quirk_packet_padto(tp, skb))
 			features &= ~NETIF_F_CSUM_MASK;
 
-		if (skb_transport_offset(skb) > TCPHO_MAX &&
+		if (transport_offset > TCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_CSUM_MASK;
 	}
@@ -5291,13 +5292,14 @@
 
 	return rc;
 }
-
+extern ssize_t at24_mac_read(unsigned char* mac);
 static void rtl_init_mac_address(struct rtl8169_private *tp)
 {
 	struct net_device *dev = tp->dev;
 	u8 *mac_addr = dev->dev_addr;
-	int rc;
-
+	int rc,i;
+	unsigned char mac[6];
+/*
 	rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr);
 	if (!rc)
 		goto done;
@@ -5309,6 +5311,29 @@
 	rtl_read_mac_from_reg(tp, mac_addr, MAC0);
 	if (is_valid_ether_addr(mac_addr))
 		goto done;
+*/
+	memset(mac, 0x00, 6);
+	at24_mac_read(mac);
+	
+	if ((mac[0] == 0x68) && (mac[1] == 0xed))
+	{
+		printk("troy : rtl811h mac read from eeprom success!! \n");
+		for (i = 0; i < ETH_ALEN; i++)
+			dev->dev_addr[i] = mac[i];
+	}
+	else
+	{
+		printk("troy : rtl811h mac read from eeprom error!! \n");
+		dev->dev_addr[0] = 0x66;
+                dev->dev_addr[1] = 0xED;
+                dev->dev_addr[2] = 0xB5;
+                dev->dev_addr[3] = 0x64;
+                dev->dev_addr[4] = 0x72;
+                dev->dev_addr[5] = 0x2C;
+	}
+	if (is_valid_ether_addr(mac_addr))
+		goto done;
+
 
 	eth_hw_addr_random(dev);
 	dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n");
@@ -5316,6 +5341,7 @@
 	rtl_rar_set(tp, mac_addr);
 }
 
+extern ssize_t at24_mac1_read(unsigned char* mac);
 static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct rtl8169_private *tp;
@@ -5323,6 +5349,7 @@
 	enum mac_version chipset;
 	struct net_device *dev;
 	u16 xid;
+	unsigned char mac[6];
 
 	dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
 	if (!dev)
@@ -5518,4 +5545,5 @@
 #endif
 };
 
-module_pci_driver(rtl8169_pci_driver);
+//module_pci_driver(rtl8169_pci_driver);
+module_pci_driver2(rtl8169_pci_driver); //late_initcall();
diff --git a/kernel/include/linux/device/driver.h b/kernel/include/linux/device/driver.h
index d5ad474..c52d23d 100644
--- a/kernel/include/linux/device/driver.h
+++ b/kernel/include/linux/device/driver.h
@@ -272,6 +272,20 @@
 } \
 module_exit(__driver##_exit);
 
+
+	
+#define module_driver2(__driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+        return __register(&(__driver) , ##__VA_ARGS__); \
+} \
+late_initcall(__driver##_init); \
+static void __exit __driver##_exit(void) \
+{ \
+        __unregister(&(__driver) , ##__VA_ARGS__); \
+} \
+module_exit(__driver##_exit);
+
 /**
  * builtin_driver() - Helper macro for drivers that don't do anything
  * special in init and have no exit. This eliminates some boilerplate.
diff --git a/kernel/include/linux/pci.h b/kernel/include/linux/pci.h
index 0bd9c16..314f6d0 100644
--- a/kernel/include/linux/pci.h
+++ b/kernel/include/linux/pci.h
@@ -1419,6 +1419,9 @@
 #define module_pci_driver(__pci_driver) \
 	module_driver(__pci_driver, pci_register_driver, pci_unregister_driver)
 
+#define module_pci_driver2(__pci_driver) \
+	module_driver2(__pci_driver, pci_register_driver, pci_unregister_driver)
+
 /**
  * builtin_pci_driver() - Helper macro for registering a PCI driver
  * @__pci_driver: pci_driver struct

--
Gitblit v1.6.2