前言
前面以一些基本的WIFI操作为例子,讲解了上层的一些流程调用,这篇开始讲讲底层驱动的一些基本流程。包括驱动是如何初始化的,以及STR相关的驱动处理等。
一、CNSS2驱动简介
先从串口看一下编译出来的模块,在/vendor_dlkm/lib/modules
路径下,可以看到以下相关ko模块:
-rw-r--r-- 1 root root 4414544 2009-01-01 00:00 cnss2.ko
...
-rw-r--r-- 1 root root 328085816 2009-01-01 00:00 qca_cld3_qca6390.ko
-rw-r--r-- 1 root root 392532288 2009-01-01 00:00 qca_cld3_qca6490.ko
-rw-r--r-- 1 root root 259933344 2009-01-01 00:00 qca_cld3_qcn7605.ko
通过lsmod
命令也可以看到如下内容:
qca6490 10862592 0
cnss2 356352 1 qca6490
不难看出,编译出来的文件主要是cnss2
模块以及qca
不同型号对应的模块,实际会根据具体芯片加载具体的qca
驱动。
比如qca6490
就是硬件对应使用的驱动,那么cnss2
后面信息是记载的used by
内容,也就是cnss2
是被qca6490
所使用的。
因此从上面信息可以看出来cnss
应该是qca
驱动的一个子模块,或者子系统。
为了更好的理解,再来看看官方的解释:
CNSS2为qcom的wlan驱动(qca)的一个子系统。驱动程序旨在将 PCIe 驱动程序打包,并在主机设备驱动程序级别中添加特殊的 Qualcomm WLAN 驱动程序功能,这在常见的 Linux 内核设备驱动程序中是不包含的。
CNSS2 是连接子系统软件 (CNSS) 的第二个版本,用于支持 qcacld3.0 主机驱动程序。
cnss2(Connectivity Subsystem driver 2.0)从他的名字来看,就是用于连接的子系统一个驱动。因为网卡芯片的接口不同,比如常见的PCIe,还有一些使用的是SDIO接口,也有使用USB接口的网卡。不同的接口意味着对应的处理也不同,那么作为网络驱动,Qcom将共通的部分作为主驱动,即qca
,而对于不同接口以及不同芯片的处理剥离出来作为其子系统,即cnss
。
这样针对不同的芯片,不同的接口在处理上的差分我们就只需要关注cnss驱动即可。
二、QCA_CLD驱动简介
qcacld
作为网络设备主驱动,那么通常网络设备需要注册的网络接口等都是在这里操作的,以及数据的发送和接收。
static const struct net_device_ops wlan_drv_ops = {
.ndo_open = hdd_open,
.ndo_stop = hdd_stop,
.ndo_uninit = hdd_uninit,
.ndo_start_xmit = hdd_hard_start_xmit,
.ndo_fix_features = hdd_fix_features,
.ndo_set_features = hdd_set_features,
.ndo_tx_timeout = hdd_tx_timeout,
.ndo_get_stats = hdd_get_stats,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
.ndo_do_ioctl = hdd_ioctl,
#endif
.ndo_set_mac_address = hdd_set_mac_address,
.ndo_select_queue = hdd_select_queue,
.ndo_set_rx_mode = hdd_set_multicast_list,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
.ndo_siocdevprivate = hdd_dev_private_ioctl,
#endif
};
除此之外,它还要负责接收netlink的消息,因此对应的cfg80211
处理接口的注册也都是在这里实现的:
static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
.add_virtual_intf = wlan_hdd_add_virtual_intf,
.del_virtual_intf = wlan_hdd_del_virtual_intf,
.change_virtual_intf = wlan_hdd_cfg80211_change_iface,
.change_station = wlan_hdd_change_station,
.start_ap = wlan_hdd_cfg80211_start_ap,
.change_beacon = wlan_hdd_cfg80211_change_beacon,
.stop_ap = wlan_hdd_cfg80211_stop_ap,
.change_bss = wlan_hdd_cfg80211_change_bss,
.add_key = wlan_hdd_cfg80211_add_key,
.get_key = wlan_hdd_cfg80211_get_key,
.del_key = wlan_hdd_cfg80211_del_key,
.set_default_key = wlan_hdd_cfg80211_set_default_key,
.scan = wlan_hdd_cfg80211_scan,
.connect = wlan_hdd_cfg80211_connect,
.disconnect = wlan_hdd_cfg80211_disconnect,
...
三、总结
总的来说,通常网络设备的注册,网络设备接口的实现,以及通信等处理,都是在qcacld
驱动中完成和处理的。
而关于具体芯片的接口注册和处理,以及芯片的电源控制,都是在cnss
中完成的。