[ Linux RK Debian10 ] 网口RTL8152 MAC地址调试


平台:Linux
内核版本:Linux version 4.19.193
网卡芯片:RTL8152


Uboot更改MAC地址

方案一:添加 #defined CONFIG_ENV_OVERWRITE到板子的配置文件,可以解决MAC只读不能写的问题

文档查看 vi uboot/REDME查看具体解释

方案二:使用RKDevInfoWriteTool工具烧写,解决MAC只读不能写的问题

设置MAC地址软件:
RK - 读写Vendor Storage区域工具
烧写软件特点:
1、软件根据ID 号写到Vendor Storage区域,具体ID分配。参考ID号设置arch\arm\include\asm\arch\vendor.h
在这里插入图片描述
2、一个ID号可以输入36个字节,一个MAC地址是12字节(最多2个MAC),这里演示设置一个地址
3、软件写入MAC地址,Vendor Storage区域只能设置不能擦除

RKDevInfo Write Tool软件使用
在这里插入图片描述
在这里插入图片描述
修改UBOOT:MAC地址、读取、分配(分配4个ID地址,16-20)
路径:arch/arm/mach-rockchip/board.c

diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
old mode 100644
new mode 100755
index 8929b0f..98f8aff
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -87,52 +87,54 @@ __weak int rk_board_init(void)
 #define CPUID_LEN      0x10
 #define CPUID_OFF      0x07

