Mstar Mac Phy 驱动学习

MII.h 和 MII.c
这是MII协议。里面有MII协议的PHY寄存器地址,及MII通信接口库

Linux的mdio主要是为了管理PHY芯片寄存器的,跟踪代码发现,它会进行创建PHY设备及一些初始化工作。

Linux内核有很多的PHY驱动。

PHY一般和具体的MAC控制驱动联系一起,这里以TI的MAC驱动为例,由它切入到PHY驱动。Linux内核通过mdio总线访问、控制PHY,源码实现在driver/net/phy/mdio_bus.c中

Linux Ethernet PHY 驱动:
http://www.voidcn.com/article/p-nhdqyqlp-h.html

Ethernet PHY芯片AR8035驱动:http://www.voidcn.com/article/p-pvwtfenz-ug.html

PHY Linux 驱动

Linux 4.6 phy驱动调试

linux Phy 设备驱动

linux Phy 设备驱动

linux PHY驱动

MII接口简介

MII接口及应用

Linux PHY 几个状态的跟踪

Linux phy驱动介绍

以太网芯片MAC和PHY的关系

MII PHY 寄存器简介:
https://www.jianshu.com/p/d539c41816e7

phy 寄存器简介

kernel里面include\uapi\linux\mii.h
在这里插入图片描述
分别对应的是PHY寄存器
在这里插入图片描述
而其中的control register 寄存器有这些配置
在这里插入图片描述
也即
在这里插入图片描述
Reset:Bit15控制的是PHY复位功能,在该位置写入1实现对PHY的复位操作。复位后该端口PHY的其他控制、状态寄存器将恢复到默认值,每次PHY复位应该在0.5s的时间内完成,复位过程中Bit15保持为1,复位完成之后该位应该自动清零。一般要改变端口的工作模式(如速率、双工、流控或协商信息等)时,在设置完相应位置的寄存器之后,需要通过Reset位复位PHY来使配置生效。

Loopback:Loopback是一个调试以及故障诊断中常用的功能,Bit14置1之后,PHY和外部MDI的连接在逻辑上将被断开,从MAC经过MII/GMII(也可能是其他的MAC/PHY接口)发送过来的数据将不会被发送到MDI上,而是在PHY内部(一般在PCS)回环到本端口的MII/GMII接收通道上,通过Loopback功能可以检查MII/GMII以及PHY接口部分是否工作正常,对于端口不通的情况可用于故障定位。需要注意的是,很多时候PHY设置Loopback后端口可能就Link down了,MAC无法向该端口发帧,这时就需要通过设置端口Force Link up才能使用Loopback功能。

Speed Selection:Bit13和Bit6两位联合实现对端口的速率控制功能,具体的对应关系见表2。需要注意的是Speed Selection只有在自动协商关闭的情况下才起作用,如果自动协商设置为Enable状态,则该设置不起作用;并且,对Speed Selection的修改设置,往往需要复位端口才能配置生效。因此在设置该位置的时候需要检查自动协商的设置并通过Bit15复位端口。

Auto-Negotiation Enable:自动协商(AN)开关。设置为1表示打开AN功能,端口的工作模式通过和连接对端进行AN来确定。如果设置为0则AN功能关系,端口的工作模式通过Control Register相应位置的配置决定。必须注意的是,对于1000BASE-T接口,自动协商必须打开。

Power Down:端口工作开关。设置为1将使端口进入Power Down模式,正常情况下PHY在Power Down模式其MII和MDI均不会对外发送数据。Power Down模式一般在软件shut down端口的时候使用,需要注意的是端口从Power Down模式恢复,需要复位端口以保证端口可靠的连接。

Isolate:隔离状态开关。该位置1将导致PHY和MII接口之间处于电气隔离状态,除了MDC/MDIO接口的信号外,其他MII引脚处于高阻态。IEEE802.3没有对Isolate 时MDI接口的状态进行规范,此时MDI端可能还在正常运行。Isolate在实际应用中并没有用到。并且,值得注意的是,由于目前很多百兆的PHY芯片其MAC接口主流的都是SMII/S3MII,8个端口的接口是相互关联的,一个端口设置Isolate可能会影响其他端口的正常使用,因此在使用中注意不要随意更改bit10的状态。

