cfg80211的kernel架构(基于Linux 3.08)之sta

http://blog.chinaunix.net/uid-27167114-id-3783603.html

1, 大致框架




2, 几个主要流程

a) malloc & init(softmac)

内存分布

struct wiphy

struct ieee80211_local

Driver private class


结构体关系


初始化顺序
  • module_init,注册xxxx_driver_ops
  • xxxx_probe,各种资源初始化。
  • ieee80211_alloc_hw,两个参数分别为mac80211_config_ops和private class的size
    • wiphy_new分配整块内存,wiphy_new里面初始化cfg80211_registered_device的一些成员
    • 初始化ieee80211_local各个成员,并将wiphy.priv指向ieee80211_local
    • ieee80211_local偏移到末尾,指针指向private class,并且保留在ieee80211_local.hw.priv
  • 初始化private class
  • ieee80211_register_hw,实现mac80211硬件的注册
    • wiphy_register添加dev(device_add),以及一些sanity检测
    • 并且初始化channel,iface以及wep等。
    • 调用ieee80211_if_add添加一个wlan0,类型为sta的net_device,并且给该net_device分配一块私有数据区:ieee80211_sub_if_data,已经实现了一套net_device_ops

b) beacon frame

接收流程

对于管理帧,通常是ieee80211_rx_handlers调用ieee80211_rx_h_mgmt,然后用wq的方式调用ieee80211_iface_work进一步调用ieee80211_sta_rx_queued_mgmt去处理。
beacon响应流程


TIM IE:
E-id | length | DTIM count | DTIM period | Bitmap control | PVM(1-256byte)
remain to investigate:
how passive scan is implemented by beacon?

c) scan


d) auth and associate

wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME
  1. true): sme_authenticate->wpa_driver_nl80211_authenticate...->cfg80211_mlme_auth
  2. false):  wpa_drv_associate->wpa_driver_nl80211_connect...->cfg80211_mlme_auth

assoc成功之后会调用driver的set_key函数update key, 一般是放到wifi芯片某个管脚对应的缓存区域,从而实现硬件加密(与xmit skb缓存区进行与或,eg)。
具体函数栈流程如下:

点击(此处)折叠或打开

  1. nl80211_connect
  2.     cfg80211_connect(after scan and have bbs)
  3.         cfg80211_conn_do_work
  4.             __cfg80211_mlme_auth
  5.                 rdev->ops->auth(&rdev->wiphy, dev, &req);

  6. CallBack by rx irq
  7. ieee80211_rx_irqsafe
  8. ieee80211_tasklet_handler
  9.     ieee80211_rx
  10.         __ieee80211_rx_handle_packet
  11.             ieee80211_prepare_and_rx_handle
  12.                     ieee80211_invoke_rx_handlers
  13.                         ieee80211_rx_handlers
  14.                             ieee80211_rx_h_mgmt

  15. Queuework:
  16. ieee80211_iface_work(iface.c)
  17.     ieee80211_sta_rx_queued_mgmt
  18.         ieee80211_rx_mgmt_auth
  19.         cfg80211_send_rx_auth
  20.             nl80211_send_rx_auth(告诉用户空间)
  21.             cfg80211_sme_rx_auth
  22.                 schedule_work(&rdev->conn_work)

  23. Queuework:
  24. cfg80211_conn_work
  25.     __cfg80211_mlme_assoc
  26.         rdev->ops->assoc

  27. CallBack by rx irq
  28. ....
  29. ieee80211_sta_rx_queued_mgmt
  30.     ieee80211_rx_mgmt_assoc_resp
  31.         ieee80211_assoc_success
  32.             ieee80211_sta_rx_notify
  33.                 通过timer定时触发 ieee80211_mgd_probe_ap_send
  34.                 发送nullfunction或者probe_req
  35.     cfg80211_send_rx_assoc
  36.             nl80211_send_rx_assoc(告诉用户空间)
  37.             __cfg80211_connect_result
  38.                 nl80211_send_connect_result
  39.                 cfg80211_upload_connect_keys
  40.                     rdev->ops->add_key

