This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] DP83TC812EVM-MC:DP83TC812R-Q1

Guru**** 1144270 points
Other Parts Discussed in Thread: DP83TC812R-Q1
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1280402/dp83tc812evm-mc-dp83tc812r-q1

器件型号:DP83TC812EVM-MC
主题中讨论的其他器件:DP83TC812R-Q1

您好!

我们使用 DP83TC812R-Q1芯片开发具有100Base-T1接口的电路板。
我们已使用载板检查此情况、如以下连接。

我们已经隔离了 DP83867ERGZR 芯片连接。

 检测到链路。 通过 MDIO、MDC 线路通信正常。  
但我们无法执行 Ping 操作。
它显示*网络无法访问*
我已在下面附上了此问题的日志。

驱动程序已加载
nVidia@Tegra-ubuntu:~$ sudo dmesg | grep -i eth
[sudo] NVIDIA 的密码:
[ 0.000000] psci:从 DT 探测管道方法。
[4.223949] hns3: Hip08系列的 HiSilicon 以太网网络驱动程序-版本
[4.248077] igb:英特尔Registered千兆以太网网络驱动程序
[4.296360] usbcore:已注册的新接口驱动程序 CDC_ether
[7.424211] OTEE:探测导管方法。
[12.965592] nvethernet 2310000.以太网:添加到 iommu 组51
[12.971985] nvethernet 2310000.Ethernet: failed to read skip Mac reset flag,default 0
[12.980167] nvethernet 2310000.以太网:无法读取 MDIO 地址
[12.986718] nvethernet 2310000.ethernet:无法读取 NVIDA、PAUSE_FRAMES,因此将默认支持设置为 DISABLE
[12.997548] nvethernet 2310000.ethernet: setting to default DMA bit mask
[ 13.004464] nvethernet 2310000.以太网:缺少 NVIDIA,PAD_auto_cal_pu_offset,设置默认值0
[ 13.013583] nvethernet 2310000.ethernet:missing nvidia, pad_auto_cal_pd_offset, setting default 0
[ 13.039802] nvethernet 2310000.以太网:以太网 MAC 地址:48:b0:2d:94:41:3d
[ 13.047748] nvethernet 2310000.以太网:DT 中的 MACsec param 缺失或禁用
[ 13.055538] nvethernet 2310000.以太网:DT 中不支持/未启用 MACsec
[ 13.065800] nvethernet 2310000.以太网: eth0 (HW ver: 53)创建了8个 DMA 通道
[ 18.883875] TI DP83TC812CS2.0 2310000.以太网:00:~~~~~~~~~~~ 已加载~~~~~~~~~~~
[ 18.884279] MDIO_BUS 2310000.以太网:~~~~~~~~~~ 在地址0处打印 phy
[ 19.100012] TI DP83TC812CS2.0 2310000.以太网:00:~~~~~~~~~~~ 已加载~~~~~~~~~~~
[63.126826] IPv6:ADDRCONF (NETDEV_CHANGE):ETH0:链路就绪
[63.127398]以太网2310000.以太网 eth0:链路已接通- 100Mbps/全-流控已关闭


驱动器自举寄存器
NVIDIA@Tegra-ubuntu:~$ sudo dmesg | grep -i dp83
[ 18.670154] dp83812_read_strap 配置:strap 配置为0x4280
[ 18.883875] TI DP83TC812CS2.0 2310000.以太网:00:~~~~~~~~~~~ 已加载~~~~~~~~~~~
[ 18.884494] dp83812_read_brands:strap 配置为0x4280
[ 19.100012] TI DP83TC812CS2.0 2310000.以太网:00:~~~~~~~~~~~ 已加载~~~~~~~~~~~

未分配 IP
NVidia@Tegra-ubuntu:~$ ifconfig
ETH0:flags=4163 MTU 1500
inet6 fe80::ae9f:68c9:9e64:82d prefixlen 64 scopeid 0x20
乙醚48:b0:2D:94:41:3D txqueuelen 1000 (以太网)
RX 数据包0字节0 (0.0B)
RX 错误0丢弃0溢出0帧0
TX 数据包73字节12523 (12.5KB)
TX 错误0丢弃0溢出0载波0冲突0

