wifi底层学习之路:四,iw指令剖析

目录

一,iw应用层

二,cfg80211层

三,mac80211层

四,无线驱动层


本章以指令:iw dev wlan0 scan为例,带你走进iw层,cfg80211层,mac80211cfg,驱动层细节流程。

一,iw应用层

1,其实是两条命令
分析scan.c文件,跟踪TOPLEVEL(scan, "[-u] xx", 0, 0, CIB_NETDEV, handle_scan_combined, "xxx");
从handle_scan_combined()函数可知,最终运行下面两条指令。

iw dev wlan0 scan trigger 
对应的netlink消息:NL80211_CMD_TRIGGER_SCAN

iw dev wlan0 scan dump 
对应的netlink消息:NL80211_CMD_GET_SCAN

二,cfg80211层

1,netlink接收到 NL80211_CMD_TRIGGER_SCAN,执行下面函数

static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{
	//调用mac80211注册的cfg80211_ops对应的函数.scan
	rdev_scan(rdev, request);
	-->ret = rdev->ops->scan(&rdev->wiphy, request);  //mac80211实现
	//构造netlink消息,回复给iw
	nl80211_send_scan_start(rdev, wdev);
	-->nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	-->nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,NL80211_CMD_TRIGGER_SCAN) < 0)
	-->nl80211hdr_put(msg, portid, seq, flags, cmd);
	-->nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
	-->nl80211_add_scan_req(msg, rdev);
	-->genlmsg_end(msg, hdr);
	--genlmsg_multicast_netns()
}

2,netlink接收到 NL80211_CMD_GET_SCAN,执行下面函数

static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
{
	nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
	cfg80211_bss_expire(rdev);
	list_for_each_entry(scan, &rdev->bss_list, list) {
		nl80211_send_bss(skb, cb,cb->nlh->nlmsg_seq, NLM_F_MULTI,rdev, wdev, scan); //从bss段中取出数据
	}
}

三,mac80211层

1,从cfg80211层中,可知调用的是.scan函数

const struct cfg80211_ops mac80211_config_ops = {
    .add_virtual_intf = ieee80211_add_iface,
    .del_virtual_intf = ieee80211_del_iface,
    ....
    .scan = ieee80211_scan,
    .abort_scan = ieee80211_abort_scan,
    ....
};

static int ieee80211_scan(struct wiphy *wiphy,struct cfg80211_scan_request *req)
{
    ieee80211_request_scan(sdata, req);
	-->__ieee80211_start_scan(sdata, req);
	
	//软件扫描方式
	--->ieee80211_start_sw_scan(local, sdata);  
		---->drv_sw_scan_start(local, sdata, local->scan_addr);
		------->local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); //ath9k实现
	
    //延时调用ieee80211_scan_work,调用前需要初始化
    ---->ieee80211_queue_delayed_work(&local->hw,&local->scan_work, 0);	

    //local->scan_work()的实现如下
    local->scan_work
    -->ieee80211_scan_work()
    --->__ieee80211_scan_completed()
    ---->drv_sw_scan_complete()
    ----->.sw_scan_complete//ath9k实现
}

2,延时调用ieee80211_scan_work()的初始化过程在ieee80211_alloc_hw_nm()函数

struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
					   const struct ieee80211_ops *ops,
					   const char *requested_name)
{
    INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);	
    // 这里使用的是INIT_DELAYED_WORK()那么之后
    // 我们就会调用schedule_delayed_work(),这两是一对
    // 表示经过一段延时然后在执行某个函数。
}
EXPORT_SYMBOL(ieee80211_alloc_hw_nm);

//以下是ieee80211_scan_work()的实现细节
void ieee80211_scan_work(struct work_struct *work)
{
	__ieee80211_scan_completed(&local->hw, aborted);
}

static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{
	drv_sw_scan_complete(local, scan_sdata);
}

static inline void drv_sw_scan_complete(struct ieee80211_local *local,
					struct ieee80211_sub_if_data *sdata)
{
	local->ops->sw_scan_complete(&local->hw, &sdata->vif);
}

void ieee80211_scan_work(struct work_struct *work)
{
	__ieee80211_scan_completed(&local->hw, aborted);
}

static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{
	drv_sw_scan_complete(local, scan_sdata);
}

static inline void drv_sw_scan_complete(struct ieee80211_local *local,
					struct ieee80211_sub_if_data *sdata)
{
	local->ops->sw_scan_complete(&local->hw, &sdata->vif);
}

四,无线驱动层

1,从mac80211层可知,调用的是.sw_scan_start()和.sw_scan_complete()函数

struct ieee80211_ops ath9k_htc_ops = {
	.tx                 = ath9k_htc_tx,
	.start              = ath9k_htc_start,
	.stop               = ath9k_htc_stop,
	.add_interface      = ath9k_htc_add_interface,
	....
	.sw_scan_start      = ath9k_htc_sw_scan_start,
	.sw_scan_complete   = ath9k_htc_sw_scan_complete,
	....
};