e) rx/tx data

rx:


xmit:


e) csa

1)beacon 2)action帧
没连上,正在scan,不用管
手头有任务,先把手头任务做完,然后断开连接
手头没任务,调用driver的channel_switch(回调实现后面的改chan值)或者hw_config函数,然后把local的chan值改一下

f) missing

some details: off channel,

3, wifi driver部分之bcmdhd

a) init(施工ing)
b) fireware load(施工ing)
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux中的MAC80211和CFG80211是用于无线网络的子系统。它们提供了一组API,使开发人员能够在Linux内核中实现无线网络设备驱动程序。 MAC80211是一个实现IEEE 802.11标准的软件模块,它负责管理Linux内核中的无线网络设备。它为网络设备提供了一组接口,使它们能够与其他网络设备进行通信。MAC80211还负责处理无线帧和管理无线网络的连接。 CFG80211是一个用于配置802.11设备的API。它负责管理无线网络设备的配置,例如频率、信道和加密设置等。它还提供了一组接口,使用户空间应用程序能够与无线网络设备进行通信。 示例代码: 以下代码展示了如何使用CFG80211 API在Linux内核中配置无线网络设备。 ``` #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> #include <linux/wireless.h> #include <net/cfg80211.h> static struct cfg80211_ops my_cfg_ops = { .change_beacon = NULL, }; static struct cfg80211_device my_cfg_device = { .ops = &my_cfg_ops, }; static int __init my_init(void) { int ret; struct wireless_dev *wdev; wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM; wdev->wiphy = wiphy_new(&my_cfg_ops, sizeof(*wdev)); if (!wdev->wiphy) { kfree(wdev); return -ENOMEM; } wdev->wiphy->privid++; wdev->wiphy->dev.parent = NULL; wdev->wiphy->dev.release = NULL; wdev->wiphy->dev.groups = NULL; wdev->wiphy->dev.dma_mask = NULL; wdev->wiphy->dev.coherent_dma_mask = ~0; ret = wiphy_register(wdev->wiphy); if (ret) { wiphy_free(wdev->wiphy); kfree(wdev); return ret; } wdev->wiphy->dev.parent = wiphy_dev(wdev->wiphy); wdev->netdev = alloc_netdev_mqs(sizeof(struct net_device *), "my_dev", NET_NAME_UNKNOWN, ether_setup, 1, 1); if (!wdev->netdev) { wiphy_unregister(wdev->wiphy); wiphy_free(wdev->wiphy); kfree(wdev); return -ENOMEM; } wdev->wiphy->privid++; wdev->netdev->ieee80211_ptr = wdev; wdev->netdev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; wdev->netdev->ieee80211_ptr->flags |= IEEE80211_STA_CONNECTION_POLL; ret = register_netdev(wdev->netdev); if (ret) { free_netdev(wdev->netdev); wiphy_unregister(wdev->wiphy); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } my_cfg_device.wiphy = wdev->wiphy; ret = cfg80211_register_device(&my_cfg_device); if (ret) { unregister_netdev(wdev->netdev); free_netdev(wdev->netdev); wiphy_unregister(wdev->wiphy); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } return 0; } static void __exit my_exit(void) { cfg80211_unregister_device(&my_cfg_device); unregister_netdev(wdev->netdev); free_netdev(wdev->netdev); wiphy_unregister(wdev->wiphy); wiphy_free(wdev->wiphy); kfree(wdev); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL"); ``` 这段代码首先创建了一个无线设备和一个无线网络接口。然后,它将无线设备注册到CFG80211子系统中,并将无线网络接口注册到Linux内核中。最后,它将无线设备和无线网络接口添加到一个数据结构中,并将该数据结构注册到CFG80211子系统中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值