以太网mac地址

以太网mac地址

dwmac-rk.c

static int rk_gmac_probe(struct platform_device *pdev)
{
		plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);  // 刷机第一次 由uboot env 传入 
		plat_dat->get_eth_addr = rk_get_eth_addr;  //判断是否有mac ,是否需要从vendor获取  
		......
		ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
		if (ret)
			goto err_gmac_powerdown;
}

stmmac_main.c

int stmmac_dvr_probe(struct device *device,
		     struct plat_stmmacenet_data *plat_dat,
		     struct stmmac_resources *res)
{
	if (res->mac)
		memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
	pr_info("%s aaaaaaaaaaaa: device MAC address %pM\n", priv->dev->name,priv->dev->dev_addr);
	dev_set_drvdata(device, priv->dev);
	.....
	stmmac_check_ether_addr(priv);
....
}
/**
 * stmmac_check_ether_addr - check if the MAC addr is valid
 * @priv: driver private structure
 * Description:
 * it is to verify if the MAC address is valid, in case of failures it
 * generates a random MAC address
 */
static void stmmac_check_ether_addr(struct stmmac_priv *priv)
{
	printk("%s\n\n\n ",__func__);
	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
		priv->hw->mac->get_umac_addr(priv->hw,
					     priv->dev->dev_addr, 0);
	     pr_info("%s:000000000000  device MAC address %pM\n", priv->dev->name,
			priv->dev->dev_addr);
			
		if (likely(priv->plat->get_eth_addr))
			priv->plat->get_eth_addr(priv->plat->bsp_priv,
				priv->dev->dev_addr);
				
		if (!is_valid_ether_addr(priv->dev->dev_addr))
			eth_hw_addr_random(priv->dev);
			
		pr_info("%s: device MAC address %pM\n", priv->dev->name,
			priv->dev->dev_addr);
	}
	pr_info("%s 222222222222: device MAC address %pM\n", priv->dev->name,priv->dev->dev_addr);
}

以下是分成这两条支线解析

stmmac_platform.c

struct plat_stmmacenet_data *stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
{
		*mac = of_get_mac_address(np);
	 	....
	}
static const void *of_get_mac_addr(struct device_node *np, const char *name)
{
	struct property *pp = of_find_property(np, name, NULL);

	if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)){
		printk("%s : device pp MAC address %pM	\n\n",__func__,pp->value);
		return pp->value;
		}
	return NULL;
}

/**
 * Search the device tree for the best MAC address to use.  'mac-address' is
 * checked first, because that is supposed to contain to "most recent" MAC
 * address. If that isn't set, then 'local-mac-address' is checked next,
 * because that is the default address.  If that isn't set, then the obsolete
 * 'address' is checked, just in case we're using an old device tree.
 *
 * Note that the 'address' property is supposed to contain a virtual address of
 * the register set, but some DTS files have redefined that property to be the
 * MAC address.
 *
 * All-zero MAC addresses are rejected, because those could be properties that
 * exist in the device tree, but were not set by U-Boot.  For example, the
 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
 * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
 * but is all zeros.
*/
const void *of_get_mac_address(struct device_node *np)
{
	const void *addr;

	addr = of_get_mac_addr(np, "mac-address");
		printk("%s : device mac-address %pM	\n\n",__func__,addr);
	if (addr)
		return addr;

	addr = of_get_mac_addr(np, "local-mac-address");		***//由uboot传入 dts找不到这个node***
			printk("%s : device local-mac-address %pM	\n\n",__func__,addr);
	if (addr)
		return addr;

	return of_get_mac_addr(np, "address");
}
EXPORT_SYMBOL(of_get_mac_address);

Uboot 代码:
/Project1/rk3399pro/u-boot/common/fdt_support.c