Restart Auto-Negotiation :重新启动自动协商开关。Bit9置1将重新启动端口的自动协商进程,当然前提是Auto-Negotiation Enable是使能的。一般在修改端口的自动协商能力信息之后通过Bit9置1重新启动自动协商来使端口按照新的配置建立link。

Duplex Mode:双工模式设置。Bit8置1端口设置为全双工,置0则端设置为半双工,和Speed Selection的设置一样,Duplex Mode的设置只有在自动协商关闭的情况下才起作用,如果自动协商设置为Enable状态,则该设置不起作用,端口的双工模式根据AN结果来定。对Duplex Mode的修改配置也需要复位端口才能生效。

Collision Test:冲突信号(COL)测试开关。在需要对COL信号进行测试时,可以通过Bit7置1,这时PHY将输出一个COL脉冲以供测试。实际测试操作中也可以将端口配置为半双工状态,通过发帧冲突来测试COL信号,因此该配置实用价值不大。

status register 有这些配置
在这里插入图片描述
Auto-Negotiation Complete:AN完成状态指示位。Bit5指示的是端口AN进程是否完成的状态位。在AN Enable的情况下,Bit5=1表示自动协商进程已经成功结束,此时PHY的其他和Link状态相关的寄存器才是正确可靠的。如果AN进程没有完成,则这些状态信息可能是错误的。在调试以及异常故障处理时,可以通过该位寄存器的状态判断AN是否成功,从而进一步的检查AN相关的设置是否正确,或者芯片的AN功能是否正常等。

Remote Fault:远端错误指示位。Bit4=1代表连接对端(Link Partner)出错,至于出错的具体类型以及错误检测机制在规范中并没有定义,由PHY的制造商自由发挥,一般的厂商都会在其他的寄存器(Register16-31由厂商自行定义)指示比较详细的错误类型。在与端口相关的故障查证中,Remote Fault是一个重要的指示信息,通过互联双方的Remote Fault信息(可能要加上其他的具体错误指示),可以帮助定位故障原因。

Link Status:Link状态指示位。Bit2=1代表端口Link up,0则代表端口Link down。实际应用中一般都是通过Bit2来判断端口的状态。而且,一般的MAC芯片也是通过轮询PHY的这个寄存器值来判断端口的Link状态的(这个过程可能有不同的名称,比如BCM叫做Link Scan,而Marvell叫做PHY Polling。)如前所述,在AN Enable的情况下,Link Status的信息只有在Auto-Negotiation Complete指示已经完成的情况下才是正确可靠的,否则有可能出错。

Jabber Detect:Jabber 检测指示位。IEEE802.3对Jabber的解释是"A condition wherein a station transmits for a period of time longer than the maximum permissible packet length, usually due to a fault condition"。这一位指示的是Link Partner发送的时间超过了规定的最大长度。值得注意的是,Jabber Detect只有在10BASE-T模式下才有意义,100和1000M模式是没有定义Jabber这一功能的。

更多寄存器配置说明查看文件MII.h

/*
 * linux/mii.h: definitions for MII-compatible transceivers
 * Originally drivers/net/sunhme.h.
 *
 * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
 */

#ifndef _UAPI__LINUX_MII_H__
#define _UAPI__LINUX_MII_H__

#include <linux/types.h>
#include <linux/ethtool.h>

