mtkwifidriver驱动的分析.docx

上传人:b****8 文档编号:10518434 上传时间:2023-02-17 格式:DOCX 页数:17 大小:65.41KB
下载 相关 举报
mtkwifidriver驱动的分析.docx_第1页
第1页 / 共17页
mtkwifidriver驱动的分析.docx_第2页
第2页 / 共17页
mtkwifidriver驱动的分析.docx_第3页
第3页 / 共17页
mtkwifidriver驱动的分析.docx_第4页
第4页 / 共17页
mtkwifidriver驱动的分析.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

mtkwifidriver驱动的分析.docx

《mtkwifidriver驱动的分析.docx》由会员分享,可在线阅读,更多相关《mtkwifidriver驱动的分析.docx(17页珍藏版)》请在冰豆网上搜索。

mtkwifidriver驱动的分析.docx

mtkwifidriver驱动的分析

管理篇

接收到扫描完毕

nicRxSDIOAggReceiveRFBs

sdio有两个通道,两个通道获取数据的流程是一样的,

1)通过prEnhDataStr->rRxInfo.u.u2NumValidRx0Len可以获取到该通道目前存储有多少数据包,通道数据包的存储量只有16个,如果超过16个则是固件问题,跳过看下一个通道的

2)然后获取当前freeswrfb空闲空间是否够用,不够用则看下一个通道的。

3)可接收的聚合报文(管理帧)长度(u4RxAvailAggLen)为2352

4)循环遍历某个通道的报文,读到报文长度+4然后按照4个字节对齐从u4RxAvailAggLen扣减掉。

如果空间不够则跳出。

5)遍历完之后用2352减去u4RxAvailAggLen可以得到总的数据长度通过dma获取数据到prRxCtrl->pucRxCoalescingBufPtr中

1)6)遍历通道中报文数,把每个报文拷贝到prSwRfb->pucRecvBuff中,并且填充prSwRfb->ucPacketType和prSwRfb->ucStaRecIdx

2)nicRxSetupRFB

3)如果prSwRfb->pvPacket为空,则先将prSwRfb置成0,然后按照2352分配sk_buff,prSwRfb->pucRecvBuff指向skb->data,prSwRfb->pvPacket指向skb

1)同时,prSwRfb->prHifRxHdr指向skb->data首部。

2)nicRxFillRFB

3)从prHifRxHdr->ucHerderLenOffset获取出header的offset和MACHeaderLen

4)设置prSwRfb->pvHeader指向skb->data越过prHifRxHdr+HIF_RX_HDR_SIZE+u4HeaderOffset,指向的将是beacon帧结构

5)重置prSwRfb->u2HeaderLen=u4MacHeaderLen和prSwRfb->u2PacketLen为原来skb->data长度减去(HIF_RX_HDR_SIZE+u4HeaderOffset)

MacHeader如下图:

nicAddScanResult

该函数分为replace和add部分,先讲解add部分

Add

1)如果prAdapter->rWlanInfo.u4ScanResultNum小于63则继续往下走

2)先将prAdapter->rWlanInfo.arScanResult[i]到aucIE之前的部分设置为0

3)设置prAdapter->rWlanInfo.arScanResult[i].u4Length为aucIE之前的部分的长度+IE的长度

4)拷贝mac地址到prAdapter->rWlanInfo.arScanResult[i].arMacAddress

5)拷贝ssid到prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid

6)设置u4Privacy、rRssi、eNetworkTypeInUse、eOpMode等

7)拷贝prConfiguration到prAdapter->rWlanInfo.arScanResult[i].rConfiguration中

8)拷贝rSupportedRates到prAdapter->rWlanInfo.arScanResult[i].rSupportedRates中

9)拷贝u2IELength到prAdapter->rWlanInfo.arScanResult[i].u4IELength

10)如果u2IELength大于0则检查aucScanIEBuf是否够放下当前bssdesc的IE部分,如果可以的话,则拷贝到aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage],然后设置指针到apucScanResultIEs[i]中,接下来重置u4ScanIEBufferUsage的值。