void fdt_fixup_ethernet(void *fdt)
{
	int i = 0, j, prop;
	char *tmp, *end;
	char mac[16];
	const char *path;
	unsigned char mac_addr[ARP_HLEN];
	int offset;
#ifdef FDT_SEQ_MACADDR_FROM_ENV
	int nodeoff;
	const struct fdt_property *fdt_prop;
#endif

	if (fdt_path_offset(fdt, "/aliases") < 0)
		return;

	/* Cycle through all aliases */
	for (prop = 0; ; prop++) {
		const char *name;

		/* FDT might have been edited, recompute the offset */
		offset = fdt_first_property_offset(fdt,
			fdt_path_offset(fdt, "/aliases"));
		/* Select property number 'prop' */
		for (j = 0; j < prop; j++)
			offset = fdt_next_property_offset(fdt, offset);

		if (offset < 0)
			break;

		path = fdt_getprop_by_offset(fdt, offset, &name, NULL);
		if (!strncmp(name, "ethernet", 8)) {
			/* Treat plain "ethernet" same as "ethernet0". */
			if (!strcmp(name, "ethernet")
#ifdef FDT_SEQ_MACADDR_FROM_ENV
			 || !strcmp(name, "ethernet0")
#endif
			)
				i = 0;
#ifndef FDT_SEQ_MACADDR_FROM_ENV
			else
				i = trailing_strtol(name);
#endif
			if (i != -1) {
				if (i == 0)
					strcpy(mac, "ethaddr");
				else
					sprintf(mac, "eth%daddr", i);
			} else {
				continue;
			}
#ifdef FDT_SEQ_MACADDR_FROM_ENV
			nodeoff = fdt_path_offset(fdt, path);
			fdt_prop = fdt_get_property(fdt, nodeoff, "status",
						    NULL);
			if (fdt_prop && !strcmp(fdt_prop->data, "disabled"))
				continue;
			i++;
#endif
			tmp = env_get(mac);
			if (!tmp)
				continue;

			printf("%s 222222222222: device MAC address %pM\n",__func__, tmp);

			for (j = 0; j < 6; j++) {
				mac_addr[j] = tmp ?
					      simple_strtoul(tmp, &end, 16) : 0; //将获到的env char 转成16进制
				if (tmp)
					tmp = (*end) ? end + 1 : end;
			}

			do_fixup_by_path(fdt, path, "mac-address",
					 &mac_addr, 6, 0);
			do_fixup_by_path(fdt, path, "local-mac-address",
					 &mac_addr, 6, 1);
 			printf("%s 222222222222: device MAC address %pM\n",__func__, mac_addr);
		}

==============================================================================================================
第二方式,从vendor获取的方法:
dwmac-rk.c


void rk_get_eth_addr(void *priv, unsigned char *addr)
{
	int ret;
	struct rk_priv_data *bsp_priv = priv;
	struct device *dev = &bsp_priv->pdev->dev;
	printk("%s \n\n",__func__);
	rk_devinfo_get_eth_mac(addr);
	if (is_valid_ether_addr(addr))
		goto out;
		
	ret = rk_vendor_read(LAN_MAC_ID, addr, 6); //LAN_MAC_ID 3
	if (ret != 6 || is_zero_ether_addr(addr)) {
		dev_err(dev, "%s: rk_vendor_read eth mac address failed (%d)",
					__func__, ret);
		random_ether_addr(addr);	 //随机产生一个mac地址
		dev_err(dev, "%s: generate random eth mac address: %02x:%02x:%02x:%02x:%02x:%02x",__func__, addr[0], addr[1], addr[2],
					addr[3], addr[4], addr[5]);
		ret = rk_vendor_write(LAN_MAC_ID, addr, 6);
		if (ret != 0)
			dev_err(dev, "%s: rk_vendor_write eth mac address failed (%d)",__func__, ret);
	}
	printk( "%s: generate random eth mac address: %02x:%02x:%02x:%02x:%02x:%02x	\n\n",__func__, addr[0], addr[1], addr[2],
					addr[3], addr[4], addr[5]);
out:
	dev_err(dev, "%s: mac address: %02x:%02x:%02x:%02x:%02x:%02x",__func__, addr[0], addr[1], addr[2],
				addr[3], addr[4], addr[5]);
}
### 不同操作系统中获取以太网MAC地址的方法 #### Windows 操作系统中的方法 在Windows操作系统下,可以通过`arp`命令来查看本地缓存的IP地址MAC地址之间的映射关系。具体操作是在命令提示符窗口输入`arp -a`并按回车键执行[^1]。 对于更直接的方式,则可以利用`getmac`工具,在命令行界面运行`getmac /v /fo list`能够显示所有适配器及其对应的物理地址(即MAC地址),并且提供详细的输出格式以便于阅读和处理[^3]。 ```powershell Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.MacAddress} | Select-Object MacAddress ``` 上述PowerShell脚本同样适用于检索当前系统的各个网络接口所关联的MAC地址信息。 #### Linux 操作系统中的方法 Linux环境下,最常用的是借助`ifconfig`指令或是更为现代的`ip link show`命令来查询指定网络设备的硬件地址: ```bash ifconfig eth0 ``` 这条语句将返回有关名为`eth0`的以太网卡的信息,其中包括其MAC地址;而采用`ip`系列的新式语法则是这样的形式: ```bash ip link show eth0 ``` 这两种途径均能有效地展示目标网口的具体参数列表,其中就包含了所需的MAC标识码。 另外一种情况涉及到安卓平台上的特殊需求——当面对启用了SELinux安全增强机制且处于强制执行(enforcing)状态下的Android 11.0版本时,如果想要访问位于文件系统路径`/sys/class/net/eth0/address`处记录着的以太网MAC地址,则可能因为权限不足而导致失败。此时就需要调整策略配置,给予应用程序适当的操作许可才能顺利完成读取动作[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不负时光年华

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值