/* Generic MII registers. */
#define MII_BMCR		0x00	/* Basic mode control register */
#define MII_BMSR		0x01	/* Basic mode status register  */
#define MII_PHYSID1		0x02	/* PHYS ID 1                   */
#define MII_PHYSID2		0x03	/* PHYS ID 2                   */
#define MII_ADVERTISE		0x04	/* Advertisement control reg   */
#define MII_LPA			0x05	/* Link partner ability reg    */
#define MII_EXPANSION		0x06	/* Expansion register          */
#define MII_CTRL1000		0x09	/* 1000BASE-T control          */
#define MII_STAT1000		0x0a	/* 1000BASE-T status           */
#define	MII_MMD_CTRL		0x0d	/* MMD Access Control Register */
#define	MII_MMD_DATA		0x0e	/* MMD Access Data Register */
#define MII_ESTATUS		0x0f	/* Extended Status             */
#ifdef CONFIG_MP_GEMAC_MII_PHY_STAT
#define MII_PHYSR		0x11	/* PHY specific status register */
#endif /* End of CONFIG_MP_GEMAC_MII_PHY_STAT */
#define MII_DCOUNTER		0x12	/* Disconnect counter          */
#define MII_FCSCOUNTER		0x13	/* False carrier counter       */
#define MII_NWAYTEST		0x14	/* N-way auto-neg test reg     */
#define MII_RERRCOUNTER		0x15	/* Receive error counter       */
#define MII_SREVISION		0x16	/* Silicon revision            */
#define MII_RESV1		0x17	/* Reserved...                 */
#define MII_LBRERROR		0x18	/* Lpback, rx, bypass error    */
#define MII_PHYADDR		0x19	/* PHY address                 */
#define MII_RESV2		0x1a	/* Reserved...                 */
#define MII_TPISTATUS		0x1b	/* TPI status for 10mbps       */
#define MII_NCONFIG		0x1c	/* Network interface config    */

/* Basic mode control register. */
#define BMCR_RESV		0x003f	/* Unused...                   */
#define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)         */
#define BMCR_CTST		0x0080	/* Collision test              */
#define BMCR_FULLDPLX		0x0100	/* Full duplex                 */
#define BMCR_ANRESTART		0x0200	/* Auto negotiation restart    */
#define BMCR_ISOLATE		0x0400	/* Isolate data paths from MII */
#define BMCR_PDOWN		0x0800	/* Enable low power state      */
#define BMCR_ANENABLE		0x1000	/* Enable auto negotiation     */
#define BMCR_SPEED100		0x2000	/* Select 100Mbps              */
#define BMCR_LOOPBACK		0x4000	/* TXD loopback bits           */
#define BMCR_RESET		0x8000	/* Reset to default state      */
#define BMCR_SPEED10		0x0000	/* Select 10Mbps               */

/* Basic mode status register. */
#define BMSR_ERCAP		0x0001	/* Ext-reg capability          */
#define BMSR_JCD		0x0002	/* Jabber detected             */
#define BMSR_LSTATUS		0x0004	/* Link status                 */
#define BMSR_ANEGCAPABLE	0x0008	/* Able to do auto-negotiation */
#define BMSR_RFAULT		0x0010	/* Remote fault detected       */
#define BMSR_ANEGCOMPLETE	0x0020	/* Auto-negotiation complete   */
#define BMSR_RESV		0x00c0	/* Unused...                   */
#define BMSR_ESTATEN		0x0100	/* Extended Status in R15      */
#define BMSR_100HALF2		0x0200	/* Can do 100BASE-T2 HDX       */
#define BMSR_100FULL2		0x0400	/* Can do 100BASE-T2 FDX       */
#define BMSR_10HALF		0x0800	/* Can do 10mbps, half-duplex  */
#define BMSR_10FULL		0x1000	/* Can do 10mbps, full-duplex  */
#define BMSR_100HALF		0x2000	/* Can do 100mbps, half-duplex */
#define BMSR_100FULL		0x4000	/* Can do 100mbps, full-duplex */
#define BMSR_100BASE4		0x8000	/* Can do 100mbps, 4k packets  */

