RfKill
内核使用 rfkill 模块管理无线设备,rfkill 提供两种类型的用户态接口用于查询和控制无线设备:
1. /dev/rfkill
这是一个标准的 I/O 设备,可以使用标准的 open(), close() ioctl() 等操作查询和控制每个无线设备的状态,相关的头文件 /usr/include/linux/rfkill.h
2. /sys/class/rfkill/
每个 rfkill 设备会在 sysfs 中创建自己的一个节点,都有下面文件:
- name : 接口或驱动名称,注册 rfkill 设备时指定。
- type : 设备类型, wlan | bluethooth …
- persistent : 从外存谋取的软限制状态
- state : 当前的无线设备状态
- 0 : RFKILL_STATE_SOFT_BLOCKED 被软件关闭
- 1 : RFKILL_STATE_UNBLOCKED 开启
- 2 : RFKILL_STATE_HARD_BLOCKED 被硬件驱动关闭
设备禁用类型
- 软件禁用,由用户态应用程序触发,并通过 rfkill 接口关闭无线设备。
- 硬件驱动禁用,由内核硬件驱动程序触发的关闭,硬件驱动程序(平台驱动)调用 rfkill 接口通知硬件被关闭。
平台驱动中的 rfkill 相关部分
// 状态设备 static int ls3a_rfkill_set(void * data, bool blocked) { // 调用 EC 设备无线设备状态 ... } // 状态查询 static void ls3a_rfkill_query(struct rfkill * rfkill, void * data) { // 调用 EC 设备查询无线设备的状态 ... rfkill_set_sw_state(rfkill, state_soft); // 设置 soft state rfkill_set_hw_state(rfkill, state_hard); // 设备 hard state } // rfkill 操作函数 static const struct rfkill_ops ls3a_rfkill_ops = { .set_block = ls3a_rfkill_set, .query = ls3a_rfkill_query, }; static int __init ls3a_setup_rfkill(void) { // wifi wifi_rfkill = rfkill_alloc("ls3a-wifi", ...); ... rfkill_register(wifi_rfkill); // bluetooth bluetooth_rfkill = rfkill_alloc("ls3a-bluetooth", ...); ... rfkill_register(bluetooth_rfkill); // wwan wwan_rfkill = rfkill_alloc("ls3a-wwan", ...); ... rfkill_register(wwan_rfkill); } static void ls3a_cleanup_rfkill(void) { // wifi rfkill_unregsiter(wifi_rfkill); rfkill_destroy(wifi_rfkill); // bluetooth rfkill_unregsiter(bluetooth_rfkill); rfkill_destroy(bluetooth_rfkill); // wwan rfkill_unregsiter(wwan_rfkill); rfkill_destroy(wwan_rfkill); } static int __init ls3a_init(void) { // 注册平台驱动和其它设备初始化 platform_device = platform_driver_register(&platform_driver); ... // 设置 rfkill 设备 ls3a_setup_rfkill(); ... return 0; } static void __exit ls3a_exit(void) { // 注销平台设备和其它设备 ... // 清除 rfkill 设备 ls3a_cleanup_rfkill(); } module_init(ls3a_init); module_exit(ls3a_exit); |
Over!
mark了