hi3520dv300 u-boot 网卡驱动移植

本文解决海思原厂提供的U-Boot网卡驱动存在的问题,针对LAN8710A网卡,通过修改驱动程序实现RGMII接口模式的支持。详细介绍了higmac_net_adjust_link和higmac_init函数的调整方法,确保网卡正确配置并正常工作。
部署运行你感兴趣的模型镜像

海思原厂提供的u-boot网卡驱动有问题,不能用,需要修改驱动程序。

网卡接口模式选择:

#define CONFIG_HIGMAC_PHY1_INTERFACE_MODE 2

模式为RGMII

网卡PHY地址:

#define CONFIG_HIGMAC_PHY1_ADDR 2

修改下面两个函数就可以了,主要是网卡的接口模式要是RGMII。

网卡型号:LAN8710A,需要通过网卡的SMI(Serial Management Interface)接口来配置网卡的PHY。

static int higmac_net_adjust_link(struct higmac_netdev_local *ld)
{
    char *mii_name = higmac_board_info[ld->index].mii_name;
    int phy_addr = higmac_board_info[ld->index].phy_addr;
    enum if_mode phy_mode = higmac_board_info[ld->index].phy_intf;
    int stat = 0, speed = 0, is_duplex_half = 1, port_mode, phy_duplex;
    enum speed_mode speed_mode;

    if (phy_addr == INVALID_PHY_ADDR)
        return stat;

    phy_fixup(mii_name, phy_addr, phy_mode);

    stat |= miiphy_link(mii_name, phy_addr) ? HIGMAC_LINKED : 0;

    phy_duplex = miiphy_duplex(mii_name, phy_addr);
    if (phy_duplex == FULL) {
        stat |= HIGMAC_DUP_FULL;
        is_duplex_half = 0;
    }

    speed = miiphy_speed(mii_name, phy_addr);
    switch (speed) {
    case _10BASET:
        stat |= HIGMAC_SPD_10M;
        speed_mode = speed_mode_10M;
        break;
    default:
        printf("wired, phy speed!\n");
    case _100BASET:
        stat |= HIGMAC_SPD_100M;
        speed_mode = speed_mode_100M;
        break;
    case _1000BASET:
        stat |= HIGMAC_SPD_1000M;
        speed_mode = speed_mode_1000M;
        break;
    }

    if (ld->link_stat != stat) {
        if (stat & HIGMAC_LINKED) {
            port_mode = calculate_port_mode(speed_mode,
                higmac_board_info[ld->index].phy_intf,
                is_duplex_half);
            //printf("port_mode:%#x\n",port_mode);
            //printf("ld->iobase:%#x\n",ld->iobase);
            port_mode |= 0x30;
            higmac_set_macif(ld, port_mode, speed_mode);

            if (is_duplex_half)
                higmac_writel(ld, 0x0, MAC_DUPLEX_HALF_CTRL);
            else
                higmac_writel(ld, 0x1, MAC_DUPLEX_HALF_CTRL);

        }
        ld->link_stat = stat;
    }

    return stat;
}