如果空间不够的话,则将arScanResult[i].u4Length、u4IELength、apucScanResultIEs[i]设置为0.

如果u2IELength不大于0,则设置apucScanResultIEs[i]=NULL;

11)prAdapter->rWlanInfo.u4ScanResultNum++;

如果当前已经没有空间存储了,则考虑替换rssi最弱的那个ap

authCheckRxAuthFrameTransSeq

1)该函数先判断该报文是否是正确的,评判标准就是:

如果报文总长度扣掉报文头所剩下的空驾大于6(authalgorithm+authseqnum+statuscode)

这三个字段是必备的意思。

获取authseqnum来判断该数据包是属于authrequest(1和3)还是authresponse(2和4)

saaFsmRunEventRxAuth(处理authresponse的包函数)

aaaFsmRunEventRxAuth(处理authrequest的包函数aaa指authentication,authorization,andaccountingservices即认证授权计费系统)

kalEnqueueCommand的cmd最后会由这边来执行wlanProcessCommandQueue

mboxRcvAllMsg

上层下发scan指令流程分析

mtk_cfg80211_scan

1)首先先查看下当前是否有在扫描的请求,如果有,则直接退出,通过变量prGlueInfo->prScanRequest来进行判断

2)通过对request进行判断分解请求

a.分解ssid,如果请求ssid的个数为1,则将ssid拷贝到rScanRequest的ssid中,如果大于1则直接退出,如果为0,则将rScanRequest.rSsid.u4SsidLen为0;

b.分解IE,如果ie_len大于0,则将rScanRequest.pucIE指向request中的ie,并且置为u4IELength为0

3)通过kalioctl进行发送wlanoidSetBssidListScanExt参数为rScanRequest

Kalioctl触发流程:

将相关参数组装成prIoReq中,之后唤醒tx_thread来处理OID,然后等待执行结束,在tx_thread中会调用wlanSetInformation或者wlanQueryInformation,不过这两部分的操作,最后都会调用prIoReq中的回调函数,

wlanoidSetBssidListScanExt流程:

1.判断参数中请求的长度参数的长度是否等于参数结构的大小

2.判断射频是否关闭

3.遍历prBSSDescList,将类型为BSS_TYPE_INFRASTRUCTURE的prBssDesc->aucRawBuf清空

4.将scanrequest的参数解析出来

5.获取ais状态机prAisFsmInfo

6.启动prAisFsmInfo->rScanDoneTimer定时器时长为15s

如果支持在线扫描,则直接aisFsmScanRequest,否则如果kalGetMediaStateIndicated(prAdapter->prGlueInfo)!

=PARAM_MEDIA_STATE_CONNECTED则跟着aisFsmScanRequest,其他直接WLAN_STATUS_FAILURE。

aisFsmScanRequest流程

1.判断prConnSettings->fgIsScanReqIssued是否为false,同一时间只能有一次scan。

2.如果有ssid、IE等获取出来,拷贝到prAisFsmInfo中对应的变量中。

3.如果当前prAisFsmInfo->eCurrentState==AIS_STATE_NORMAL_TR,如果当前是处于prAisBssInfo->eCurrentOPMode==OP_MODE_INFRASTRUCTURE并且prAisFsmInfo->fgIsInfraChannelFinished==FALSE(802.1x可能还没完成,pendit等后续操作),则执行aisFsmInsertRequest(prAdapter,AIS_REQUEST_SCAN);否则,则执行开始onlinescan(包括wlanClearScanningResult(prAdapter)和aisFsmSteps(prAdapter,AIS_STATE_ONLINE_SCAN))

4.如果当前prAisFsmInfo->eCurrentState==AIS_STATE_IDLE,则直接进行扫描(包括wlanClearScanningResult(prAdapter)和aisFsmSteps(prAdapter,AIS_STATE_ONLINE_SCAN))。

其他情况也是直接pendit等后续操作aisFsmInsertRequest(prAdapter,AIS_REQUEST_SCAN);

