linuxwifi分析源碼,madwifi無線網(wǎng)卡源代碼閱讀_第1頁
linuxwifi分析源碼,madwifi無線網(wǎng)卡源代碼閱讀_第2頁
linuxwifi分析源碼,madwifi無線網(wǎng)卡源代碼閱讀_第3頁
linuxwifi分析源碼,madwifi無線網(wǎng)卡源代碼閱讀_第4頁
linuxwifi分析源碼,madwifi無線網(wǎng)卡源代碼閱讀_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

linuxwifi分析源碼,madwifi?線?卡源代碼閱讀在我的Doctor課題研究中,基于ARF協(xié)議設計了?個改進型的AMARF協(xié)議,該?發(fā)表在milcom06和電?科學學刊英?版上。最近,我們將PC機上,使?linux操作系統(tǒng),基于madwifi開源代碼實現(xiàn)了AMARF協(xié)議,已經在室內固定以及移動環(huán)境測試表明,AMARF協(xié)議明顯優(yōu)越于現(xiàn)有的協(xié)議。2008-9-20現(xiàn)在使?了madwifi程序實現(xiàn)AMARF協(xié)議,下?分析其代碼。使?iwconfig命令可以設置速率:1、iwconfig源代碼閱讀?先下載iwconfig.c代碼,源代碼包為\wireless_tools.29?錄先看執(zhí)?iwconfigeth0的命令的執(zhí)?過程:調?main函數(shù),因為是兩個參數(shù):if(argc==2)print_info(skfd,argv[1],NULL,0);print_info調?get_info(intskfd,char*ifname,structwireless_info*info)將?卡的各種信息打印出來。下?與打印發(fā)送速率為例,說明調?過程,get_info函數(shù)??:/*Getbitrate*/if(iw_get_ext(skfd,ifname,SIOCGIWRATE,&wrq)>=0){info->has_bitrate=1;memcpy(&(info->bitrate),&(wrq.u.bitrate),sizeof(iwparam));}對信息的獲取都是通過iw_get_ext函數(shù)來實現(xiàn)的,通過參數(shù)SIOCGIWRATE來識別不同的內容iwlib.h?件定義了iw_get_ext:iw_get_ext(intskfd,/*Sockettothekernel*/constchar*ifname,/*Devicename*/intrequest,/*WEID*/structiwreq*pwrq)/*Fixedpartoftherequest*/{

/*Setdevicename*/strncpy(pwrq->ifr_name,ifname,IFNAMSIZ);/*Dotherequest*/return(ioctl(skfd,request,pwrq));}因此,真正對?卡其他參數(shù)的實現(xiàn)是通過ioctl函數(shù)實現(xiàn)的,ioctl是驅動程序的基本功能,因此,如果??想編寫?個對?卡參數(shù)設置的程序,也應該使?ioctl函數(shù)。下?在看使?iwconfigeth0rateauto命令執(zhí)?情況main函數(shù),當輸?參數(shù)?于2的時候,調?:goterr=set_info(skfd,argv+2,argc-2,argv[1]);set_info函數(shù)調?iwcmd=find_command(args[0]);?來查找命令,所有的命令都存放在?個表中,只要查找這個表即可:staticconststructiwconfig_entryiwconfig_cmds[]={……….{"bit",set_bitrate_info,1,SIOCSIWRATE,"SetBitRate","{N[k|M|G]|auto|fixed}"},{"rate",set_bitrate_info,1,SIOCSIWRATE,"SetBitRate","{N[k|M|G]|auto|fixed}"},當?shù)谌齻€參數(shù)為rate的時候,就會?動調?set_bitrate_info函數(shù),該函數(shù)的定義為:set_bitrate_infoif(!strcasecmp(args[0],"auto")){wrq.u.bitrate.value=-1;wrq.u.bitrate.fixed=0;//如果輸?是auto,那么設置為bitrate.value=-1;}else{if(!strcasecmp(args[0],"fixed")){/*Getoldbitrate*/if(iw_get_ext(skfd,ifname,SIOCGIWRATE,&wrq)<0)return(IWERR_GET_EXT);

wrq.u.bitrate.fixed=1;}……………if(iw_set_ext(skfd,ifname,SIOCSIWRATE,&wrq)<0)return(IWERR_SET_EXT);也就是說,如果選擇auto,那么設置變量bitrate.fixed=0,最后調?iw_set_ext(skfd,ifname,SIOCSIWRATE,&wrq)函數(shù),這個函數(shù)也是直接與?卡相關的。與iw_get_ext函數(shù)?樣,iw_set_ext也是通過SIOCGIWRATE來識別的:staticinlineintiw_set_ext(intskfd,/*Sockettothekernel*/constchar*ifname,/*Devicename*/intrequest,/*WEID*/structiwreq*pwrq)/*Fixedpartoftherequest*/{/*Setdevicename*/strncpy(pwrq->ifr_name,ifname,IFNAMSIZ);/*Dotherequest*/return(ioctl(skfd,request,pwrq));}2、madiwifi驅動和硬件說明該說明來源于“IEEE802.11RateAdaptation:APracticalApproach”該?主要提出了AMRR算法。本??先談到是否能夠基于包級的速率控制需要看硬件是否?持,有些芯?在硬件??包含了CPU,TexasInstrumentsaroundanARMcore,WaveLAN802.11b,因此具有低的延時。然?,Atheros802.11chipsets芯?不包含CPU,需要主機CPU來完成很多的MAC功能,?主機CPU很難實現(xiàn)實時的控制,基于包的速率控制是不可?的,認為是?延時的?類。ARF算法和AARF算法、以及AMARF都是基于低延時的控制算法,Atheros的linux驅動,稱為MultibandAtherosDriverforWiFi(MadWiFi),可以在SourceForge上找到源代碼,使?了HAL(硬件抽象層的概念),與硬件有關的部分是進制的代碼,不提供源代碼。Atheros硬件允許?戶創(chuàng)建9個發(fā)送FIFIO描述符,對發(fā)送進?調度;每個發(fā)送描述符包含了發(fā)送狀況,數(shù)據(jù)的指針和長度,并且包含了?個4對的“速率/重傳次數(shù)”對(r0/c0,r1/c1,r2/c2,r3/c3)。當?線信道可以發(fā)送的時候,硬件將引發(fā)處于FIFO頭的數(shù)據(jù)的發(fā)送,?先以速率r0發(fā)送,如果發(fā)送失敗,繼續(xù)以速率r0發(fā)送c0-1次,然?再次以速率r1發(fā)送,如果發(fā)送失敗,繼續(xù)以速率r1發(fā)送c1-1次……如果發(fā)送失敗了c0+c1+c2+c3次,那么放棄這次發(fā)送。當發(fā)送完畢,或者發(fā)送放棄,硬件會在發(fā)送描述符中報告本次發(fā)送丟失的ACK的數(shù)?,因此,通過獲知丟失的ACK的數(shù)?可以間接的得到本次的發(fā)送速率。MadWiFi的這個機制稱為MultiRateRetrymechanism。