-#define MAX_ETHERNET   0x2
+#define MAX_ETHERNET   0x1

 static int rockchip_set_ethaddr(void)
 {
 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
        char buf[ARP_HLEN_ASCII + 1], mac[16];
        u8 ethaddr[ARP_HLEN * MAX_ETHERNET] = {0};
-       int ret, i;
+       int ret, i,m;
        bool need_write = false, randomed = false;
-
-       ret = vendor_storage_read(LAN_MAC_ID, ethaddr, sizeof(ethaddr));
-       for (i = 0; i < MAX_ETHERNET; i++) {
-               if (ret <= 0 || !is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
-                       if (!randomed) {
-                               net_random_ethaddr(&ethaddr[i * ARP_HLEN]);
-                               randomed = true;
-                       } else {
-                               if (i > 0) {
-                                       memcpy(&ethaddr[i * ARP_HLEN],
-                                              &ethaddr[(i - 1) * ARP_HLEN],
-                                              ARP_HLEN);
-                                       ethaddr[i * ARP_HLEN] |= 0x02;
-                                       ethaddr[i * ARP_HLEN] += (i << 2);
+
+       for(m=16; m < 20; m++){
+               ret = vendor_storage_read(m, ethaddr, sizeof(ethaddr));
+               for (i = 0; i < MAX_ETHERNET; i++) {
+                       if (ret <= 0 || !is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
+                               if (!randomed) {
+                                       net_random_ethaddr(&ethaddr[i * ARP_HLEN]);
+                                       randomed = true;
+                               } else {
+                                       if (i > 0) {
+                                               memcpy(&ethaddr[i * ARP_HLEN],
+                                                      &ethaddr[(i - 1) * ARP_HLEN],
+                                                      ARP_HLEN);
+                                               ethaddr[i * ARP_HLEN] |= 0x02;
+                                               ethaddr[i * ARP_HLEN] += (i << 2);
+                                       }
                                }
+
+                               need_write = true;
                        }

-                       need_write = true;
+                       if (is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
+                               sprintf(buf, "%pM", &ethaddr[i * ARP_HLEN]);
+                               if (m == 16)
+                                       memcpy(mac, "ethaddr", sizeof("ethaddr"));
+                               else
+                                       sprintf(mac, "eth%daddr", m-16);
+                               env_set(mac, buf);
+                       }
                }

-               if (is_valid_ethaddr(&ethaddr[i * ARP_HLEN])) {
-                       sprintf(buf, "%pM", &ethaddr[i * ARP_HLEN]);
-                       if (i == 0)
-                               memcpy(mac, "ethaddr", sizeof("ethaddr"));
-                       else
-                               sprintf(mac, "eth%daddr", i);
-                       env_set(mac, buf);
+               if (need_write) {
+                       ret = vendor_storage_write(LAN_MAC_ID,
+                                                  ethaddr, sizeof(ethaddr));
+                       if (ret < 0)
+                               printf("%s: vendor_storage_write failed %d\n",
+                                      __func__, ret);
                }
        }
-
-       if (need_write) {
-               ret = vendor_storage_write(LAN_MAC_ID,
-                                          ethaddr, sizeof(ethaddr));
-               if (ret < 0)
-                       printf("%s: vendor_storage_write failed %d\n",
-                              __func__, ret);
-       }
 #endif

        return 0;
}

Kernel获取并设置MAC地址

UBOOT将ethaddr转化为local-mac-address
//common\fdt_support.c
fdt_fixup_ethernet
    fdt_path_offset(fdt, "/aliases") //寻找设备树根节点 如下图
    if (!strncmp(name, "ethernet", 8))  //对比ethernet 如下图ethernet0
    sprintf(mac, "eth%daddr", i);//将eth%daddr的值传入mac
    do_fixup_by_path(fdt, path, "local-mac-address",
                     &mac_addr, 6, 1); //建立local-mac-address节点供内核查找

在这里插入图片描述

设备树修改

所以只需要多添加ethernet即可

/{	
	aliases {
	    ethernet = &rtl8152;
	};
	
	rtl8152: rtl8152 {
	    local-mac-address = [01 02 03 04 05 05];
	};
};

查看local-mac-address 是否识别成功

cd /sys/firmware/devicetree/base/rtl8152
cat local-mac-address #先查看是否有local-mac-address字段

修改rtl8152驱动

路径:drivers/net/usb/r8152.c
方法一

//头文件
#include <linux/of_net.h>

//修改函数
static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa)
{
	struct net_device *dev = tp->netdev;
	int ret;
+	unsigned char mac[ETH_ALEN];
+	char rtl8152_name[256] = "rtl8152";
+	const char *mac_p=NULL;
+	struct device_node* np;


	sa->sa_family = dev->type;

	if (tp->version == RTL_VER_01) {
		ret = pla_ocp_read(tp, PLA_IDR, 8, sa->sa_data);
	} else {
		/* if device doesn't support MAC pass through this will
		 * be expected to be non-zero
		 */
		ret = vendor_mac_passthru_addr_read(tp, sa);
		if (ret < 0)
			ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa->sa_data);
	}

+	np = of_find_node_by_name(NULL, rtl8152_name);
+	if(np){
+	    mac_p = of_get_mac_address(np);
+	}

+	if (is_valid_ether_addr(mac)) {
+	    memcpy(sa->sa_data, mac_p, ETH_ALEN);
+	    return 0;
+	}

	if (ret < 0) {
		netif_err(tp, probe, dev, "Get ether addr fail\n");
	} else if (!is_valid_ether_addr(sa->sa_data)) {
		netif_err(tp, probe, dev, "Invalid ether addr %pM\n",
			  sa->sa_data);
		eth_hw_addr_random(dev);
		ether_addr_copy(sa->sa_data, dev->dev_addr);
		netif_info(tp, probe, dev, "Random ether addr %pM\n",
			   sa->sa_data);
		return 0;
	}
	return ret; 
}

方法二 (参考dm9621修改)

//头文件
#include <linux/of_net.h>

//添加函数
static void dm9621_get_mac(struct usbnet *dev, unsigned char *addr) 
{
    unsigned char mac[ETH_ALEN];
    char dm9621_name[256] = "dm9601";
    const char *mac_p;
    struct device_node* np;
    
    np = of_find_node_by_name(NULL, dm9621_name);
    if(np){
        mac_p = of_get_mac_address(np);
    }

    if (is_valid_ether_addr(mac)) {
        memcpy(addr, mac_p, ETH_ALEN);
        return;
    }

    eth_random_addr(mac); //为生成随机mac地址
    memcpy(addr, mac, ETH_ALEN);
}

网口状态灯配置

问题:网口灯一个亮,一个不亮;原因:phy芯片配置灯的寄存器错误
修改文件:drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c

--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c

@@ -5333,7 +5333,7 @@ static void r8152b_init(struct r8152 *tp)
                data &= ~BMCR_PDOWN;
                r8152_mdio_write(tp, MII_BMCR, data);
        }
+      ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, 0x0C2A);
        r8152_aldps_en(tp, false);

        if (tp->version == RTL_VER_01) {
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bazinga bingo

您的鼓励就是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值