wlanClearScanningResult流程

1.如果当前处于连接状态,则遍历prAdapter->rWlanInfo.arScanResult,跟当前连接的ap的mac地址进行比对prAdapter->rWlanInfo.rCurrBssId.arMacAddress,如果一致,则将其搬到prAdapter->rWlanInfo.arScanResult[0]其他都清除。

如果当前不处于连接,则直接prAdapter->rWlanInfo.u4ScanResultNum=0;prAdapter->rWlanInfo.u4ScanIEBufferUsage=0;

aisFsmSteps(prAdapter,AIS_STATE_SCAN/AIS_STATE_ONLINE_SCAN/LOOK_FOR)流程:

1.先将nextState保存到prAisFsmInfo->eCurrentState中。

2.Switch(nextState)就看AIS_STATE_SCAN/AIS_STATE_ONLINE_SCAN/LOOK_FOR

3.A.先检测网络设备是否已经激活,如果没有激活,则进行激活操作。

B.组装SCAN_REQ,msgID为:

MID_AIS_SCN_SCAN_REQ,扫描类型为:

SCAN_TYPE_ACTIVE_SCAN,根据SSID长度来选择ucSSIDType,如果为0则SCAN_REQ_SSID_WILDCARD,否则,则SCAN_REQ_SSID_SPECIFIED方式。

然后通过检测当前是否在p2p或者是bow来修正channel的问题,对于非p2p或者bow来说,则通过aePreferBand和fgEnable5GBand来决定是应该是扫描的band。

接下来处理IE的部分。

最后将msg通过mboxSendMsg采用MSG_SEND_METHOD_BUF发送到MBOX_ID_0中。

mboxSendMsg对于类型为MSG_SEND_METHOD_BUF的,会将该信息插入到mbox的链表中(prMbox->rLinkHead),然后唤醒tx_thread。

对于MSG_SEND_METHOD_UNBUF,则会调用MBOX_HNDL_MSG,该函数将会从arMsgMapTable中获取对应类型的handle,马上进行相关处理。

对于BUF的msg,唤醒tx_thread之后,将会执行wlanProcessMboxMessage。

wlanProcessMboxMessage

