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—>DevSetuphtcCallbacks.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
ar6003 驱动架构图