/* Advertisement control register. */
#define ADVERTISE_SLCT		0x001f	/* Selector bits               */
#define ADVERTISE_CSMA		0x0001	/* Only selector supported     */
#define ADVERTISE_10HALF	0x0020	/* Try for 10mbps half-duplex  */
#define ADVERTISE_1000XFULL	0x0020	/* Try for 1000BASE-X full-duplex */
#define ADVERTISE_10FULL	0x0040	/* Try for 10mbps full-duplex  */
#define ADVERTISE_1000XHALF	0x0040	/* Try for 1000BASE-X half-duplex */
#define ADVERTISE_100HALF	0x0080	/* Try for 100mbps half-duplex */
#define ADVERTISE_1000XPAUSE	0x0080	/* Try for 1000BASE-X pause    */
#define ADVERTISE_100FULL	0x0100	/* Try for 100mbps full-duplex */
#define ADVERTISE_1000XPSE_ASYM	0x0100	/* Try for 1000BASE-X asym pause */
#define ADVERTISE_100BASE4	0x0200	/* Try for 100mbps 4k packets  */
#define ADVERTISE_PAUSE_CAP	0x0400	/* Try for pause               */
#define ADVERTISE_PAUSE_ASYM	0x0800	/* Try for asymetric pause     */
#define ADVERTISE_RESV		0x1000	/* Unused...                   */
#define ADVERTISE_RFAULT	0x2000	/* Say we can detect faults    */
#define ADVERTISE_LPACK		0x4000	/* Ack link partners response  */
#define ADVERTISE_NPAGE		0x8000	/* Next page bit               */

#define ADVERTISE_FULL		(ADVERTISE_100FULL | ADVERTISE_10FULL | \
				  ADVERTISE_CSMA)
#define ADVERTISE_ALL		(ADVERTISE_10HALF | ADVERTISE_10FULL | \
				  ADVERTISE_100HALF | ADVERTISE_100FULL)

/* Link partner ability register. */
#define LPA_SLCT		0x001f	/* Same as advertise selector  */
#define LPA_10HALF		0x0020	/* Can do 10mbps half-duplex   */
#define LPA_1000XFULL		0x0020	/* Can do 1000BASE-X full-duplex */
#define LPA_10FULL		0x0040	/* Can do 10mbps full-duplex   */
#define LPA_1000XHALF		0x0040	/* Can do 1000BASE-X half-duplex */
#define LPA_100HALF		0x0080	/* Can do 100mbps half-duplex  */
#define LPA_1000XPAUSE		0x0080	/* Can do 1000BASE-X pause     */
#define LPA_100FULL		0x0100	/* Can do 100mbps full-duplex  */
#define LPA_1000XPAUSE_ASYM	0x0100	/* Can do 1000BASE-X pause asym*/
#define LPA_100BASE4		0x0200	/* Can do 100mbps 4k packets   */
#define LPA_PAUSE_CAP		0x0400	/* Can pause                   */
#define LPA_PAUSE_ASYM		0x0800	/* Can pause asymetrically     */
#define LPA_RESV		0x1000	/* Unused...                   */
#define LPA_RFAULT		0x2000	/* Link partner faulted        */
#define LPA_LPACK		0x4000	/* Link partner acked us       */
#define LPA_NPAGE		0x8000	/* Next page bit               */

#define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)

/* Expansion register for auto-negotiation. */
#define EXPANSION_NWAY		0x0001	/* Can do N-way auto-nego      */
#define EXPANSION_LCWP		0x0002	/* Got new RX page code word   */
#define EXPANSION_ENABLENPAGE	0x0004	/* This enables npage words    */
#define EXPANSION_NPCAPABLE	0x0008	/* Link partner supports npage */
#define EXPANSION_MFAULTS	0x0010	/* Multiple faults detected    */
#define EXPANSION_RESV		0xffe0	/* Unused...                   */

#define ESTATUS_1000_TFULL	0x2000	/* Can do 1000BT Full          */
#define ESTATUS_1000_THALF	0x1000	/* Can do 1000BT Half          */

/* N-way test register. */
#define NWAYTEST_RESV1		0x00ff	/* Unused...                   */
#define NWAYTEST_LOOPBACK	0x0100	/* Enable loopback for N-way   */
#define NWAYTEST_RESV2		0xfe00	/* Unused...                   */

/* 1000BASE-T Control register */
#define ADVERTISE_1000FULL	0x0200  /* Advertise 1000BASE-T full duplex */
#define ADVERTISE_1000HALF	0x0100  /* Advertise 1000BASE-T half duplex */
#define CTL1000_AS_MASTER	0x0800
#define CTL1000_ENABLE_MASTER	0x1000