该函数主要是通过遍历所有的MBOX,对每个MBOX执行mboxRcvAllMsg(将prMbox->rLinkHead中所有的节点提取handle,然后执行它。

流程同上面unbuf的流程。

针对该scan流程,则会触发scnFsmMsgStart函数的执行。

scnFsmMsgStart执行流程

判断当前状态是否为idle(prScanInfo->eCurrentState==SCAN_STATE_IDLE),如果是则判断当前的emsgid是否为(MID_AIS_SCN_SCAN_REQ|MID_BOW_SCN_SCAN_REQ|MID_P2P_SCN_SCAN_REQ|MID_RLM_SCN_SCAN_REQ),如果是的话则scnFsmHandleScanMsg;

如果当前emsgid是否为(MID_AIS_SCN_SCAN_REQ_V2|MID_BOW_SCN_SCAN_REQ_V2|MID_P2P_SCN_SCAN_REQ_V2|MID_RLM_SCN_SCAN_REQ_V2),如果是的话则执行scnFsmHandleScanMsgV2;接下来将该free掉该msghdr,接着执行scnFsmSteps。

scnFsmHandleScanMsg函数流程

该函数主要将scanreq的数据保存到prAdapter->rWifiVar.rScanInfo中的rscanparam中。

还设置prScanParam->u2ProbeDelayTime为0,fgIsScanV2这个设置为false,设置ucSeqNum为ucSeqNum。

scnFsmSteps函数流程传入的SCAN_STATE_SCANNING这个状态

将SCAN_STATE_SCANNING赋值给prScanInfo->eCurrentState中,进入switch中,执行scnSendScanReq函数。

scnSendScanReq函数执行流程。

创建CMD_SCAN_REQ对象rCmdScanReq,将prScanParam中的相关信息拷贝到rCmdScanReq中,最后调用wlanSendSetQueryCmd函数,发送CMD_ID_SCAN_REQ,其中fgIsOid为false,fgNeedResp为false,fgSetQuery为true。

wlanSendSetQueryCmd执行流程

1.申请下cmdinfo的buf

2.将prAdapter->ucCmdSeqNum计数加1,fgDriverDomainMCR为false

组装P_CMD_INFO_T对象prCmdInfo,cmdType类型为COMMAND_TYPE_NETWORK_IOCTL,NetWorkType为NETWORK_TYPE_AIS_INDEX,pvInformationBuffer为rCmdScanReq对象,ucCID为CMD_ID_SCAN_REQ,然后将该prCmdInfo进行kalEnqueueCommand(该函数将会把该cmd插入到prCmdQue中),最后唤醒tx_thread

Tx_thread将在wlanProcessCommandQueue处理prCmdQue中的事件。

wlanProcessCommandQueue函数处理流程

先将prCmdQue拷贝到prTempCmdQue,然后遍历prTempCmdQue中每个进行处理。

对于我们scan的,则会设置eFrameAction为FRAME_ACTION_TX_PKT,该部分的处理会wlanSendCommand,如果没有资源(通过TC来发送)的话,则会将该请求放置到prMergeCmdQue中,如果命令包还需要更多的处理被pending的话,则将该请求放置到prAdapter->rPendingCmdQueue中,其他的,如果成功,判断是否有设置DoneHandler,则调用,没有则不处理。

如果发送失败的,则判断fgIsOid是否为真,如果为真则调用kalOidComplete,最后进行对cmdinfo的释放。

最后将所有剩下的cmd重新入到prCmdQue中。

wlanSendCommand函数处理流程

1.先判断NIC是否还在

看下是否属于正常发送CMDpacket,如果是则指定TC为TC4,接着判断是否有资源nicTxAcquireResource(主要是通过判断aucFreeBufferCount的缓冲区是否还有足够的空间,如果还有空间,则统计减一),然后通过nicTxCmd进行发送。

接下来看扫描结果返回路径。

这部分从tx_thread入口,AHB总线如果有中断产生,则会设置GlueInfo->u4Flag的中断位。

Tx_thread无限循环过程中,如果检测到有GlueInfo->u4Flag设置了中断位并且当前没有设置GLUE_FLAG_HALT,则会触发wlanIST函数的调用。

接下来看下该函数的实现

wlanIST函数解析

1.先唤醒connsys—》ACQUIRE_POWER_CONTROL_FROM_PM

2.处理中断---》nicProcessIST

3.使能HIF中断—》nicEnableInterrupt

Connsys可以考虑进入休眠。

--》RECLAIM_POWER_CONTROL_TO_PM

nicProcessIST函数解析

第一步先判断当前prAdapter->rAcpiState的状态是否为ACPI_STATE_D3,如果是这个状态,则直接返回当前adapter尚未准备好,否则继续执行。

然后从固件读取中断标志位(调用nicSDIOReadIntStatus),然后先对中断进行处理,接着将对应中断的位分发给各自的处理函数(nicProcessIST_impl)。

nicProcessIST_impl函数解析

该函数是用来将对应的中断的位分发给各自的处理函数,对应关系表格为arIntEventMapTable,对应的处理函数在表格apfnEventFuncTable中。

对于scan的返回结果最后会调用到对应的方法为nicProcessRxInterrupt。

nicProcessRxInterrupt函数解析

1.nicRxSDIOAggReceiveRFBs

2.nicRxProcessRFBs

nicRxSDIOAggReceiveRFBs函数解析

sdio有两个通道,两个通道获取数据的流程是一样的,

1)通过prEnhDataStr->rRxInfo.u.u2NumValidRx0Len可以获取到该通道目前存储有多少数据包,通道数据包的存储量只有16个,如果超过16个则是固件问题,跳过看下一个通道的

2)然后获取当前freeswrfb空闲空间是否够用,不够用则看下一个通道的。

3)可接收的聚合报文(管理帧)长度(u4RxAvailAggLen)为2352