3、onoe?適應速率說明該說明來源于“Bit-rateSelectioninWirelessNetworks“,JohnC.Bicket,MIT碩?論?P29該?主要提出了SampleRate算法,也對其他的算法進?了說明。onoe對每個包的失敗與否并不敏感,試圖找到丟幀率?于50%的最?速率;對于每個?的連接,onoe保存了?個當前鏈路的?特速率、以及該?特率的信?度;算法跟蹤每個鏈路當前?特速率的信?度,如果丟包率較?,那么增加該信?度;如果該信?度達到?定的閾值,那么嘗試增加信?度;如果發(fā)?了?些錯誤,那么該信?度復位,速率下降。當?shù)?次發(fā)送到?的地址的時候,將初始的速率設置為24M(802.11a/g),11M(802.11b);onoe周期性的執(zhí)?算法(缺省值為1秒)1)如果沒有數(shù)據(jù)發(fā)送成功,降低到下?個速率;2)如果發(fā)送了10個以上的包,并且每個包的平均重傳次數(shù)?于1,降低到下?個速率;3)如果超過10%的包需要重傳,將信?值減?(保持?于0),4)如果少于10%的包需要重傳,增加信?值;次數(shù)5)如果信?值?于10,增加速率;相關代碼為://每次發(fā)送完數(shù)據(jù)后,都會調?該函數(shù),來判斷發(fā)送的結果,成功還是失敗,以及重傳的次數(shù)voidath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structonoe_node*on=ATH_NODE_ONOE(an);if(ds->ds_txstat.ts_status==0)//如果ts_status為0,表明發(fā)送成功on->on_tx_ok++;//統(tǒng)計發(fā)送成功和發(fā)送失敗的次數(shù),elseon->on_tx_err++;on->on_tx_retr+=ds->ds_txstat.ts_shortretry//統(tǒng)計重傳的次數(shù),長重傳加上短重傳,適?于不同的長度,?般來說應該是?個為0,?另外?個不為0,+ds->ds_txstat.ts_longretry;if(jiffies>=on->on_nextcheck){//判斷現(xiàn)在的時間,每?約1秒鐘執(zhí)??次速率控制ath_rate_ctl(sc,&an->an_node);/*XXXhalverateforstationmode*/on->on_nextcheck=jiffies+(ath_rateinterval*HZ)/1000;//ath_rateinterval定義為1000,}}//這個是速率控制函數(shù)staticvoidath_rate_ctl(void*arg,structieee80211_node*ni)

