Linux内核(十一)WiFi MAC地址获取流程

本文详细讲解了在Linux系统中,如何通过dhd_register_if、netdev_register_kobject等流程实现WIFI设备的注册,并获取其MAC地址的过程。涉及的关键函数和模块包括dhd_linux.c、sysfs、eth/wlan节点的生成,以及MAC地址读取与格式化的方法。

platform:RK
OS:Linux
Kernel: 4.4.143

用户空间查看MAC地址:
/sys/class/net/wlan0/address

WIFI如何注册并生成address文件?
net目录下的节点如eth/wlan生成都是通过网络设备注册生成的,以下是WiFi注册流程:

dhd_register_if  -> dhd_linux.c
	register_netdev -> dev.c
		register_netdevice  -> 
			netdev_register_kobject  -> net-sysfs.c
				dev->class = &net_class;      //eth/wlan对应net的“net_class”
				device_add(dev);              //生成address文件

注册后 /sys/class/net/wlan0/address 就生成了。

WIFI MAC address如何获取?

打开/sys/class/net/wlan0/address调用 函数address_show -> net-sysfs.c

static ssize_t address_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct net_device *ndev = to_net_dev(dev);
	ssize_t ret = -EINVAL;

	read_lock(&dev_base_lock);
	if (dev_isalive(ndev))       //数据从net->dev_addr获取
		ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len);
	read_unlock(&dev_base_lock);

	return ret;
}

net->dev_addr的值如何获取?

函数dhd_register_if    -> dhd_linux.c
if (ifidx == 0) {
	if (!ETHER_ISNULLADDR(dhd->pub.mac.octet))
	{
		memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
	} else {
	........
	}
}
memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);

pub.mac.octet值如何获取?
系统开机初始化有两处地方会去读取MAC地址。

第一种
dhdsdio_probe -> dhd_sdio.c
	dhd_attach -> dhd_linux.c
	  wifi_platform_get_mac_addr(dhd->adapter, dhd->pub.mac.octet);  
		plat_data->get_mac_addr ->bcm_wlan_set_plat_data()中定义
		  bcm_wlan_get_mac_address 
			rockchip_wifi_mac_addr -> dhd_gpio.c

int rockchip_wifi_mac_addr(unsigned char *buf)
{
	......
    if(is_zero_ether_addr(wifi_custom_mac_addr)) {
        int i;
        char *tempBuf = kmalloc(512, GFP_KERNEL);
        if(tempBuf) {            //如果在IDB模块有自定义写入地址的话就能获取成功
            GetSNSectorInfo(tempBuf);
            for (i = 445; i <= 450; i++)
                wifi_custom_mac_addr[i-445] = tempBuf[i];
            kfree(tempBuf);
        } else {
            return -1;
        }
    }
	//否则就是空
    memcpy(buf, wifi_custom_mac_addr, 6);
    return 0;
}
第二种
dhd_open -> dhd_linux.c
	wl_android_wifi_on ->
		dhd_dev_init_ioctl ->
			dhd_sync_with_dongle ->
				dhd_preinit_ioctls

int dhd_preinit_ioctls(dhd_pub_t *dhd) {
	.......
	ret = wifi_platform_get_mac_addr(dhd->info->adapter, ea_addr.octet);     -> dhd_linux_platdev.c   	
	plat_data = adapter->wifi_plat_data 	
	if (plat_data->get_mac_addr) {        
		return plat_data->get_mac_addr(buf);	
	}
	memcpy(dhd->mac.octet, ea_addr.octet, ETHER_ADDR_LEN);
	......
}

plat_data->get_mac_addr(buf);    						-> dhd_linux_platdev.c 
struct wifi_platform_data dhd_wlan_control = {			-> dhd_gpio.c
 	.......
	.get_mac_addr	= dhd_wlan_get_mac_addr,
	......
};

rockchip_wifi_mac_addr                  -> rfkill-wlan.c
int rockchip_wifi_mac_addr(unsigned char *buf) {
	// 从供应商的存储中获取
	if (is_zero_ether_addr(wifi_custom_mac_addr)) {
		if (get_wifi_addr_vendor(wifi_custom_mac_addr) != 0)
			return -1;
	}
	memcpy(buf, wifi_custom_mac_addr, 6);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bazinga bingo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值