文章目录
平台: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(ðaddr[i * ARP_HLEN])) {
- if (!randomed) {
- net_random_ethaddr(ðaddr[i * ARP_HLEN]);
- randomed = true;
- } else {
- if (i > 0) {
- memcpy(ðaddr[i * ARP_HLEN],
- ðaddr[(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(ðaddr[i * ARP_HLEN])) {
+ if (!randomed) {
+ net_random_ethaddr(ðaddr[i * ARP_HLEN]);
+ randomed = true;
+ } else {
+ if (i > 0) {
+ memcpy(ðaddr[i * ARP_HLEN],
+ ðaddr[(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(ðaddr[i * ARP_HLEN])) {
+ sprintf(buf, "%pM", ðaddr[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(ðaddr[i * ARP_HLEN])) {
- sprintf(buf, "%pM", ðaddr[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) {