LO:flags=73 MTU 65536
iNet 127.0.0.1网络掩码255.0.0.0
inet6 :: 1 prefixlen 128 scopeid 0x10
循环 txqueuelen 1000 (本地回送)
RX 数据包1110字节71114 (71.1 KB)
RX 错误0丢弃0溢出0帧0
TX 数据包1110字节71114 (71.1 KB)
TX 错误0丢弃0溢出0载波0冲突0

错误消息
NVIDIA@Tegra-ubuntu:~$[ 264.950727] nvethernet 2310000.Ethernet: Failed to report error:Reporter ID:0x0、Error code:0x1001、return:-19

已使用静态和动态 IP 配置尝试 Ping。
NVIDIA@ó n Tegra-ubuntu:~$ ping 8.8.8.8
Ping:连接:无法访问网络


nVidia@Tegra-ubuntu:~$ sudo ethtool eth0
[sudo] NVIDIA 的密码:
ETH0的设置:
支持的端口:[ TP MII ]
支持的链接模式:未报告
支持的暂停帧使用:对称仅接收
支持自动协商:否
支持的 FEC 模式:未报告
通告的链路模式:未报告
广播的暂停帧使用:否
广播的自动协商:否
广播的 FEC 模式:未报告
速度:100Mb/s
双工:全双工
端口:双绞线
PHYAD:0
收发器:内部
自动协商:关闭
MDI-X:未知
支持唤醒:D
唤醒:D
当前报文级别:0x00000000 (0)