/* 1000BASE-T Status register */
#define LPA_1000LOCALRXOK	0x2000	/* Link partner local receiver status */
#define LPA_1000REMRXOK		0x1000	/* Link partner remote receiver status */
#define LPA_1000FULL		0x0800	/* Link partner 1000BASE-T full duplex */
#define LPA_1000HALF		0x0400	/* Link partner 1000BASE-T half duplex */

/* Flow control flags */
#define FLOW_CTRL_TX		0x01
#define FLOW_CTRL_RX		0x02

/* MMD Access Control register fields */
#define MII_MMD_CTRL_DEVAD_MASK	0x1f	/* Mask MMD DEVAD*/
#define MII_MMD_CTRL_ADDR	0x0000	/* Address */
#define MII_MMD_CTRL_NOINCR	0x4000	/* no post increment */
#define MII_MMD_CTRL_INCR_RDWT	0x8000	/* post increment on reads & writes */
#define MII_MMD_CTRL_INCR_ON_WT	0xC000	/* post increment on writes only */

#ifdef CONFIG_MP_GEMAC_MII_PHY_STAT
/* PHY specific status register  */
#define PHYSR_SPEED_MASK	0xc000	/* Speed mask*/
#define PHYSR_RESERVED		0xc000	/* Reserved*/
#define PHYSR_1000		0x8000	/* 1000Mbps*/
#define PHYSR_100		0x4000	/* 100Mbps*/
#define PHYSR_10		0x0000	/* 10Mbps*/
#define PHYSR_DUPLEX_MASK	0x2000	/* Duplex mask*/
#define PHYSR_FULL_DUPLEX	0x2000	/* Full duplex*/
#define PHYSR_HALF_DUPLEX	0x0000	/* Half duplex*/
#endif /* End of CONFIG_MP_GEMAC_MII_PHY_STAT */

/* This structure is used in all SIOCxMIIxxx ioctl calls */
struct mii_ioctl_data {
	__u16		phy_id;
	__u16		reg_num;
	__u16		val_in;
	__u16		val_out;
};

#endif /* _UAPI__LINUX_MII_H__ */

mstar 平台phy 相关文件:
kernel\linaro\mstar2\hal\m7221\emac\mhal_emac.c
kernel\linaro\mstar2\drv\emac\mdrv_emac.c
kernel\linaro\mstar2\hal\m7221\emac\mhal_emac.h
kernel\linaro\mstar2\drv\emac\mdrv_emac.h
kernel\linaro\drivers\net\mii.c
kernel\linaro\drivers\net\phy\phy_device.c
kernel\linaro\drivers\net\phy\phy.c

mstar 平台网卡属性操作:
接口有MHal_EMAC_read_phy ,MHal_EMAC_write_phy

  • Auto-negotiation complete
		u32  bmsr;
		MHal_EMAC_read_phy(phyaddr, MII_BMSR, &bmsr);
        MHal_EMAC_read_phy(phyaddr, MII_BMSR, &bmsr);
        if (bmsr & BMSR_ANEGCOMPLETE) {
            /* For Link Parterner adopts force mode and EPHY used,
             * EPHY LPA reveals all zero value.
             * EPHY would be forced to Full-Duplex mode.
             */
            ......
        }

MII_BMSR 为寄存器id,BMSR_ANEGCOMPLETE 为Auto-negotiation complete对应的bit 位。

  • Link partner ability
        MHal_EMAC_read_phy (phyaddr, MII_LPA, &LocPtrA);
        if ((LocPtrA & LPA_100FULL) || (LocPtrA & LPA_100HALF))
        {
            uRegStatus |= ETHERNET_TEST_SPEED_100M; //SPEED_100//
        }
        else
        {
            uRegStatus &= ~ETHERNET_TEST_SPEED_100M; //SPEED_10//
        }

        if ((LocPtrA & LPA_100FULL) || (LocPtrA & LPA_10FULL))
        {
            uRegStatus |= ETHERNET_TEST_DUPLEX_FULL; //DUPLEX_FULL//
        }
        else
        {
            uRegStatus &= ~ETHERNET_TEST_DUPLEX_FULL; //DUPLEX_HALF//
        }

