[Linux-wifi]wifi驱动相关知识

来源:互联网 发布:excel如何筛选重复数据 编辑:程序博客网 时间:2024/05/21 21:44

图参考:
https://wireless.wiki.kernel.org/_media/en/developers/documentation/control.pdf

1.android_kernel/net/mac80211
2.android_kernel/include/net/cfg80211.h
3.android_kernel/net/wireless
4.android_kernel/drivers/net/wireless
一.如下为驱动—>内核wiphy_new—>注册cfg80211_ops结构体逻辑:
kernel/include/net/cfg80211.h头文件中有需要”驱动”实现的具体方法结构体cfg80211_ops声明
{
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
int (*resume)(struct wiphy *wiphy);
int (*scan)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request);

int (*auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_auth_request *req);
int (*assoc)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_assoc_request *req);
int (*deauth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_deauth_request *req);
int (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_disassoc_request *req);

int (*connect)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
int (*disconnect)(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code);
int (*set_tx_power)(struct wiphy *wiphy,
enum nl80211_tx_power_setting type, int mbm);
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
bool enabled, int timeout);
….等它函数指针略
}
}
kernel/net/wireless/core.c中有相应的方法用来被调用传递驱动实现的ops结构体
{
struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
{
struct cfg80211_registered_device *rdev;//结构体
rdev = kzalloc(alloc_size, GFP_KERNEL);
rdev->ops = ops;//保存驱动实现的ops结构体
rdev->wiphy_idx = wiphy_counter++;
device_initialize(&rdev->wiphy.dev);//初始化设备
rdev->wiphy.dev.class = &ieee80211_class;
rdev->wiphy.dev.platform_data = rdev;//rdev结构体注册到wiphy结构体中
return &rdev->wiphy;
}
//1.其中cfg80211_registered_device在”kernel/net/wireless/core.h”头文件中
//struct cfg80211_registered_device {
// const struct cfg80211_ops *ops;
// /* wiphy index, internal only */
// int wiphy_idx;
// struct cfg80211_scan_request scan_req; / protected by RTNL */
// /* must be last because of the way we do wiphy_priv(),
// * and it should at least be aligned to NETDEV_ALIGN */
// struct wiphy wiphy attribute((aligned(NETDEV_ALIGN)));
// …….其它略
//
//2.其中ieee80211_class在”kernel/net/wireless/sysfs.c文件中”
// struct class ieee80211_class = {
// .name = “ieee80211”,
// .owner = THIS_MODULE,
// .dev_release = wiphy_dev_release,
// .dev_attrs = ieee80211_dev_attrs,
// #ifdef CONFIG_HOTPLUG
// .dev_uevent = wiphy_uevent,
// #endif
// .suspend = wiphy_suspend,
// .resume = wiphy_resume,
// .ns_type = &net_ns_type_operations,
// .namespace = wiphy_namespace,
//
//一般对cfg80211_registered_device进行转换调用再cfg80211_ops(具体方法由驱动实现)
//3.重要的转换方法在”kernel/net/wireless/core.h”
//static inline struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy){
// return container_of(wiphy, struct cfg80211_registered_device, wiphy);}
//
}

高通驱动初始化方法如下
vendor/qcom/opensource/wlan/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
{
static struct cfg80211_ops wlan_hdd_cfg80211_ops;//定义cfg80211_ops结构体
struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
{
struct wiphy *wiphy;
ENTER();
/*
* Create wiphy device
*/
wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);//调内核中的方法把驱动实现的cfg80211_ops结构体传给内核

if (!wiphy){    /* Print error and jump into err label and free the memory */    hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);    return NULL;}return wiphy;

}
/* cfg80211_ops 驱动中具体的实现方法*/
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,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))

#else
.start_ap = wlan_hdd_cfg80211_start_ap,
.change_beacon = wlan_hdd_cfg80211_change_beacon,
.stop_ap = wlan_hdd_cfg80211_stop_ap,
#endif
.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,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
.set_channel = wlan_hdd_cfg80211_set_channel,
#endif
.scan = wlan_hdd_cfg80211_scan,
.connect = wlan_hdd_cfg80211_connect,
.disconnect = wlan_hdd_cfg80211_disconnect,
.join_ibss = wlan_hdd_cfg80211_join_ibss,
.leave_ibss = wlan_hdd_cfg80211_leave_ibss,
.set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
.set_tx_power = wlan_hdd_cfg80211_set_txpower,
.get_tx_power = wlan_hdd_cfg80211_get_txpower,
.remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
.cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
.mgmt_tx = wlan_hdd_mgmt_tx,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
.mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
.set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
.set_txq_params = wlan_hdd_set_txq_params,
#endif
.get_station = wlan_hdd_cfg80211_get_station,
.set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
.del_station = wlan_hdd_cfg80211_del_station,
.add_station = wlan_hdd_cfg80211_add_station,
#ifdef FEATURE_WLAN_LFR
.set_pmksa = wlan_hdd_cfg80211_set_pmksa,
.del_pmksa = wlan_hdd_cfg80211_del_pmksa,
.flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
#endif
#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
.update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
#endif
#ifdef FEATURE_WLAN_TDLS
.tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
.tdls_oper = wlan_hdd_cfg80211_tdls_oper,
#endif
#ifdef WLAN_FEATURE_GTK_OFFLOAD
.set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
#endif /* WLAN_FEATURE_GTK_OFFLOAD */
#ifdef FEATURE_WLAN_SCAN_PNO
.sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
.sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
#endif /FEATURE_WLAN_SCAN_PNO /
.resume = wlan_hdd_cfg80211_resume_wlan,
.suspend = wlan_hdd_cfg80211_suspend_wlan,
.set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
#ifdef WLAN_NL80211_TESTMODE
.testmode_cmd = wlan_hdd_cfg80211_testmode,
#endif
.dump_survey = wlan_hdd_cfg80211_dump_survey,
};
}
}

Linux中的80211架构如下:
这里写图片描述

这里写图片描述

原创粉丝点击