Atheros wifi 驱动分析

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


Atheros wifi 驱动分析_第1张图片
QQ图片20180418160259.png
Atheros wifi 驱动分析_第2张图片
QQ图片20180418160325.png
  • 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

ar6003 驱动架构图


Atheros wifi 驱动分析_第3张图片
QQ图片20180418160810.png

你可能感兴趣的:(Atheros wifi 驱动分析)