MII_LPA 为“Link partner ability ” 寄存器索引id,LPA_100HALF 为bit 7 ,为1 则表示可以做可以做100M bps半双工,LPA_100FULL 为bit 8 ,为1 则表示可以做100M bps全双工。

MHal_EMAC_read_phy

//-------------------------------------------------------------------------------------------------
// Read value stored in a PHY register.
// Note: MDI interface is assumed to already have been enabled.
//-------------------------------------------------------------------------------------------------
void MHal_EMAC_read_phy( unsigned char phy_addr, unsigned char address, u32* value )
{
#if CONFIG_ETHERNET_ALBANY
    phys_addr_t uRegBase  = INTERNEL_PHY_REG_BASE;
    u32 tempvalue ;

    phy_addr =0;

    tempvalue = *(volatile unsigned int *)(INTERNEL_PHY_REG_BASE + 0x04UL);
    tempvalue |= 0x0004UL;
    *(volatile unsigned int *)(INTERNEL_PHY_REG_BASE + 0x04UL) = tempvalue;
    udelay( 1 );
    *value = *(volatile unsigned int *)(uRegBase + address*4);
#else
    u32 uRegVal = 0, uCTL = 0;

    uRegVal = (EMAC_HIGH | EMAC_CODE_802_3 | EMAC_RW_R)
            | ((phy_addr & 0x1fUL) << PHY_ADDR_OFFSET) | (address << PHY_REGADDR_OFFSET) | (0) ;

    uCTL = MHal_EMAC_Read_CTL();
    MHal_EMAC_enable_mdi();
    MHal_EMAC_Write_MAN(uRegVal);

    //Wait until IDLE bit in Network Status register is cleared //
    uRegVal = MHal_EMAC_ReadReg32( REG_ETH_SR );  //Must read Low 16 bit.
    while ( !( uRegVal & EMAC_IDLE ) )
    {
        uRegVal = MHal_EMAC_ReadReg32( REG_ETH_SR );
        barrier();
    }
    *value = ( MHal_EMAC_Read_MAN() & 0x0000ffffUL );
    MHal_EMAC_Write_CTL(uCTL);
#endif
}

MHal_EMAC_write_phy

//-------------------------------------------------------------------------------------------------
// Write value to the a PHY register
// Note: MDI interface is assumed to already have been enabled.
//-------------------------------------------------------------------------------------------------
void MHal_EMAC_write_phy( unsigned char phy_addr, unsigned char address, u32 value )
{
#if CONFIG_ETHERNET_ALBANY
    phys_addr_t uRegBase = INTERNEL_PHY_REG_BASE;

    phy_addr =0;

    *(volatile unsigned int *)(uRegBase + address*4) = value;
    udelay( 1 );
#else
    u32 uRegVal = 0, uCTL = 0;
    uRegVal =  ( EMAC_HIGH | EMAC_CODE_802_3 | EMAC_RW_W) | (( phy_addr & 0x1FUL ) << PHY_ADDR_OFFSET )
                | ( address << PHY_REGADDR_OFFSET ) | (value & 0xFFFFUL);

    uCTL = MHal_EMAC_Read_CTL();
    MHal_EMAC_enable_mdi();

    MHal_EMAC_Write_MAN( uRegVal );
    // Wait until IDLE bit in Network Status register is cleared //
    uRegVal = MHal_EMAC_ReadReg32( REG_ETH_SR );  //Must read Low 16 bit.
    while ( !( uRegVal & EMAC_IDLE ) )
    {
        uRegVal = MHal_EMAC_ReadReg32( REG_ETH_SR );
        barrier();
    }
    MHal_EMAC_Write_CTL(uCTL);
#endif
}

两个函数用法差不多,主要是查清楚,寄存器 id 及其bit 对应的功能,这就需要对协议比较了解。