欢迎订阅公众号【从零开始学无线】,一起学习交流!

                                                                

<think>嗯,用户想了解Android 14的Wi-Fi移植,可能需要将新的Wi-Fi功能或驱动适配到旧设备上。首先,我得回忆一下Android系统架构里Wi-Fi子系统的大致结构,比如WPA supplicant、HAL层、内核驱动这些部分。移植的话,可能需要处理不同硬件之间的兼容性问题,特别是不同厂商的芯片可能需要不同的驱动。 用户可能是开发者或者硬件厂商的人,需要将Android 14的新特性移植到他们的设备上。可能遇到的问题包括内核版本差异、HAL接口变化,或者新的安全要求。比如Android 14可能引入了新的Wi-Fi API或者加强了权限控制,这会影响现有的驱动和中间层。 接下来,我应该分步骤解释移植流程,比如环境准备、代码获取、配置适配、编译调试等。需要提到AOSP源码的获取,内核配置,HAL层的实现,可能还要处理SeLinux策略,以及测试验证的步骤。用户可能还关心常见问题,比如驱动不兼容、HAL接口不匹配,或者性能问题,这时候需要给出排查建议,比如日志分析、内核配置检查等。 另外,要确保回答符合用户的要求,使用中文,结构清晰,LaTeX公式正确。不过Wi-Fi移植可能涉及代码和系统配置,不太需要数学公式,但如果有参数配置可能需要用行内公式,比如频率范围$2.4\text{GHz}$之类的。不过根据用户的问题,可能用不上太多数学表达式,但需要注意系统指令里的格式要求,确保所有技术术语和代码部分正确标注。</think>关于Android 14的Wi-Fi移植,这是一个涉及底层驱动适配和系统框架整合的复杂过程。以下是分步骤的技术说明: 一、Wi-Fi子系统架构 Android的Wi-Fi子系统包含以下层级: $$ \text{应用层} \rightarrow \text{框架层(WifiManager)} \rightarrow \text{HAL层} \rightarrow \text{内核驱动} $$ 其中关键组件包括$wpa\_supplicant$和$hostapd$等守护进程 二、移植核心步骤 1. **内核驱动适配** - 确保内核版本符合Android 14最低要求(通常≥5.10) - 移植目标Wi-Fi芯片的驱动模块(如$ath9k$, $mt76$等) - 验证DTS配置中的总线接口: ```dts &pcie { wifi@0 { compatible = "qcom,ath11k"; reg = <0 0 0 0>; }; } ``` 2. **HAL层实现** - 实现`android.hardware.wifi@1.x`系列接口 - 适配新的`IWifiChip`接口(Android 14新增特性) - 示例HIDL接口定义: ```cpp interface IWifiChip { getCapabilities(...) generates (WifiStatus status, bitfield<ChipCapabilityMask> capabilities); }; ``` 3. **框架层适配** - 同步AOSP中`frameworks/opt/net/wifi`的最新修改 - 处理新的权限模型(Android 14强化了$NEARBY_WIFI_DEVICES$权限) - 适配Wi-Fi感知(Aware)相关API变更 三、配置与调试 1. **Makefile配置** ```makefile PRODUCT_PACKAGES += \ wpa_supplicant \ hostapd \ wificond \ android.hardware.wifi@1.0-service ``` 2. **SELinux策略** ```te allow wpa_supplicant system_data_file:dir { search }; allow hal_wifi_default system_prop:property_service set; ``` 3. **调试命令** ```bash adb shell dumpsys wifi | grep "Current state" adb logcat | grep -E &#39;WifiStateMachine|WifiNative&#39; ``` 、常见问题处理 1. **驱动加载失败** - 检查内核日志:`dmesg | grep -i wifi` - 验证DMA内存配置是否符合芯片要求 2. **HAL接口不匹配** - 使用`lshal`命令验证HAL服务注册 - 确保HIDL版本与框架层要求的$major.minor$版本一致 3. **功耗异常** - 优化电源管理策略:`iw dev wlan0 set power_save on` - 验证wake_lock的持有时间 五、性能优化建议 - 启用Wi-Fi 6特性需同时更新$cfg80211$和$mac80211$组件 - 调整QoS参数满足低延迟需求: $$ \text{EDCA参数} = [aifsn=2, cw_min=3, cw_max=7, txop=300] $$ - 使用Wireshark分析802.11帧结构时注意解密设置 建议在实际移植时,先基于对应芯片厂商的BSP基础进行适配,再逐步集成Android 14的新特性。官方AOSP文档中`development/pdk/docs/wifi_porting.md`提供了详细指引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值