4)循环遍历某个通道的报文,读到报文长度+4然后按照4个字节对齐从u4RxAvailAggLen扣减掉。

如果空间不够则跳出。

5)遍历完之后用2352减去u4RxAvailAggLen可以得到总的数据长度通过dma获取数据到prRxCtrl->pucRxCoalescingBufPtr中

6)遍历通道中报文数,把每个报文拷贝到prSwRfb->pucRecvBuff中,并且填充prSwRfb->ucPacketType和prSwRfb->ucStaRecIdx

nicRxProcessRFBs函数解析

从prRxCtrl->rReceivedRfbList抓取一个prSwRfb,然后判断该包的类型,通过字段ucPacketType进行判断,分为HIF_RX_PKT_TYPE_DATA、HIF_RX_PKT_TYPE_EVENT、HIF_RX_PKT_TYPE_MANAGEMENT,对于scan的帧将会触发HIF_RX_PKT_TYPE_MANAGEMENT的分支,然后调用nicRxProcessMgmtPacket的调用。

nicRxProcessMgmtPacket函数解析

1.nicRxFillRFB

获取管理帧的subtype来判断是属于什么类型的管理帧。

各种类型的帧对应的函数表在apfnProcessRxMgtFrame中,根据ucSubtype就可以调用到需要的方法。

对于scan的操作将会调用scanProcessBeaconAndProbeResp该方法。

scanProcessBeaconAndProbeResp函数解析

不管是接收到subtype为5(beacon帧)或者是8(proberesponse帧)都会调用到该函数。

1)检测帧是否正常一个beacon帧除了要有MACHEADER还需要TIMESTAMP_FIELD、BEACON_INTERVAL_FIELD、CAP_INFO_FIELD总长度为:

12byte,所以检测就将报文体-macheader是否大于12byte即可。

2)获取帧结构prWlanBeaconFrame=(P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;

3)解析beacon帧的同时添加到bss_desclist中(scanAddToBssDesc)

3.1遍历IE中,只处理ssid(ssid最长为32位),拷贝ssid到rssid中

3.2调用scanSearchExistingBssDescWithSsid

3.3

如果当前prScanInfo->rBSSDescList中不存在该BssDesc的话,则从prScanInfo->rFreeBSSDescList获取一个prBssDesc,设置成0,之后插入prScanInfo->rBSSDescList队列中。

如果分配失败的话,则执行scanRemoveBssDescsByPolicy,策略是:

SCN_RM_POLICY_EXCLUDE_CONNECTED|SCN_RM_POLICY_OLDEST_HIDDEN意思是:

将最老的HIDDEN的ap移除,对于正在连接的不移除。

然后再进行分配prBssDesc。

如果再次分配失败的话,则再次调用scanRemoveBssDescsByPolicy,策略为:

SCN_RM_POLICY_EXCLUDE_CONNECTED|SCN_RM_POLICY_SMART_WEAKEST意思是:

移掉信号最差的AP,之后再次尝试realloc。

如果当前prScanInfo->rBSSDescList中存在该BssDesc的话,则从获取当前系统时间,然后查看查找到的跟当前搜索到的类型是否一致,如果不一致,则将搜索到的prBssDesc的eBSSType改为新的eBSSType,否则,则看下当前beacon帧中,信道是否跟搜索到的bssdesc中的信道是否一致并且搜索到的bssdesc中的信号比beacon帧中的信号强度还大的话,则进一步检测搜索到的bssdesc中的信号强度超过beacon帧中的信号强度的32,并且当前时间减去搜索到的bssdesc中的上次更新时间小于10s,则直接返回当前搜索到的bssdesc,否则如果更新时间小于3s,则也是直接反馈当前搜索到的bssdesc。

如果都没返回的话,则继续往下执行。

如果beacon帧的时间戳,小于搜索到的bssdesc并且网络为BSS_TYPE_INFRASTRUCTURE,则会重新创造一个新的bssdesc。

3.4将beacon帧中包的大小更

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 管理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1