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, ðaddr[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