atheros wifi 动因分析
Ar6003
驱动文档摘要
1、
wmi : wireless module interface //无线模块结构
2、
bmi : bootloader message interface
3、
htc : host target communications
4、
wps:wifi protected setup
5、
CS:connection services module
6、
STA:station
7、
AP:access point
Wireless application :
生产数据和消费数据
Wireless module interface (WMI):host
和target 之间的通信协议
Host/target communications (HTC):
发送和接收数据
Hardware interface (HIF) :调用硬件接口发送和接收数据(这里用的是sdio
接口)
Bootloader message interface (BMI):在wifi芯片启动时通信协议。能够下载bin文件到wifi芯片中。
Ar6000 wifi 驱动分析(AP
模式分析)
代码运行的主要流程
//挂载sdio
驱动到内核和注冊网络设备
module_init(__ar6000_init_module);
à__ar6000_init_module
àstatus = ar6000_init_module();
àstatus =
HIFInit(&osdrvCallbacks);
à status = sdio_register_driver(&ar6k_driver);注冊sdio
驱动(这里直接调用的内核sdio协议栈)
à.probe = hifDeviceInserted, //运行驱动的probe
函数
àret = hifEnableFunc(device, func);
à kthread_create(async_task,
//内核开了一个sdio 异步发送数据的进程
à taskFunc = startup_task; //开一个内核进程,运行startup_task
进程
àif ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK)//调用安装wifi
设备的函数指针ar6000_android_avail_ev。这个函数是在android_module_init中注冊的。
àar6000_android_avail_ev
àret = ar6000_avail_ev_p(context, hif_handle);
àar6000_avail_ev//这个函数指针赋值赋的非常曲折首先在ar6000_init_module(void)函数中赋给了osdrvCallbacks.deviceInsertedHandler
= ar6000_avail_ev;然后在android_module_init(&osdrvCallbacks);中ar6000_avail_ev_p = osdrvCallbacks->deviceInsertedHandler;赋给了ar6000_avail_ev_p;
à BMIInit();//開始启动wifi模块
àar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);//创建htc ,关闭中断
à status = (ar6000_init(dev)==0) ?
A_OK : A_ERROR; //
初始化网络设备
à (BMIDone(ar->arHifDevice) != A_OK))//bmi
启动完毕
à status = HTCStart(ar->arHtcTarget);//启动htc ,开启中断
àstatus = DevUnmaskInterrupts(&target->Device);//开启中断,
注冊中断处理函数
àHIFUnMaskInterrupt(pDev->HIFDevice);//注冊中断处理函数
àret = sdio_claim_irq(device->func,
hifIRQHandler);//注冊中断处理函数,中断后就会调用hifIRQHandler
这个处理函数
à if (register_netdev(dev))
//向内核注冊网络设备。到此初始化完毕。
//产生中断后的代码流程
àhifIRQHandler(struct sdio_func *func) //中断处理函数
(hif.c)
àstatus = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); //设备处理函数的函数指针
àA_STATUS DevDsrHandler(void *context);这函数是在创建htc
即HTCCreate 函数中填充的:HTCCreate—>DevSetupàhtcCallbacks.dsrHandler = DevDsrHandler;(ar6k_events.c)
àstatus = ProcessPendingIRQs(pDev, &done, &asyncProc);//处理未决事件的函数,在这里会循环处理(ar6k_events.c)
àstatus = pDev->MessagePendingCallback();这个函数指针也是在HTCCreate
中填充的target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;(htc_recv.c)
àHTCRecvMessagePendingHandler();
à DO_RCV_COMPLETION(pEndpoint,&container);
à DoRecvCompletion();
à pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);//这个函数指针是在ar6000_init
中填充的connect.EpCallbacks.EpRecv = ar6000_rx; ar6000_rx
是一个很重要的函数。
à ar6000_rx(void *Context, HTC_PACKET *pPacket)
//数据发送流程
à ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
à HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
à return HTCSendPktsMultiple(HTCHandle, &queue);
à HTCTrySend(target, pEndpoint, pPktQueue);
à HTCIssueSend(target, pPacket);
à status = DevSendPacket(&target->Device,
à status = HIFReadWrite(pDev->HIFDevice, //传给了sido
总线
à AddToAsyncList(device, busrequest);//把要发送的数据包增加异步发送队列
à up(&device->sem_async); //获取信号量,用内核进程进行数据发送
à static int async_task(void *param) //发送数据
à __HIFReadWrite();//发送数据
à sdio_writesb();sdio_memcpy_toio();sdio_readsb();sdio_memcpy_fromio();
à down_interruptible(&busrequest->sem_req) != 0 //释放信号量
//中断发送或,接收流程
àHTCRecvMessagePendingHandler
à status = HTCIssueRecv(target, pPacket);//异步接收数据包
à status = HIFReadWrite(pDev->HIFDevice, //命令传给sdio
总线
à与发送流程同样
//sta
连接流程
à ar6000_rx ();收到连接的命令,此时的ar->arControlEp=ept=1
à wmi_control_rx(arPriv->arWmi, skb)。//解析命令
à case (WMI_CONNECT_EVENTID): //连接命令
à status = wmi_connect_event_rx(wmip, datap, len);
à A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev);
à ar6000_connect_event((devt), (pEvt));
à wireless_send_event(arPriv->arNetDev, IWEVREGISTERED, &wrqu, NULL); //向网络层发送事件 wext-core.c
àskb_queue_tail(&dev_net(dev)->wext_nlevents, skb); //wext-core.c
----------------------------------经过网络层的处理--------------------------------------------------------------------
àsock_ioctl(struct file *file, unsigned cmd, unsigned long arg)// net/socket.c
àerr = dev_ioctl(net, cmd, argp); // net/core/dev.c
àreturn
wext_handle_ioctl(net, &ifr, cmd, arg); // net/wireless/wext-core.c
àret = wext_ioctl_dispatch(net, ifr, cmd, &info,
ioctl_standard_call,
ioctl_private_call); // net/wireless/wext-core.c
àret = wireless_process_ioctl(net, ifr, cmd, info, standard, private); //net/wireless/wext-core.c
à return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);//这个是在注冊网络设备注冊的函数.ndo_do_ioctl = ar6000_ioctl,
---------------------------网络层调用驱动层的函数----------------------------------------
à int ar6000_ioctl(); // ioctl.c
à case IEEE80211_IOCTL_SETKEY: //ioctl.c
à ar6000_ioctl_setkey(arPriv, &keydata); //ioctl.c
à status = ar6000_sendkey(arPriv, ik, keyUsage); //ioctl.c
à status = wmi_addKey_cmd()
à status = wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag);
//传输数据流程
à ar6000_rx ();收到连接的数据,此时ept=2
à ar6000_deliver_frames_to_nw_stack((void *) arPriv->arNetDev, (void *)skb);
à A_NETIF_RX_NI(skb);
ànetif_rx_ni(skb) //将数据传给ip
层
Hostapd 设置ssid
àint main(int argc, char *argv[]); //main.c
àinterfaces.iface[i] = hostapd_interface_init(&interfaces, //main.c
àhostapd_setup_interface(iface)) { //main.c
àret = setup_interface(iface); //hostapd.c
àreturn hostapd_setup_interface_complete(iface, 0); //hostapd.c
àif (hostapd_driver_commit(hapd) < 0) { // ap_drv_ops.c
àreturn hapd->driver->commit(hapd->drv_priv);//在driver_ar6000.c
中赋值的.commit = ar6000_commit
àar6000_commit(void *priv)//driver_ar6000.c
----------------------从应用层通过ioctl
进入驱动层---------------------------------------------------------------
àif (ioctl(drv->ioctl_sock, SIOCSIWCOMMIT, &iwr) < 0) { //在wireless_ext.c
中赋值的(iw_handler) ar6000_ioctl_siwcommit,
àar6000_ioctl_siwcommit(struct net_device *dev, //
wireless_ext.c
àar6000_ap_mode_profile_commit(arPriv);
//ar6000_dr.c
àwmi_ap_profile_commit(arPriv->arWmi, &p); //wmi.c
àstatus = wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG); //wmi.c
版权声明:本文博主原创文章。博客,未经同意不得转载。
atheros wifi 动因分析的更多相关文章
- linux驱动基础系列--Linux下Spi接口Wifi驱动分析
前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...
- 公交wifi运营平台分析
一.前言背景 昨晚下午,老板让看一些车载公交wifi后台管理的一些东西,这个随着移动端设备而兴起的wifi战,慢慢的也会越演越烈. 现在于很多人在外面的时候,进入一家店首先看的不是菜单,而是问一句“你 ...
- Wifiner for Mac(WiFi 状况分析工具)破解版安装
1.软件简介 Wifiner 是 macOS 系统上一款 Wifi 分析工具,仅需几次点击即可对您的 Wi-Fi 网络连接进行分析和故障排除.扫描您的 Wi-Fi 网络,获取包含交互式彩色编码热 ...
- Android WIFI模块分析
一:什么是WIFI WIFI是一种无线连接技术.可用于手机.电脑.PDA等终端. WIFI技术产生的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11 ...
- 为什么房间的 Wi-Fi 信号这么差
最近把家里主卧整成了个小影院,由于之前房子装修时网线端口与电源插口布置太少,导致家庭网络架设变得麻烦起来,最后终于通过「无线中继」技术达到了全屋满格 Wi-Fi 的效果. 在 Wi-Fi 架设过程中, ...
- I.MX6 AW-NB177NF WIFI 驱动移植问题
/******************************************************************************** * I.MX6 AW-NB177NF ...
- Android 数据通信
一. Http/Net1. http 通讯协议和android中相关API介绍 2.发送http请求实例[GET,POST]论坛参考文献:http://www.eoeandroid.com/viewt ...
- 【openwrt】再设置
https://wiki.openwrt.org/zh-cn/doc/uci/network https://wiki.openwrt.org/zh-cn/doc/uci/wireless https ...
- iOS多用连接、反向协议、安全
资源 WWDC-2013-Session-708 BlackHat-US-2014-"It Just (Net)works" Understanding Multipeer Con ...
随机推荐
- Spring Boot集成EHCache实现缓存机制
SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManag ...
- 利用朴素贝叶斯(Navie Bayes)进行垃圾邮件分类
贝叶斯公式描写叙述的是一组条件概率之间相互转化的关系. 在机器学习中.贝叶斯公式能够应用在分类问题上. 这篇文章是基于自己的学习所整理.并利用一个垃圾邮件分类的样例来加深对于理论的理解. 这里我们来解 ...
- amazeui学习笔记--js插件(UI增强4)--下拉组件Dropdown
amazeui学习笔记--js插件(UI增强4)--下拉组件Dropdown 一.总结 1.am-dropdown(及其孩子):控制下拉列表的样式 2.data-am-dropdown(及其孩子):控 ...
- C语言深度剖析-----数组参数和指针参数分析
数组退化的意义 当向函数传递数组时, 二维数组参数 等价关系 注意事项 只能去一维数组 无法向一个函数传递一个任意的多维数组,注释地方出错 传递与访问二维数组的方式 动态地算出二维数组的列
- Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
spring 5.+jpa 配置类出错: 十二月 20, 2018 5:53:01 下午 org.springframework.web.servlet.DispatcherServlet initS ...
- ZOJ 1076 Gene Assembly LIS
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=76 题目大意: 题目前面都是废话. 给你一串基因,然后给你上面的外显子的起始和终 ...
- MinGW、MinGW-w64 与TDM-GCC 应该如何选择?
MinGW.MinGW-w64 与TDM-GCC 应该如何选择? https://www.zhihu.com/question/39952667
- 洛谷 P3112 后卫马克Guard Mark
->题目链接 题解: 贪心+模拟 #include<algorithm> #include<iostream> #include<cstring> #incl ...
- NSCache使用常见错误
NSCache用来存储缓存数据的时候.和NSDictionary功能类似, 可是NSCache有一个特别的问题: 一旦接收到内存警告之后,假设使用[NSCache removeAllObjects]处 ...
- ssl 内存泄露
http://i.mtime.com/chevalier/blog/1824652/ openssl内存分配 chevalier 发布于: 2009-04-20 10:31 openssl内存分配 ...