检测到链路:是

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Santhoshwaran:

    我注意到驱动程序无法读取 MDIO 地址。 您能否改为尝试附加的驱动程序文件?

    e2e.ti.com/.../dp83867.zip

    此致、

    梅利萨

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Melissa:

    实际上我们 加载了驱动程序、MDIO 地址为0。

    DP83TC812_CS2_0_PHY_ID  0x2000a271 是 PHY ID 读取。

    // SPDX-License-Identifier: GPL-2.0
    /*
     * Driver for the Texas Instruments DP83TC812 PHY
     *
     * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
     *
     */
    
    #include <linux/ethtool.h>
    #include <linux/etherdevice.h>
    #include <linux/kernel.h>
    #include <linux/mii.h>
    #include <linux/module.h>
    #include <linux/of.h>
    #include <linux/phy.h>
    #include <linux/netdevice.h>
    
    #define DP83TC812_CS1_0_PHY_ID  0x2000a270
    #define DP83TC812_CS2_0_PHY_ID  0x2000a271
    #define DP83TC813_CS2_0_PHY_ID  0x2000a211
    #define DP83TC814_CS2_0_PHY_ID  0x2000a261
    
    #define DP83812_DEVADDR         0x1f
    #define DP83812_DEVADDR_MMD1    0x1
    
    #define DP83812_STRAP           0x45d
    #define MII_DP83812_SGMII_CTRL  0x608
    #define MII_DP83812_RGMII_CTRL  0x600
    #define MII_DP83812_INT_STAT1   0x12
    #define MII_DP83812_INT_STAT2   0x13
    #define MII_DP83812_INT_STAT3   0x18
    #define MII_DP83812_RESET_CTRL  0x1f
    
    #define DP83812_HW_RESET        BIT(15)
    #define DP83812_SW_RESET        BIT(14)
    
    /* INT_STAT1 bits */
    #define DP83812_RX_ERR_CNT_HALF_FULL_INT_EN     BIT(0)
    #define DP83812_TX_ERR_CNT_HALF_FULL_INT_EN     BIT(1)
    #define DP83812_MS_TRAIN_DONE_INT_EN            BIT(2)
    #define DP83812_ESD_EVENT_INT_EN                BIT(3)
    #define DP83812_LINK_STAT_INT_EN                BIT(5)
    #define DP83812_ENERGY_DET_INT_EN               BIT(6)
    #define DP83812_LINK_QUAL_INT_EN                BIT(7)
    
    /* INT_STAT2 bits */
    #define DP83812_JABBER_INT_EN           BIT(0)
    #define DP83812_POL_INT_EN              BIT(1)
    #define DP83812_SLEEP_MODE_INT_EN       BIT(2)
    #define DP83812_OVERTEMP_INT_EN         BIT(3)
    #define DP83812_FIFO_INT_EN             BIT(4)
    #define DP83812_PAGE_RXD_INT_EN         BIT(5)
    #define DP83812_OVERVOLTAGE_INT_EN      BIT(6)
    #define DP83812_UNDERVOLTAGE_INT_EN     BIT(7)
    
    /* INT_STAT3 bits */
    #define DP83812_LPS_INT_EN              BIT(0)
    #define DP83812_WUP_INT_EN              BIT(1)
    #define DP83812_WAKE_REQ_INT_EN         BIT(2)
    #define DP83811_NO_FRAME_INT_EN         BIT(3)
    #define DP83811_POR_DONE_INT_EN         BIT(4)
    #define DP83812_SLEEP_FAIL_INT_EN       BIT(5)
    
    /* RGMII_CTRL bits */
    #define DP83812_RGMII_EN                BIT(3)
    
    /* SGMII CTRL bits */
    #define DP83812_SGMII_AUTO_NEG_EN       BIT(0)
    #define DP83812_SGMII_EN                BIT(9)
    
    /* Strap bits */
    #define DP83812_MASTER_MODE     BIT(9)
    #define DP83812_RGMII_IS_EN     BIT(7)
    
    enum dp83812_chip_type {
            DP83812_CS1 = 0,
            DP83812_CS2,
            DP83813_CS2,
            DP83814_CS2,
    };
    
    struct dp83812_init_reg {
            int     reg;
            int     val;
    };
    
    static const struct dp83812_init_reg dp83812_master_cs1_0_init[] = {
            {0x523, 0x0001},
            {0x800, 0xf864},
            {0x803, 0x1552},
            {0x804, 0x1a66},
            {0x805, 0x1f7b},
            {0x81f, 0x2a88},
            {0x825, 0x40e5},
            {0x82b, 0x7f3f},
            {0x830, 0x0543},
            {0x836, 0x5008},
            {0x83a, 0x08e0},
            {0x83b, 0x0845},
            {0x83e, 0x0445},
            {0x855, 0x9b9a},
            {0x85f, 0x2010},
            {0x860, 0x6040},
            {0x86c, 0x1333},
            {0x86b, 0x3e10},
            {0x872, 0x88c0},
            {0x873, 0x0003},
            {0x879, 0x000f},
            {0x87b, 0x0070},
            {0x87c, 0x003f},
            {0x89e, 0x00aa},
            {0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_master_cs2_0_init[] = {
            {0x523, 0x0001},
            {0x81C, 0x0fe2},
            {0x872, 0x0300},
            {0x879, 0x0f00},
            {0x806, 0x2952},
            {0x807, 0x3361},
            {0x808, 0x3D7B},
            {0x83E, 0x045F},
            {0x834, 0x8000},
            {0x862, 0x00E8},
            {0x896, 0x32CB},
            {0x03E, 0x0009},
            {0x01f, 0x4000},
            {0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_slave_cs1_0_init[] = {
            {0x523, 0x0001},
            {0x803, 0x1b52},
            {0x804, 0x216c},
            {0x805, 0x277b},
            {0x827, 0x3000},
            {0x830, 0x0543},
            {0x83a, 0x0020},
            {0x83c, 0x0001},
            {0x855, 0x9b9a},
            {0x85f, 0x2010},
            {0x860, 0x6040},
            {0x86c, 0x0333},
            {0x872, 0x88c0},
            {0x873, 0x0021},
            {0x879, 0x000f},
            {0x87b, 0x0070},
            {0x87c, 0x0002},
            {0x897, 0x003f},
            {0x89e, 0x00a2},
            {0x510, 0x000f},
            {0x523, 0x0000},
    };
    
    static const struct dp83812_init_reg dp83812_slave_cs2_0_init[] = {
            {0x523, 0x0001},
            {0x873, 0x0821},
            {0x896, 0x22ff},
            {0x89E, 0x0000},
            {0x01f, 0x4000},
            {0x523, 0x0000},
    };
    
    struct dp83812_private {
            int chip;
            bool is_master;
            bool is_rgmii;
            bool is_sgmii;
    };
    
    static int dp83812_read_straps(struct phy_device *phydev)
    {
            struct dp83812_private *dp83812 = phydev->priv;
            int strap;
    
            strap = phy_read_mmd(phydev, DP83812_DEVADDR, DP83812_STRAP);
            if (strap < 0)
                    return strap;
    
            printk("%s: Strap is 0x%X\n", __func__, strap);
            if (strap & DP83812_MASTER_MODE)
                    dp83812->is_master = true;
    
            if (strap & DP83812_RGMII_IS_EN)
                    dp83812->is_rgmii = true;
            return 0;
    };
    
    static int dp83812_reset(struct phy_device *phydev, bool hw_reset)
    {
            int ret;
    
            if (hw_reset)
                    ret = phy_write(phydev, MII_DP83812_RESET_CTRL,
                                    DP83812_HW_RESET);
            else
                    ret = phy_write(phydev, MII_DP83812_RESET_CTRL,
                                    DP83812_SW_RESET);
    
            if (ret)
                    return ret;
    
            mdelay(100);
    
            return 0;
    }
    
    static int dp83812_phy_reset(struct phy_device *phydev)
    {
            int err;
            int ret;
    
            err = phy_write(phydev, MII_DP83812_RESET_CTRL, DP83812_HW_RESET);
            if (err < 0)
                    return err;
    
            ret = dp83812_read_straps(phydev);
            if (ret)
                    return ret;
    
            return 0;
    }
    
    static int dp83812_write_seq(struct phy_device *phydev, const struct
                                    dp83812_init_reg *init_data, int size)
    {
            int ret;
            int i;
    
            for (i = 0; i < size; i++) {
                    ret = phy_write_mmd(phydev, DP83812_DEVADDR, init_data[i].reg,
                                            init_data[i].val);
            if (ret)
                    return ret;
            }
            return 0;
    }
    
    static int dp83812_chip_init(struct phy_device *phydev)
    {
            struct dp83812_private *dp83812 = phydev->priv;
            int ret;
    	printk("~~~~~~~~~~HI LOADED~~~~~~~~~~~\n");
            ret = dp83812_reset(phydev, true);
            if (ret)
                    return ret;
    
            if (dp83812->is_master)
                    ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0xc001);
                    // ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0xc001);
            else
                    ret = phy_write_mmd(phydev, DP83812_DEVADDR_MMD1, 0x0834, 0x8001);
                    // ret = phy_write_mmd(phydev, DP83812_DEVADDR, 0x0834, 0x8001);
    
            switch (dp83812->chip) {
            case DP83812_CS1:
                    if (dp83812->is_master)
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_master_cs1_0_init,
                                                    ARRAY_SIZE(dp83812_master_cs1_0_init));
                    else
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_slave_cs1_0_init,
                                                    ARRAY_SIZE(dp83812_slave_cs1_0_init));
            break;
            case DP83812_CS2:
                    if (dp83812->is_master)
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_master_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_master_cs2_0_init));
                    else
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_slave_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_slave_cs2_0_init));
            break;
            case DP83813_CS2:
                    if (dp83812->is_master)
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_master_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_master_cs2_0_init));
                    else
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_slave_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_slave_cs2_0_init));
            break;
            case DP83814_CS2:
                    if (dp83812->is_master)
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_master_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_master_cs2_0_init));
                    else
                            ret = dp83812_write_seq(phydev,
                                                    dp83812_slave_cs2_0_init,
                                                    ARRAY_SIZE(dp83812_slave_cs2_0_init));
            break;
            default:
                    return -EINVAL;
            };
    
            if (ret)
                    return ret;
    
            mdelay(10);
            // phy_write_mmd(phydev, DP83812_DEVADDR, 0x523, 0x00);
            /* Do a soft reset to restart the PHY with updated values */
            return dp83812_reset(phydev, false);
    }
    
    static int dp83812_config_init(struct phy_device *phydev)
    {
            int value, err;
    
            err = dp83812_chip_init(phydev);
            if (err)
                    return err;
    	phydev_info(phydev, "~~~~~~~~~~~LOADED~~~~~~~~~~~\n");
    
            value = phy_read_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL);
            if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
                    err = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
                                            (DP83812_SGMII_EN | value));
            } else {
                    err = phy_write_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL,
                                            (~DP83812_SGMII_EN & value));
            }
    
            if (err < 0)
    
                    return err;
    
            return 0;
    }
    
    static int dp83812_ack_interrupt(struct phy_device *phydev)
    {
            int err;
    
            err = phy_read(phydev, MII_DP83812_INT_STAT1);
            if (err < 0)
                    return err;
    
            err = phy_read(phydev, MII_DP83812_INT_STAT2);
            if (err < 0)
                    return err;
    
            err = phy_read(phydev, MII_DP83812_INT_STAT3);
            if (err < 0)
                    return err;
    
            return 0;
    }
    
    static int dp83812_config_intr(struct phy_device *phydev)
    {
            int misr_status, err;
    
            if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
                    misr_status = phy_read(phydev, MII_DP83812_INT_STAT1);
                    if (misr_status < 0)
                            return misr_status;
    
                    misr_status |= (DP83812_ESD_EVENT_INT_EN |
                                    DP83812_LINK_STAT_INT_EN |
                                    DP83812_ENERGY_DET_INT_EN |
                                    DP83812_LINK_QUAL_INT_EN);
    
                    err = phy_write(phydev, MII_DP83812_INT_STAT1, misr_status);
                    if (err < 0)
                            return err;
    
                    misr_status = phy_read(phydev, MII_DP83812_INT_STAT2);
                    if (misr_status < 0)
                            return misr_status;
    
                    misr_status |= (DP83812_SLEEP_MODE_INT_EN |
                                    DP83812_OVERTEMP_INT_EN |
                                    DP83812_OVERVOLTAGE_INT_EN |
                                    DP83812_UNDERVOLTAGE_INT_EN);
    
                    err = phy_write(phydev, MII_DP83812_INT_STAT2, misr_status);
                    if (err < 0)
                            return err;
    
                    misr_status = phy_read(phydev, MII_DP83812_INT_STAT3);
                    if (misr_status < 0)
                            return misr_status;
    
                    misr_status |= (DP83812_LPS_INT_EN |
                                    DP83812_WAKE_REQ_INT_EN |
                                    DP83811_NO_FRAME_INT_EN |
                                    DP83811_POR_DONE_INT_EN);
    
                    err = phy_write(phydev, MII_DP83812_INT_STAT3, misr_status);
    
            } else {
                    err = phy_write(phydev, MII_DP83812_INT_STAT1, 0);
                    if (err < 0)
                            return err;
    
                    err = phy_write(phydev, MII_DP83812_INT_STAT2, 0);
                    if (err < 0)
                            return err;
    
                    err = phy_write(phydev, MII_DP83812_INT_STAT3, 0);
            }
    
            return err;
    }
    
    #if 0
    static irqreturn_t dp83812_handle_interrupt(struct phy_device *phydev)
    {
            bool trigger_machine = false;
            int irq_status;
    
            /* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
             * in the upper half (15:8), while the lower half (7:0) is used for
             * controlling the interrupt enable state of those individual interrupt
             * sources. To determine the possible interrupt sources, just read the
             * INT_STAT* register and use it directly to know which interrupts have
             * been enabled previously or not.
             */
            irq_status = phy_read(phydev, MII_DP83812_INT_STAT1);
            if (irq_status < 0) {
                    phy_error(phydev);
                    return IRQ_NONE;
            }
            if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
                    trigger_machine = true;
    
            irq_status = phy_read(phydev, MII_DP83812_INT_STAT2);
            if (irq_status < 0) {
                    phy_error(phydev);
                    return IRQ_NONE;
            }
            if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
                    trigger_machine = true;
    
            irq_status = phy_read(phydev, MII_DP83812_INT_STAT3);
            if (irq_status < 0) {
                    phy_error(phydev);
                    return IRQ_NONE;
            }
            if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
                    trigger_machine = true;
    
            if (!trigger_machine)
                    return IRQ_NONE;
    
            phy_trigger_machine(phydev);
    
            return IRQ_HANDLED;
    }
    #endif
    
    static int dp83812_config_aneg(struct phy_device *phydev)
    {
            int value, err;
    
            if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
                    value = phy_read_mmd(phydev, DP83812_DEVADDR, MII_DP83812_SGMII_CTRL);
                    if (phydev->autoneg == AUTONEG_ENABLE) {
                            err = phy_write_mmd(phydev, DP83812_DEVADDR,
                                                MII_DP83812_SGMII_CTRL,
                                            (DP83812_SGMII_AUTO_NEG_EN | value));
                            if (err < 0)
                                    return err;
                    } else {
                            err = phy_write_mmd(phydev, DP83812_DEVADDR,
                                                MII_DP83812_SGMII_CTRL,
                                            (~DP83812_SGMII_AUTO_NEG_EN & value));
                            if (err < 0)
                                    return err;
                    }
            }
            return genphy_config_aneg(phydev);
    }
    
    
    
    static int dp83812_probe(struct phy_device *phydev)
    {
            struct dp83812_private *dp83812;
            int ret;
    
            dp83812 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83812), GFP_KERNEL);
            if (!dp83812)
                    return -ENOMEM;
    	pr_err("~~~~~~~~~~~~~Entered into probe function~~~~~~~~~~~~~~~~\n");
            pr_err("~~~~~~~~~~~LOADED~~~~~~~~~~~\n");
    	
    	phydev->priv = dp83812;
    	ret = dp83812_read_straps(phydev);
            if (ret)
                    return ret;
    
            switch (phydev->phy_id) {
            case DP83TC812_CS1_0_PHY_ID:
                    dp83812->chip = DP83812_CS1;
            break;
            case DP83TC812_CS2_0_PHY_ID:
                    dp83812->chip = DP83812_CS2;
            break;
            case DP83TC813_CS2_0_PHY_ID:
                    dp83812->chip = DP83813_CS2;
                    break;
            case DP83TC814_CS2_0_PHY_ID:
                    dp83812->chip = DP83814_CS2;
            break;
            default:
            return -EINVAL;
            };
    /* vikram : above code added to switch between different phy ids */
    
            return dp83812_config_init(phydev);
    }
    
    #define DP83812_PHY_DRIVER(_id, _name)                          \
            {                                                       \
                    PHY_ID_MATCH_EXACT(_id),                        \
                    .name           = (_name),                      \
                    .probe          = dp83812_probe,                \
                    /* PHY_BASIC_FEATURES */                        \
                    .soft_reset     = dp83812_phy_reset,            \
                    .config_init    = dp83812_config_init,          \
                    .config_aneg = dp83812_config_aneg,             \
                    .ack_interrupt = dp83812_ack_interrupt,         \
    /*if 0                                                          \
                    .handle_interrupt = dp83812_handle_interrupt,   \
    #endif  */                                                      \
                    .config_intr = dp83812_config_intr,             \
                    .suspend = genphy_suspend,                      \
                    .resume = genphy_resume,                        \
            }
    
    static struct phy_driver dp83812_driver[] = {
            DP83812_PHY_DRIVER(DP83TC812_CS1_0_PHY_ID, "TI DP83TC812CS1.0"),
            DP83812_PHY_DRIVER(DP83TC812_CS2_0_PHY_ID, "TI DP83TC812CS2.0"),
            DP83812_PHY_DRIVER(DP83TC813_CS2_0_PHY_ID, "TI DP83TC813CS2.0"),
            DP83812_PHY_DRIVER(DP83TC814_CS2_0_PHY_ID, "TI DP83TC814CS2.0"),
            };
    
    module_phy_driver(dp83812_driver);
    
    static struct mdio_device_id __maybe_unused dp83812_tbl[] = {
            { PHY_ID_MATCH_EXACT(DP83TC812_CS1_0_PHY_ID) },
            { PHY_ID_MATCH_EXACT(DP83TC812_CS2_0_PHY_ID) },
            { PHY_ID_MATCH_EXACT(DP83TC813_CS2_0_PHY_ID) },
            { PHY_ID_MATCH_EXACT(DP83TC814_CS2_0_PHY_ID) },
            { },
    };
    
    MODULE_DESCRIPTION("Texas Instruments DP83TC812 PHY driver");
    MODULE_AUTHOR("Hari Nagalla <hnagalla@ti.com");
    MODULE_LICENSE("GPL");
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Santhoshwaran:

    抱歉、我为错误的器件附上了驱动器。 如果仍有问题、请尝试使用此驱动程序。

    e2e.ti.com/.../dp83tc812.zip

    此致、

    梅利萨