{structath_softc*sc=arg;structonoe_node*on=ATH_NODE_ONOE(ATH_NODE(ni));structieee80211_rateset*rs=&ni->ni_rates;intdir=0,nrate,enough;sc->sc_stats.ast_rate_calls++;/**Ratecontrol*XXX:veryprimitiveversion.*/enough=(on->on_tx_ok+on->on_tx_err>=10);//這兩參數(shù)是從ath_rate_tx_complete中獲得的,onoe算法要統(tǒng)計10次以上的發(fā)送結果才?有動作/*nopacketreached->down*/if(on->on_tx_err>0&&on->on_tx_ok==0)//如果壓根就沒有任何?次發(fā)送成功,速率控制的?向是遞減,也就是算法中的第?中情況dir=-1;/*allpacketsneedsretryinaverage->down*/if(enough&&on->on_tx_ok<on->on_tx_retr)//就是算法中的第?種情況,基本上所有的包都需要重傳,降低速率dir=-1;//ath_rate_raise初始值定義為10,判斷?于10%的?個變量//如果沒有發(fā)?傳輸失敗,并且少于10%的包需要重傳,增加速率,也就是第四鐘情況/*noerrorandlessthanrate_raise%ofpacketsneedretry->up*/if(enough&&on->on_tx_err==0&&on->on_tx_retr<(on->on_tx_ok*ath_rate_raise)/100)dir=1;DPRINTF(sc,"%s:ok%derr%dretr%dupper%ddir%d\n",ether_sprintf(ni->ni_macaddr),on->on_tx_ok,on->on_tx_err,on->on_tx_retr,on->on_tx_upper,dir);nrate=ni->ni_txrate;//?前使?的速率,實際上是?個?于等于0的編號switch(dir){case0://不增加也不減少if(enough&&on->on_tx_upper>0)on->on_tx_upper--;//on_tx_upper定義為信?值

//如果發(fā)送超過了10次,并且超過10%的包需要重傳,信?值on_tx_upper減?break;case-1://減少速率,if(nrate>0){nrate--;//如果?于0,減?速率sc->sc_stats.ast_rate_drop++;}on->on_tx_upper=0;//將信?值復位置0break;case1:/*raiserateifwehitrate_raise_threshold*/if(++on->on_tx_upper<ath_rate_raise_threshold)break;//信?值加1,如果信?值沒有達到閾值,那么直接退出,on->on_tx_upper=0;//否則,增加速率,將信?值復位置0if(nrate+1<rs->rs_nrates){nrate++;sc->sc_stats.ast_rate_raise++;}break;}if(nrate!=ni->ni_txrate){//如果速率發(fā)?了改變,更新速率DPRINTF(sc,"%s:%dM->%dM(%dok,%derr,%dretr)\n",__func__,(rs->rs_rates[ni->ni_txrate]&IEEE80211_RATE_VAL)/2,(rs->rs_rates[nrate]&IEEE80211_RATE_VAL)/2,on->on_tx_ok,on->on_tx_err,on->on_tx_retr);ath_rate_update(sc,ni,nrate);}elseif(enough)//如果速率沒有發(fā)?改變,發(fā)送次數(shù)已經?約10次了,重新復位on->on_tx_ok=on->on_tx_err=on->on_tx_retr=0;//復位}//速率更新的代碼staticvoidath_rate_update(structath_softc*sc,structieee80211_node*ni,intrate){

//ath_rate_ctl函數(shù)僅僅是確定了合適使?的速率,然?,atheor?卡需要在發(fā)送描述符中寫?r0/c0,r1/c1,r2/c2,r3/c3四個速率和retry對,如果填充這四個發(fā)送對呢?r0速率,就是判斷的最佳發(fā)送速率,r1就是最佳速率的下?個速率(如果r0已經是最低速率,那么r1為0);r2是r1的下?個速率,r3是r2的下?個速率,對于retry次數(shù),分別設置為4,2,2,2on->on_tx_rix0=sc->sc_rixmap[ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];on->on_tx_rate0=rt->info[on->on_tx_rix0].rateCode;on->on_tx_try0=1+3;/*4triesatrate0*///速率r0的設置,就是最佳速率rateif(--rate>=0){//速率r1的設置,就是最佳速率rate的下?個速率rix=sc->sc_rixmap[ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];on->on_tx_rate1=rt->info[rix].rateCode;on->on_tx_rate1sp=on->on_tx_rate1|rt->info[rix].shortPreamble;}elseon->on_tx_rate1=on->on_tx_rate1sp=0;……….速率r1/c1,r2/c2,r3/c3是通過ath_rate_setupxtxdesc函數(shù)寫?硬件的,這是與硬件相關的函數(shù),ath_rate_setupxtxdesc(structath_softc*sc,structath_node*an,structath_desc*ds,intshortPreamble,size_tframe_size,u_int8_trix){structonoe_node*on=ATH_NODE_ONOE(an);ath_hal_setupxtxdesc(sc->sc_ah,ds,on->on_tx_rate1sp,2/*series1*/,on->on_tx_rate2sp,2/*series2*/,on->on_tx_rate3sp,2/*series3*/);}速率r0/c0是通過ath_hal_setuptxdesc函數(shù)寫?硬件的,ath_hal_setuptxdesc(ah,ds,pktlen/*packetlength*/,hdrlen/*headerlength*/,atype/*Atherospackettype*/,MIN(ni->ni_txpower,60)/*txpower*/,txrate,try0/*series0rate/tries*/,keyix/*keycacheindex*/

先看ath_rate_tx_complete函數(shù),每次發(fā)送后是如何處理的,該函數(shù)在if_ath.c中每次ath_tx_start函數(shù)進?發(fā)送的時候調?通過上?的分析,我們認為實際上使?的發(fā)送速率就是r0,那么如何獲取呢?速率控制的驅動中有?個函數(shù):voidath_rate_findrate(structath_softc*sc,structath_node*an,intshortPreamble,size_tframeLen,u_int8_t*rix,int*try0,u_int8_t*txrate){structonoe_node*on=ATH_NODE_ONOE(an);*rix=on->on_tx_rix0;*try0=on->on_tx_try0;if(shortPreamble)*txrate=on->on_tx_rate0sp;else*txrate=on->on_tx_rate0;}返回的txrate就是實際上使?的on->on_tx_rate0,r0該函數(shù)也在if_ath.c中每次ath_tx_start函數(shù)進?發(fā)送的時候調?,這個函數(shù)雖然參數(shù)很多,但是查看代碼,只有structath_node*an的輸?代碼是有效的,shortPreamble是否為短符號,可以不考慮,設置為0.因此,需要修改ioctl部分的函數(shù),將auto部分返回-1的代碼,修改為調?ath_rate_findrat函數(shù),調?該函數(shù)的關鍵就是如何獲取structath_node*an參數(shù)。4、AMRR代碼閱讀AMRR是onoe的改進,使?了?進制避退(BEB)的概念,來適應改變rn/cn的周期,為了適應快速變化的?線信道,設置c0=c1=c2=c3=1,速率r3設置為最?可?速率(6Mbps802.11a),?r1和r2由r0決定,也就是r1為r0的下?個低速率,r2為r1的下?個低速率;因此,核?是改變r0。AMRR使?了?個定時器來周期性的進?速率控制,時間設置為1秒。staticvoidath_ratectl(unsignedlongdata){……..asc->timer.expires=jiffies+((HZ*interval)/1000);add_timer(&asc->timer);}void

ath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structamrr_node*amn=ATH_NODE_AMRR(an);intsr=ds->ds_txstat.ts_shortretry;intlr=ds->ds_txstat.ts_longretry;intretry_count=sr+lr;//這個變量表明重傳的次數(shù),需要注意c0=c1=c2=c3=1,因此,重傳次數(shù)最多為4次,amn->amn_tx_try0_cnt++;//amn->amn_tx_try0_cnt變量為使?速率r0發(fā)送的次數(shù),因為c0=1,每次發(fā)送,都會并且只會使//?r0發(fā)送?次,因此,這個變量還可以同時表?發(fā)送的包的個數(shù)(包括成功和失敗的)if(retry_count==1){//如果重傳次數(shù)是?次,由于c0=c1=c2=c3=1,必然可以得出使?速率r0發(fā)送了?次,失敗之后,?使?速率r1發(fā)送了?次amn->amn_tx_try1_cnt++;}elseif(retry_count==2){//同理可以得出如果重傳次數(shù)是2次,由于c0=c1=c2=c3=1,必然可以得出使?速率r0發(fā)送了?次,失敗之后,?使?速率r1發(fā)送了?次,再使?r2發(fā)送了?次amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;}elseif(retry_count==3){amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;amn->amn_tx_try3_cnt++;}elseif(retry_count>3){//如果次數(shù)為4次,說明各個速率都嘗試過,并且最后都發(fā)送都失敗了。amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;amn->amn_tx_try3_cnt++;amn->amn_tx_failure_cnt++;}}staticvoidath_rate_ctl(void*arg,structieee80211_node*ni){structath_softc*sc=arg;

structamrr_node*amn=ATH_NODE_AMRR(ATH_NODE(ni));intold_rate;#defineis_success(amn)(amn->amn_tx_try1_cnt<(amn->amn_tx_try0_cnt/10))如果發(fā)送包的中?于10%的包出現(xiàn)了重傳,那么認為上次速率設置發(fā)送是成功的,#defineis_enough(amn)(amn->amn_tx_try0_cnt>10)如果發(fā)送包的個數(shù)?于10,認為是?夠進?判斷了#defineis_failure(amn)(amn->amn_tx_try1_cnt>(amn->amn_tx_try0_cnt/3))如果發(fā)送包中出現(xiàn)?約33%的包需要重傳,那么認為上次速率設置是失敗的#defineis_max_rate(ni)((ni->ni_txrate+1)>=ni->ni_rates.rs_nrates)#defineis_min_rate(ni)(ni->ni_txrate==0)old_rate=ni->ni_txrate;if(is_success(amn)&&is_enough(amn)){//如果發(fā)送成功,將成功的計數(shù)器加1amn->amn_success++;if(amn->amn_success==amn->amn_success_threshold&&!is_max_rate(ni)){如果計數(shù)器達到閾值,那么將速率增加,并且設置?個變量,amn_recovery=1,表明處于嘗試速率增加階段amn->amn_recovery=1;amn->amn_success=0;ni->ni_txrate++;DPRINTF(sc,"increaserateto%d\n",ni->ni_txrate);}elseamn->amn_recovery=0;}elseif(is_failure(amn)){如果發(fā)送失敗,成功的計數(shù)器清零。amn->amn_success=0;if(!is_min_rate(ni)){if(amn->amn_recovery){/*recoveryfailure.*/如果處于是處于嘗試速率增加階段,那么將閾值翻倍,amn->amn_success_threshold*=2;amn->amn_success_threshold=min(amn->amn_success_threshold,(u_int)ath_rate_max_success_threshold);DPRINTF(sc,"decreaseraterecoverythr:%d\n",

amn->amn_success_threshold);}else{/*simplefailure.*/否則,如果處于正常情況下的失敗,將閾值設置為最?amn->amn_success_threshold=ath_rate_min_success_threshold;DPRINTF(sc,"decreaseratenormalthr:%d\n",amn->amn_success_threshold);}amn->amn_recovery=0;ni->ni_txrate--;}elseamn->amn_recovery=0;}}可以看出來,AMRR協(xié)議類似于AARF,每次嘗試速率增加的時候,如果嘗試失敗,將閾值翻倍。5、SampleRate?適應速率說明該說明來源于“Bit-rateSelectioninWirelessNetworks“,JohnC.Bicket,MIT碩?論?P29該?主要提出了SampleRate算法,也對其他的算法進?了說明。該算法周期性的發(fā)送其他速率的包進?探詢,看其他速率發(fā)送是否合適。本?認為速率選擇算法需要考慮?下?個??:1)不能認為因為如果某低速率性能性能差,那么?它??級的速率會性能更差(3.5章節(jié)的說明)2)最?吞吐量的算法可能丟包率也多,丟包率?的速率可能吞吐量未必最?(3.2節(jié))3)鏈路狀態(tài)是會發(fā)?變化的,不能對鏈路狀態(tài)進?反映,會導致低的吞吐量;4)速率選擇算法必須要?效,不能嘗試所有的速率;6、AMARF協(xié)議的實現(xiàn)AMARF協(xié)議是ARF協(xié)議的改進,核?是給每個速率設置?個不同的閾值,閾值的??可以?適應的變化,因此,AMARF適?于信道快速變化的場合。使?madwifi可能存在的問題:1)madwifi屬于?延時的系統(tǒng),是否能夠進?每個包的控制,另外如何控制FIFIO?2)madwifi驅動本?提供了多速率多重傳的機制,如何利??因此,我們提出兩種?法:純粹的P-AMARF,結合madwifi的M-AMARF?先分析P-AMARF:還是從ath_rate_tx_complete函數(shù)看其,每次發(fā)送后是如何處理的。

