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