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

时间: 2024-10-05 06:15:56

atheros wifi 驱动分析的相关文章

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 applica

【智能家居篇】wifi驱动的理解(1)——驱动架构

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在分析WIFI驱动前,分享一下个人对Linux驱动的一些了解,其实纵观Linux众多的设备驱动,几乎都是以总线为载体,所有的数据传输都是基于总线形式的,即使设备没有所谓的总线接口,但是Linux还是会给它添加一条虚拟总线,如platform总线等:介于WIFI的驱动实在是太庞大了,同时又是基于比较复杂的USB总线,所以建议读者在看此文章之前,先了解一下USB设备驱动和网络设备驱动. 我们要看懂WIFI驱动,首先要

SDIO 接口的wifi驱动

1.sdio接口层解析 SDIO总线   SDIO总线 和 USB总线 类似,SDIO也有两端,其中一端是HOST端,另一端是device端.所有的 通信 都是 由HOST端 发送 命令 开始的,Device端只要能解析命令,就可以相互通信. CLK信号:HOST给DEVICE的 时钟信号,每个时钟周期传输一个命令. CMD信号:双向 的信号,用于传送 命令 和 反应. DAT0-DAT3 信号:四条用于传送的数据线. VDD信号:电源信号. VSS1,VSS2:电源地信号. SDIO热插拔原理

Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

转: http://blog.csdn.net/zqixiao_09/article/details/51146149 前面学习了SDIO接口的WiFi驱动,现在我们来学习一下USB接口的WiFi驱动,二者的区别在于接口不同.而USB接口的设备驱动,我们前面也有学习,比如USB摄像头驱动.USB鼠标驱动,同样都符合LinuxUSB驱动结构: USB设备驱动(字符设备.块设备.网络设备) | USB 核心 | USB主机控制器驱动 不同之处只是在于USB摄像头驱动是字符设备,而我们今天要学习的Wi

Android WIFI模块分析

一:什么是WIFI WIFI是一种无线连接技术,可用于手机.电脑.PDA等终端.WIFI技术产生的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11标准的,但WIFI不等同无线网络. 二:Android平台下的WIFI模块 简单介绍一下,WIFI模块的基本功能: 1. 开关WIFI 除了在WIFI设置界面可以开关WIFI,还有其他的方法可以设置,要查看这些开关状态是否一致.还有就是飞行模式对WIFI开关的影响,由于WIFI开和关都有一个时间过程,

蓝牙驱动分析 linux

蓝牙驱动分析 这个驱动分析的是OK6410开发板自带的内核版本是linux3.0.1,所支持的wifi和蓝牙一体芯片是marvell的8688和8787.根据开发板的设计,芯片与主机之间是通过sdio协议接口通信的,所以驱动也是通过sdio的方式写的. 个人分析驱动的过程是从插入设备驱动的动作开始的. 首先每次插入设备和拔出设备驱动都会通过终端打印相应的信息,判断在sd卡槽中肯定是触发中断的,通过看硬件原理图和数据手册中的SDMMC控制器可知用于mmc的中断号分别为56和57,回到代码中.在内核

Linux SD/MMC/SDIO驱动分析

一.SD/MMC/SDIO概念区分 SD(SecureDigital)与 MMC(MultimediaCard) SD 是一种 flash memory card 的标准,也就是一般常见的 SD 记忆卡,而 MMC 则是较早的一种记忆卡标准,目前已经被 SD 标准所取代.在维基百科上有相当详细的 SD/MMC 规格说明:[http://zh.wikipedia.org/wiki/Secure_Digital]. SDIO(SecureDigital I/O) SDIO 是目前我们比较关心的技术,

Linux 下wifi 驱动开发(三)—— SDIO接口WiFi驱动浅析

SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈.可以实现用户主平台数据通过SDIO口到无线网络之间的转换.SDIO具有数据传输快,兼容SD.MMC接口等特点. 对于SDIO接口的wifi,首先,它是一个sdio的卡的设备.然后具备了wifi的功能.所以.注冊的时候还是先以sdio的卡的设备去注冊的. 然后检測到卡之后就要驱动他的wifi功能了.显然,他是用sdio的协议,通过发命令和数据来控制的.以

I.MX6 AW-NB177NF WIFi 驱动移植问题

/******************************************************************************** * I.MX6 AW-NB177NF WIFi 驱动移植问题 * 说明: * 之前驱动移植,但看不到有wlan设备产生,于是感觉是wifi驱动出了问题,于是开始 * 分析厂家提供的wifi驱动,发现id对应的信息不对,经过与FAE确认之后并验证,确实是 * 这个问题导致的. * * 2016-6-20 深圳 南山平山村 曾剑锋 ***