eth mac 中断
在这里插入图片描述
其中emac 中断ID为

dev->irq = E_IRQ_EMAC;

E_IRQ_EMAC 在kernel\linaro\mstar2\hal\m7221\cpu\arm64\chip_int.h定义
在这里插入图片描述

当然,如果能拿到原厂驱动设备在cpu 的映射地址,则可以接获取对应寄存器的信息:

例如,某方案的bank 34 对应的寄存器14 ,寄存器 15 储存网卡的状态信息,其中reg 15 的bit0,bit3 都为1 时,网线物理连接;都为零时,网线物理断开。

BOOL xxxxxxxxxx::function()
{
    BOOL     bRet = false;
    MS_U8  u8RegL = 0x00;
    MS_U8  u8RegH = 0x00;
    MS_U16 detRes = 0x0000;

    u8RegL = MApi_XC_ReadByte(0x003414);
    u8RegH = MApi_XC_ReadByte(0x003414 + 1);
    detRes = (u8RegH << 8 | u8RegL);
    printf("[Alex] detect res: 0x%04x .\n",detRes);
    if( detRes == 0x0000 || detRes == 0x0020)
    {
        bRet = false;
    }
    else if(u8RegH == 0x09)
    {
        bRet = true;
    }

    return bRet;
}

又如T9632 ,新加的RJ45 座子,其中灯不是直连主芯片,而是直连网络芯片,而网线的连接状态在网络芯片的emac模块被检测到,这个时候可以在这里控制了。

--- a/drv/emac/mdrv_emac_v3.c
+++ b/drv/emac/mdrv_emac_v3.c
@@ -116,6 +116,10 @@
 #include <random.h>
 #include "mhal_rng_reg.h"
 #endif
+
+#include "mdrv_gpio.h"
+#include "mhal_gpio_reg.h"
+
 //-------------------------------------------------------------------------------------------------
 //  Data structure
 //-------------------------------------------------------------------------------------------------
@@ -1398,11 +1402,13 @@ static int MDev_EMAC_open (struct net_device *dev)
     {
         netif_carrier_off(dev);
         LocPtr->ThisBCE.connected = 0;
+        MDrv_GPIO_Set_High(PAD_GPIO9_PM);
     }
     else if(0 == ret)
     {
         netif_carrier_on(dev);
         LocPtr->ThisBCE.connected = 1;
+        MDrv_GPIO_Set_Low(PAD_GPIO9_PM);
     }
 
     return 0;
@@ -4759,6 +4765,7 @@ static void MDev_EMAC_timer_callback(unsigned long value)
         {
             LocPtr->ThisBCE.connected = 1;
             netif_carrier_on(emac_dev);
+            MDrv_GPIO_Set_Low(PAD_GPIO9_PM);
         }
 
         // Link status is latched, so read twice to get current value //
@@ -4776,6 +4783,7 @@ static void MDev_EMAC_timer_callback(unsigned long value)
         if(LocPtr->ThisBCE.connected) {
             LocPtr->ThisBCE.connected = 0;
             netif_carrier_off(emac_dev);
+            MDrv_GPIO_Set_High(PAD_GPIO9_PM);
         }
         // If disconnected is over 3 Sec, the real value of PHY's status register will report to application.
         if(time_count > CONFIG_DISCONNECT_DELAY_S*10) {
@@ -4788,6 +4796,7 @@ static void MDev_EMAC_timer_callback(unsigned long value)
             // Report to kernel.
             netif_carrier_off(emac_dev);
             LocPtr->ThisBCE.connected = 0;
+            MDrv_GPIO_Set_High(PAD_GPIO9_PM);
             // Normally, time out is set 1 Sec.
             LocPtr->Link_timer.expires = jiffies + EMAC_CHECK_LINK_TIME;
         }

网线接入时,emac 驱动会将/sys/class/net/eth0/carrier 节点就行刷新,netif_carrier_off 时为0 也即网线断开,netif_carrier_on 时为1 也即网线连着的,在对应状态控灯就可以了。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值