static int gmac_inited;
static int mdio_register;
static int higmac_init(void)
{
    int ret = 0;
    struct higmac_netdev_local *ld;
    int i;

    /* init once to save time */
    if (!gmac_inited) {
        gmac_inited = 1;
        higmac_sys_init();
        higmac_mdiobus_driver_init();

        if (!mdio_register) {
            mdio_register = 1;
            miiphy_register(mdio_bus[0], higmac0_mdio_read,
                    higmac0_mdio_write);

            if (CONFIG_GMAC_NUMS == 2) {
                miiphy_register(mdio_bus[1], higmac1_mdio_read,
                        higmac1_mdio_write);
            }
        }
#if 0
        /* disable PHY 1000M Mode */
        miiphy_write(higmac_board_info[0].mii_name,
                higmac_board_info[0].phy_addr, PHY_1000BTCR, 0);

        if (CONFIG_GMAC_NUMS == 2)
            miiphy_write(higmac_board_info[1].mii_name,
                    higmac_board_info[1].phy_addr,
                    PHY_1000BTCR, 0);
#endif
#if 1
    unsigned short value;
    unsigned int oui;
    unsigned char model;
    unsigned char rev;
    unsigned char PHY_ADDR;
    int j;
    char *phy_name = higmac_board_info[0].mii_name;

    for(j=2;j<32;j++)
    {
        if(miiphy_info (phy_name,j, &oui,&model, &rev) == 0)
        {
            //printf("PHY 0x%02X: ""OUI = 0x%04X, ""Model = 0x%02X, ""Rev = 0x%02X \n",j, oui,model, rev);
            if(oui == 0x1374)
            {
            //    writel(0xc14fc1cf, 0x20050100);
            //    writel(0xc14fdfcf, 0x20050100);

            #if 1
                PHY_ADDR = j;
                miiphy_write(phy_name,PHY_ADDR,PHY_BMCR,PHY_BMCR_RESET);
                udelay(1000);
                miiphy_read(phy_name,PHY_ADDR,PHY_BMCR,&value);
                value |= PHY_BMCR_AUTON;
                //value |=0x1140;
                miiphy_write(phy_name,PHY_ADDR,PHY_BMCR,value);
                udelay(1000);

                miiphy_read(phy_name,PHY_ADDR,PHY_ANAR,&value);
                value |= (PHY_ANLPAR_TXFD|PHY_ANLPAR_TX|PHY_ANLPAR_10FD|PHY_ANLPAR_10);
                miiphy_write(phy_name,PHY_ADDR,PHY_ANAR,value);
                udelay(1000);
                //printf("PHY_ANAR:%lx\n",value);
                miiphy_write(phy_name,PHY_ADDR,0x1d,0x05);
                miiphy_write(phy_name,PHY_ADDR,0x1e,0x0100);  
                //printf("CONFIG RGMII\n");
            #endif
            }
            else if(oui == 0x01f0)
            {
                //writel(0x1, 0x120f0138);
                //writel(0x1, 0x120f013c);
                //writel(0x1, 0x120f0140);
                /* SDK BUG */
                writel(0x3f, 0x1204008c);

            #if 1
                PHY_ADDR = j;
                //miiphy_write(phy_name,PHY_ADDR,PHY_BMCR,PHY_BMCR_RESET);
                    miiphy_reset(higmac_board_info[0].mii_name,
                higmac_board_info[0].phy_addr);
                udelay(1000);
                miiphy_read(phy_name,PHY_ADDR,PHY_BMCR,&value);
                value |= PHY_BMCR_AUTON;
                miiphy_write(phy_name,PHY_ADDR,PHY_BMCR,value);

                miiphy_read(phy_name,PHY_ADDR,PHY_ANAR,&value);
                value |= (PHY_ANLPAR_TXFD|PHY_ANLPAR_TX|PHY_ANLPAR_10FD|PHY_ANLPAR_10);
                miiphy_write(phy_name,PHY_ADDR,PHY_ANAR,value);
                udelay(1000);

                //printf("rgmii0_col = 0x%lx\n",readl(0x200f0000+0x1b8));
                miiphy_read(phy_name,PHY_ADDR,PHY_MIPGSR,&value);
                //printf("value = 0x%lx\n",value);    
                //printf("CONFIG MII\n");
            #endif
            }
            break;
        }
        
    }

    if(j == 32)
    {
        printf("NOFOUND PHY\n");
    }
#endif

#if 0
        miiphy_reset(higmac_board_info[0].mii_name,
                higmac_board_info[0].phy_addr);

        if (CONFIG_GMAC_NUMS == 2)
            miiphy_reset(higmac_board_info[1].mii_name,
                    higmac_board_info[1].phy_addr);
#endif
        for_each_gmac_netdev_local_priv(ld, i) {
            higmac_glb_preinit_dummy(ld);

            ret = higmac_set_hwq_depth(ld);
            if (ret) {
                printf("init eth%d hw desc depth fail!\n", i);
                goto glb_init;
            }

            ret = higmac_init_hw_desc_queue(ld);
            if (ret) {
                printf("init eth%d hw desc queue fail!\n", i);
                goto hw_desc_init;
            }
        }
    }

    ret = select_current_linked_phy();
    if (ret)
        goto mdiobus_init;

    higmac_desc_enable(current_ld,
            RX_OUTCFF_WR_DESC_ENA|RX_CFF_RD_DESC_ENA);
    higmac_writel_bits(current_ld, 1, PORT_EN, BITS_RX_EN);

    higmac_writel_bits(current_ld, 1, PORT_EN, BITS_TX_EN);
    higmac_desc_enable(current_ld,
            TX_OUTCFF_WR_DESC_ENA|TX_CFF_RD_DESC_ENA);

    return 0;

hw_desc_init:
glb_init:
    higmac_mdiobus_driver_exit();

mdiobus_init:
    higmac_sys_exit();

    return ret;
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

### 回答1: hi3516dv300是一款高性能的视频处理芯片,主要用于监控、安防、智能家居等领域。它采用了ARM Cortex-A7架构的CPU和高性能的图像处理模块,能够实现高清视频的编解码、图像处理和智能分析等功能。 u-boot是一个开源的引导加载程序,用于启动嵌入式系统。它负责初始化硬件、加载操作系统内核,并提供命令行界面来操作和控制系统。对于hi3516dv300芯片来说,u-boot也是必不可少的,它能够加载和启动操作系统,开发者可以通过u-boot来进行系统调试和修改。 bin文件是一种二进制文件格式,用于存储机器语言的指令和数据。在hi3516dv300中,u-boot bin文件是经过编译后生成的可执行文件,它包含了u-boot的所有代码和数据,可以直接烧写到芯片的闪存中,用于启动系统。 csdn是一个网络社区平台,提供了众多技术和学习资源。在csdn上可以找到和hi3516dv300芯片相关的资料和开发文档,可以与其他开发者进行交流和学习。对于开发者来说,csdn是一个宝贵的资源库,能够帮助他们更好地理解和应用hi3516dv300芯片。 ### 回答2: Hi3516DV300是一款由华为海思公司推出的嵌入式处理器,具有强大的图像处理和视频编解码功能。该处理器内置的U-boot是一种开源的引导加载程序,可用于启动操作系统并加载应用程序。 CSND是中国领先的IT技术社区,提供了广泛的技术交流和资源共享平台。在CSND上,你可以找到Hi3516DV300系列芯片的相关资料和技术文章,了解其技术特性、应用场景和开发方式等。 如果你想使用Hi3516DV300芯片,首先你需要获取它的U-boot二进制文件。这个二进制文件是预先编译好的,可以直接烧录到芯片中。U-boot在启动时会进行硬件初始化、加载操作系统内核,并提供命令行界面供用户进行配置和操作。 在CSND上,你可以找到一些Hi3516DV300 U-boot bin的相关资源下载链接。你可以根据自己的需求选择适合的版本进行下载,并按照相关文档进行烧录和配置。 总之,Hi3516DV300芯片和它的U-boot引导程序在CSND上都有相关资源可供参考和下载。希望这些信息能对你有所帮助。 ### 回答3: hi3516dv300是海思半导体推出的一款高性能视频处理芯片,可以广泛应用于监控摄像头、智能家居、工业视觉等领域。它具有低功耗、高性能、丰富的接口等特点,深受市场欢迎。 而U-boot是一种开源的引导加载程序,用于启动操作系统。它具有灵活的配置选项,可以适配多种不同的硬件平台和操作系统。 而.bin文件是二进制文件的一种格式,可以将程序代码编译成计算机可读的二进制形式。 优快云是中国最大的IT技术社区,提供丰富的技术文章和论坛交流平台,涵盖了计算机科学、软件开发、网络安全等众多领域。 因此,hi3516dv300 u-boot bin csdn可以理解为指的是使用hi3516dv300芯片,编译好的U-boot二进制文件,并在优快云上进行相关技术discussion和分享。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值