From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom

---
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c    |   27 ++++++
 kernel/include/linux/platform_device.h                   |    5 +
 kernel/include/linux/device/driver.h                     |   12 +++
 kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   22 +++++
 kernel/drivers/misc/eeprom/at24.c                        |  147 ++++++++++++++++++++++++++++++++++++
 5 files changed, 207 insertions(+), 6 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/stmicro/stmmac/dwmac-rk.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index cf9c46e..8e1b354 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -2711,13 +2711,17 @@
 }
 EXPORT_SYMBOL(dwmac_rk_get_phy_interface);
 
+static unsigned char macaddr[6];
+extern ssize_t at24_mac_read(unsigned char* addr);
 static void rk_get_eth_addr(void *priv, unsigned char *addr)
 {
 	struct rk_priv_data *bsp_priv = priv;
 	struct device *dev = &bsp_priv->pdev->dev;
-	unsigned char ethaddr[ETH_ALEN * MAX_ETH] = {0};
-	int ret, id = bsp_priv->bus_id;
+	//unsigned char ethaddr[ETH_ALEN * MAX_ETH] = {0};
+	//int ret, id = bsp_priv->bus_id;
+	int i;
 
+#if 0
 	if (is_valid_ether_addr(addr))
 		goto out;
 
@@ -2747,7 +2751,23 @@
 	} else {
 		memcpy(addr, &ethaddr[id * ETH_ALEN], ETH_ALEN);
 	}
+#endif
+	
+	#if 1
+        if (at24_mac_read(macaddr) > 0) {
+                printk("ben %s: at24_mac_read Success!! \n", __func__);
+                memcpy(addr, macaddr, 6);
 
+                printk("Read the Ethernet MAC address from :");
+                for (i = 0; i < 5; i++)
+                        printk("%2.2x:", addr[i]);
+
+                printk("%2.2x\n", addr[i]);
+        } else {
+                printk("ben %s: at24_mac_read Failed!! \n", __func__);
+                goto out;
+        }
+        #endif
 out:
 	dev_err(dev, "%s: mac address: %pM\n", __func__, addr);
 }
@@ -2920,7 +2940,8 @@
 		.of_match_table = rk_gmac_dwmac_match,
 	},
 };
-module_platform_driver(rk_gmac_dwmac_driver);
+//module_platform_driver(rk_gmac_dwmac_driver);
+module_platform_driver1(rk_gmac_dwmac_driver);
 
 MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
 MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e14a682..f10330b 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1101,6 +1101,23 @@
 	}
 }
 
+static void rtl8211F_led_control(struct phy_device *phydev)
+{
+	printk("ben debug:rtl8211F_led_control...1 \n");
+
+       	if(!phydev) return;
+       	if(phydev->phy_id!=0x001cc916) return; /* only for 8211E*/
+
+       	/*switch to extension page44*/
+	phy_write(phydev, 31, 0x0d04);
+//add hc 1000M --> orange   
+//	 100M  --> green
+	phy_write(phydev, 16, 0x6D02);  
+//add hc 1000M&100M  --> green
+//     	phy_write(phydev, 16, 0x6C0A); 
+	printk("ben debug:rtl8211F_led_control...2 \n");
+}
+
 /**
  * stmmac_init_phy - PHY initialization
  * @dev: net device structure
@@ -1136,6 +1153,7 @@
 			return -ENODEV;
 		}
 
+		rtl8211F_led_control(phydev);
 		ret = phylink_connect_phy(priv->phylink, phydev);
 	}
 
@@ -1145,7 +1163,6 @@
 		phylink_ethtool_get_wol(priv->phylink, &wol);
 		device_set_wakeup_capable(priv->device, !!wol.supported);
 	}
-
 	return ret;
 }
 
@@ -2345,7 +2362,8 @@
  */
 static void stmmac_check_ether_addr(struct stmmac_priv *priv)
 {
-	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
+//	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
+	if (1) {
 		stmmac_get_umac_addr(priv, priv->hw, priv->dev->dev_addr, 0);
 		if (likely(priv->plat->get_eth_addr))
 			priv->plat->get_eth_addr(priv->plat->bsp_priv,
diff --git a/kernel/include/linux/device/driver.h b/kernel/include/linux/device/driver.h
index d5ad474..e5185cc 100644
--- a/kernel/include/linux/device/driver.h
+++ b/kernel/include/linux/device/driver.h
@@ -272,6 +272,18 @@
 } \
 module_exit(__driver##_exit);
 
+#define module_driver1(__driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+        return __register(&(__driver) , ##__VA_ARGS__); \
+} \
+arch_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/platform_device.h b/kernel/include/linux/platform_device.h
index 72b8a95..637c774 100644
--- a/kernel/include/linux/platform_device.h
+++ b/kernel/include/linux/platform_device.h
@@ -256,6 +256,11 @@
 	module_driver(__platform_driver, platform_driver_register, \
 			platform_driver_unregister)
 
+	
+#define module_platform_driver1(__platform_driver) \
+       module_driver1(__platform_driver, platform_driver_register, \
+                       platform_driver_unregister)
+
 /* builtin_platform_driver() - Helper macro for builtin drivers that
  * don't do anything special in driver init.  This eliminates some
  * boilerplate.  Each driver may only use this macro once, and

--
Gitblit v1.6.2