上?的?個算法都是周期性的對速率進?控制,引?了定時器,每次發(fā)送之后僅僅是對速率進?統(tǒng)計,我們的算法需要進?快速的調整速率,每次發(fā)送完之后都進?控制!!voidath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structamarf_node*arn=ATH_NODE_AMARF(an);arn->amarf_txok=!(ds->ds_txstat.ts_status);//判斷是否發(fā)送成功//printk("txokis%d\n",arn->amarf_txok);ath_rate_ctl(sc,&an->an_node);}staticvoidath_rate_ctl(void*arg,structieee80211_node*ni){structath_softc*sc=arg;structamarf_node*arn=ATH_NODE_AMARF(ATH_NODE(ni));intold_rate;sc->sc_stats.ast_rate_calls++;#defineis_max_rate(ni)((ni->ni_txrate+1)>=ni->ni_rates.rs_nrates)#defineis_min_rate(ni)(ni->ni_txrate==0)/*ni_txrate:indextoni_rates[]*/old_rate=ni->ni_txrate;if(arn->amarf_txok){if(arn->amarf_counter_success>=amarf_th[ni->ni_txrate]){arn->amarf_counter_success=0;amarf_th[ni->ni_txrate]+=amarf_c;DEBUG2("amarf_cis%f\n",amarf_c);if(!is_max_rate(ni)){ni->ni_txrate++;DEBUG2("increaseto%d\n",ni->ni_txrate);arn->amarf_isprobe=1;}}elsearn->amarf_counter_success++;arn->amarf_isprobe=0;//DEBUG2("consecutivecounter_successis%d\n",arn->amarf_counter_success);

}else{arn->amarf_counter_success=0;if(arn->amarf_isprobe==1)amarf_th[ni->ni_txrate]-=amarf_a;DEBUG2("amarf_ais%f\n",amarf_a);elseamarf_th[ni->ni_txrate]-=amarf_b;DEBUG2("amarf_bis%f\n",amarf_b);if(!is_min_rate(ni)){ni->ni_txrate--;DEBUG2("decreaseto%d\n",ni->ni_txrate);}arn->amarf_isprobe=0;}if(ni->ni_txrate!=old_rate)ath_rate_update(sc,ni,ni->ni_txrate);}7、madwifi驅動閱讀該程序有好?個?錄ath:物理?卡的控制函數(shù),例如發(fā)送等ath_rate:速率控制的相關代碼hal:硬件抽象層的相關庫,不公開源代碼net80211:802.11相關的代碼,與物理層獨?,完成諸如scan、wap、VAP等功能。Ieee80211_wireless.cstaticconstiw_handlerieee80211_handlers[]={(iw_handler)ieee80211_ioctl_siwrate,/*SIOCSIWRATE*/(iw_handler)ieee80211_ioctl_giwrate,/*SIOCGIWRATE*/模塊的??函數(shù):if_ath_pci.c/module_init(init_ath_pci);staticint__initinit_ath_pci(void){

printk(KERN_INFO"%s:%s\n",dev_info,version);if(pci_register_driver(&ath_pci_drv_id)<0){printk("ath_pci:Nodevicesfound,drivernotinstalled.\n");return(-ENODEV);}#ifdefCONFIG_SYSCTLath_sysctl_register();#endifreturn(0);}module_init(init_ath_pci);初始化會調?ath_pci_probe(structpci_dev*pdev,conststructpci_device_id*id)函數(shù),進?步加載ath?線?卡:if(ath_attach(vdevice,dev)!=0)gotobad4;If_ath.c(ath)?件實現(xiàn)ath_attach函數(shù),該函數(shù)的實現(xiàn)?常復雜,關鍵的代碼如下:ath_attach(u_int16_tdevid,structnet_device*dev){……………ah=_ath_hal_attach(devid,sc,NULL,(void*)dev->mem_start,&status);可能是探測與硬件相關的東西,不能顯?更進?步的代碼:………………..dev->hard_start_xmit=ath_hardstart;dev->do_ioctl=ath_ioctl;ieee80211_ifattach(ic);該函數(shù)在Ieee80211.c?件中實現(xiàn)ic->ic_vap_create=ath_vap_create;ic->ic_vap_delete=ath_vap_delete;重點需要掌握ath與80211?錄的關聯(lián),ath_vap_create是做什么的。staticstructieee80211vap*ath_vap_create(structieee80211com*ic,constchar*name,intunit,intopmode,intflags,structnet_device*mdev){……ieee80211_vap_setup(ic,dev,name,unit,opmode,flags);………….

(void)ieee80211_vap_attach(vap,ieee80211_media_change,ieee80211_media_status);Ieee80211_wireless.cieee80211_vap_setup(structieee80211com*ic,structnet_device*dev,constchar*name,intunit,intopmode,intflags)->調?下?的函數(shù),實現(xiàn)ioctl函數(shù),ieee80211_ioctl_vattach(structieee80211vap*vap){structnet_device*dev=vap->iv_dev;dev->do_ioctl=ieee80211_ioctl;這?就存在兩次對dev->do_ioctl賦值的情況,?次是在ath_attach函數(shù)中,?次在ieee80211_ioctl_vattach函數(shù)中,懷疑第?次是不是就將第?次的覆蓋了。ieee80211_ioctl函數(shù)就有很多的?函數(shù)?以實現(xiàn)不同的功能,以設置和獲取速率為例:ieee80211_ioctl_siwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra)獲取速率的ioctl函數(shù)的實現(xiàn)ieee80211_ioctl_giwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra){structieee80211vap*vap=dev->priv;structifmediareqimr;intrate;memset(&imr,0,sizeof(imr));vap->iv_media.ifm_status(vap->iv_dev,&imr);rrq->fixed=IFM_SUBTYPE(vap->iv_media.ifm_media)!=IFM_AUTO;/*mediastatuswillhavethecurrentxmitrateifavailable*/rate=ieee80211_media2rate(imr.ifm_active);//這個函數(shù)的意思是將速率編號轉換為實際的速率if(rate==-1)/*IFM_AUTO*/rate=0;//如果是auto,那么就返回0rrq->value=1000000*(rate/2);return0;}有關于速率的東西都在ifm_active變量中,這個變量包含了很多的屬性,包括速率、模式等等,在if_media.h?件中#defineIFM_IEEE80211_DS15/*DirectSequence1Mbps*/

#defineIFM_IEEE80211_DS26/*DirectSequence2Mbps*/#defineIFM_IEEE80211_DS57/*DirectSequence5.5Mbps*/#defineIFM_IEEE80211_DS118/*DirectSequence11Mbps*/函數(shù)ieee80211com_media_status實現(xiàn)獲得ifm_active變量ieee80211com_media_status(structnet_device*dev,structifmediareq*imr){structieee80211com*ic=dev->priv;/*XXX*/imr->ifm_status=IFM_AVALID;if(!TAILQ_EMPTY(&ic->ic_vaps))imr->ifm_status|=IFM_ACTIVE;imr->ifm_active=media_status(ic->ic_opmode,ic->ic_curchan);}通過上述分析,發(fā)現(xiàn)ifm_active變量的獲得實際上是ieee80211com*ic結構體獲得的。數(shù)據(jù)發(fā)送過程分析:staticintath_hardstart(structsk_buff*skb,structnet_device*dev)->ath_tx_start(structnet_device*dev,structieee80211_node*ni,structath_buf*bf,structsk_buff*skb,intnextfraglen){……….ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);//有關速率控制的東西………ath_hal_setuptxdesc(ah,ds,pktlen/*packetlength*/,hdrlen/*headerlength*/,atype/*Atherospackettype*/,MIN(ni->ni_txpower,60)/*txpower*/,txrate,try0/*series0rate/tries*/,keyix/*keycacheindex*/,antenna/*antennamode*/,flags/*flags*/,ctsrate/*rts/ctsrate*/,ctsduration/*rts/ctsduration*/,icvlen/*compicvlen*/

,ivlen/*compivlen*/,comp/*compscheme*/);//與硬件相關的函數(shù)if(try0!=ATH_TXMAXTRY)ath_rate_setupxtxdesc(sc,an,ds,shortPreamble,skb->len,rix);//速率控制的描述符}8、有關速率獲取的問題通過上?的代碼分析,我們認為在madwifi情況下,r0就是實際的速率,因此,需要在應?層能夠獲得r0的指,經過跟蹤,發(fā)現(xiàn)當調?iwconfig命令,來獲取速率的值的時候,會調?ieee80211_ioctl_giwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra){structieee80211vap*vap=dev->priv;現(xiàn)在當使?auto的?適應速率時候,?動返回-1,因此,獲得速率值為0.因此,需要修改這個函數(shù),調?ARMARF?適應速率的ath_rate_findrate函數(shù)通過上?的分析,我們認為實際上使?的發(fā)送速率就是r0,那么如何獲取呢?速率控制的驅動中有?個函數(shù):voidath_rate_findrate(structath_softc*sc,structath_node*an,intshortPreamble,size_tframeLen,u_int8_t*rix,int*try0,u_int8_t*txrate){structonoe_node*on=ATH_NODE_ONOE(an);*rix=on->on_tx_rix0;*try0=on->on_tx_try0;if(shortPreamble)*txrate=on->on_tx_rate0sp;else*txrate=on->on_tx_rate0;}返回的txrate就是實際上使?的on->on_tx_rate0,r0該函數(shù)為實際上只有structath_node*an參數(shù)是需要傳遞的,ieee80211_ioctl_giwrate輸?的參數(shù)為net_device*dev,因此,需要將該輸?參數(shù)轉換得到structath_node*an參數(shù):因此,我們需要關注三個結構體:

structnet_device*dev結構體包含了ieee80211vap*vap結構體:ieee80211vap*vap=dev->priv;an=ATH_NODE(ni);structath_softc{structieee80211comsc_ic;/*NB:mustbefirst*/structnet_device*sc_dev;structsemaphoresc_lock;/*dev-levellock*/structath_node{structieee80211_nodean_node;/*baseclass*/u_int16_tan_decomp_index;/*decompressionmaskindex*/u_int32_tan_avgrssi;/*averagerssioverallrxframes*/u_int8_tan_prevdatarix;/*rateixoflastdataframe*/u_int16_tan_minffrate;/*mimumrateinkbpsforfftoaggragate*/HAL_NODE_STATSan_halstats;/*rssistatisticsusedbyhal*/structath_buf*an_tx_ffbuf[WME_NUM_AC];/*ffstagingarea*/ath_bufheadan_uapsd_q;/*U-APSDdeliveryqueue*/intan_uapsd_qdepth;/*U-APSDdeliveryqueuedepth*/ath_bufheadan_uapsd_overflowq;/*U-APSDoverflowqueue(for>MaxSpframes)*/intan_uapsd_overflowqdepth;/*U-APSDoverflowqueuedepth*/spinlock_tan_uapsd_lock;/*U-APSDdeleiveryqueuelock*//*variable-lengthratecontrolstatefollows*/};structieee80211_node{structieee80211vap*ni_vap;structieee80211com*ni_ic;structieee80211_node_table*ni_table;…………..structieee80211vap{structnet_device*iv_dev;/*associateddevice*/structnet_device_statsiv_devstats;/*interfacestatistics*/structifmediaiv_media;/*interfacemediaconfig*/#ifdefCONFIG_NET_WIRELESSstructiw_statisticsiv_iwstats;/*wirelessstatisticsblock*/#endif

…………structieee80211com*iv_ic;/*backptrtocommonstate*/……………下?三個結構體的包含關系為:ath_node->ieee80211_node->ieee80211vap并且由于?地址是?樣的,因此,只要獲得任意?個結構體,可以使?指針強制轉換為另外兩個結構體,例如已知ieee80211_node結構體,可以獲得ath_node,在if_ath.c的ath_tx_start函數(shù)中,使?an=ATH_NODE(ni)命令獲得,#defineATH_NODE(_n)((structath_node*)(_n))structath_softc*sc=dev->priv;structieee80211com*an=dev->priv;ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);調試中發(fā)現(xiàn),始終不能正確的傳遞參數(shù),經過調試,發(fā)現(xiàn)ieee80211.c和if_ath.c代碼的structnet_device變量是不?樣的,兩者的參數(shù)名字分別為ath0和wifi0,也就是兩個?絡設備的名字,因此,沒有辦法傳遞參數(shù)。下?還是分析iwconfig中的參數(shù)是如何傳遞的,以ieee80211_ioctl_siwpower函數(shù)為例,設置發(fā)送功率。ieee80211_ioctl_siwpower(structnet_device*dev,structiw_request_info*info,structiw_param*wrq,char*extra){structieee80211vap*vap=dev->priv;structieee80211com*ic=vap->iv_ic;……………..returnIS_UP(ic->ic_dev)?ic->ic_reset(ic->ic_dev):0;如果設備已經UP,那么以新的參數(shù)對設備設置。這??調?了?個函數(shù)指針,ic->ic_reset,經過檢查,只有if_ath.c?件調?了,if_ath.c(692):ic->ic_reset=ath_reset;ath_attach(u_int16_tdevid,structnet_device*dev){structath_softc*sc=dev->priv;structieee80211com*ic=&sc->sc_ic;structath_hal*ah;………….ic->ic_reset=ath_reset;ath_reset(structnet_device*dev){structath_softc*sc=dev->priv;structieee80211com*ic=&sc->sc_ic;

structath_hal*ah=sc->sc_ah;structieee80211_channel*c;HAL_STATUSstatus;iwconfig命令會最終調?ieee80211_wireless.c中的各種參數(shù)設置和控制命令,查看代碼,發(fā)現(xiàn)ieee80211_wireless中本?定義了很多的參數(shù)變量,如果需要設置,再調?底層的函數(shù)將參數(shù)寫??卡芯?,如果讀參數(shù),就直接讀??已經保存好的參數(shù),?并不是讀真正的物理層的參數(shù)!ieee80211_ioctl_siwpower代碼最終會調?ath_reset,這兩個函數(shù)的輸?參數(shù)都是structnet_device*dev,他是如何進?參數(shù)轉換的呢?將ath0變?yōu)閣ifi0?Iwconfig中,?先由輸?參數(shù)ath0(structnet_device*dev)獲得vapstructieee80211vap*vap=dev->priv;該結構體定義為:structieee80211vap{structnet_device*iv_dev;/*associateddevice*/structieee80211com*iv_ic;/*backptrtocommonstate*/……………然后由vap獲得ic,structieee80211com*ic=vap->iv_ic;?該結構體定義為:structieee80211com{structnet_device*ic_dev;/*associateddevice*/?關聯(lián)了?個net_device設備,這個設備正是wifi0,因此,調?ic_reset的時候,并不是直接將ieee80211_ioctl_siwpower的輸出參數(shù)dev放進去,?是轉了兩個彎,ic->ic_reset(ic->ic_dev)。再次回到獲取速率的函數(shù),調?下?的函數(shù)獲得速率,ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);這?,sc以前直接定義為:ieee80211_ioctl_siwpower輸?參數(shù)的dev,structath_softc*sc=dev->priv;需要將其定義為wifi0,因此,需要定義為:structieee80211vap*vap=dev->priv;由ath0device獲得vapstructieee80211com*ic=vap->iv_ic;structnet_device*wifi=ic->ic_dev;再次獲得wifidevicestructath_softc*sc=wifi->priv;獲得sc如果調?findrate函數(shù),第?個參數(shù)ath_node需要傳遞過來,發(fā)現(xiàn)這較困難,因此,暫時不使?這個?法,?是??在ieee80211com結構體中定義?個變量,利?該變量傳遞參數(shù)。ath_rate_findrate(structath_softc*sc,structath_node*an,

intshortPreamble,size_tframeLen,u

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論