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

被折叠的 条评论
为什么被折叠?



