gl_kal.c 158 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#10
  3. */
  4. /*! \file gl_kal.c
  5. \brief GLUE Layer will export the required procedures here for internal driver stack.
  6. This file contains all routines which are exported from GLUE Layer to internal
  7. driver stack.
  8. */
  9. /*
  10. ** Log: gl_kal.c
  11. **
  12. ** 11 05 2014 eason.tsai
  13. ** [ALPS01728937] [Need Patch] [Volunteer Patch] MET support
  14. ** revise destination port to src port for MET
  15. **
  16. ** 09 16 2014 eason.tsai
  17. ** [ALPS01728937] [Need Patch] [Volunteer Patch] MET support
  18. ** MET support
  19. **
  20. ** 03 12 2014 eason.tsai
  21. ** [ALPS01070904] [Need Patch] [Volunteer Patch][MT6630][Driver]MT6630 Wi-Fi Patch
  22. ** revise for cfg80211 disconnect because of timeout
  23. **
  24. ** 01 15 2014 eason.tsai
  25. ** [ALPS01070904] [Need Patch] [Volunteer Patch][MT6630][Driver]MT6630 Wi-Fi Patch
  26. ** Merging
  27. **
  28. ** //ALPS_SW/DEV/ALPS.JB2.MT6630.DEV/alps/mediatek/kernel/drivers/combo/drv_wlan/mt6630/wlan/...
  29. **
  30. * to //ALPS_SW/TRUNK/KK/alps/mediatek/kernel/drivers/combo/drv_wlan/mt6630/wlan/...
  31. **
  32. ** 12 27 2013 eason.tsai
  33. ** [ALPS01070904] [Need Patch] [Volunteer Patch][MT6630][Driver]MT6630 Wi-Fi Patch
  34. ** update code for ICAP & nvram
  35. **
  36. ** 08 12 2013 cp.wu
  37. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  38. ** 1. fix on cancel_remain_on_channel() interface
  39. ** 2. queue initialization for another linux kal API
  40. **
  41. ** 08 09 2013 cp.wu
  42. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  43. ** 1. integrate scheduled scan functionality
  44. ** 2. condition compilation for linux-3.4 & linux-3.8 compatibility
  45. ** 3. correct CMD queue access to reduce lock scope
  46. **
  47. ** 08 09 2013 bruce.kang
  48. ** [BORA00002740] [MT6630 Wi-Fi][Driver]
  49. ** Solve the recursive lock problem when clearing CMD queue.
  50. **
  51. ** 08 09 2013 terry.wu
  52. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  53. ** 1. Add new input parameter, Tx done status, for wlanReleaseCommand()
  54. **
  55. ** 07 31 2013 terry.wu
  56. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  57. ** 1. Fix NetDev binding issue
  58. **
  59. ** 07 29 2013 cp.wu
  60. ** [BORA00002725] [MT6630][Wi-Fi] Add MGMT TX/RX support for Linux port
  61. ** Preparation for porting remain_on_channel support
  62. **
  63. ** 07 26 2013 terry.wu
  64. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  65. ** 1. Set NoACK to BMC packet
  66. ** 2. Add kalGetEthAddr function for Tx frame
  67. ** 3. Update RxIndicatePackets
  68. **
  69. ** 07 25 2013 wh.su
  70. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  71. ** Sync the MT6628 MP code which make sure the BSS include at
  72. ** connection result, to let the sme_state become connected
  73. **
  74. ** 07 23 2013 cp.wu
  75. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  76. ** 1. build success for win32 port
  77. ** 2. add SDIO test read/write pattern for HQA tests (default off)
  78. **
  79. ** 07 05 2013 terry.wu
  80. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  81. ** 1. Avoid large packet Tx issue
  82. **
  83. ** 07 04 2013 terry.wu
  84. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  85. ** Update for 1st Connection.
  86. **
  87. ** 06 19 2013 terry.wu
  88. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  89. ** Update for 1st connection. Set TC4 default resource value for FW_DL cmd
  90. **
  91. ** 03 13 2013 terry.wu
  92. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  93. ** .
  94. **
  95. ** 03 12 2013 terry.wu
  96. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  97. ** Update Tx utility function for management frame
  98. **
  99. ** 03 05 2013 cp.wu
  100. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  101. ** always set values before calling complete()
  102. **
  103. ** 02 01 2013 cp.wu
  104. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  105. ** 1. eliminate MT5931/MT6620/MT6628 logic
  106. ** 2. add firmware download control sequence
  107. **
  108. ** 01 23 2013 cp.wu
  109. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  110. ** modify AIS behavior: stop join trial if failed
  111. **
  112. ** 01 23 2013 terry.wu
  113. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  114. ** Refine net dev implementation
  115. **
  116. ** 01 21 2013 terry.wu
  117. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  118. ** Update TX path based on new ucBssIndex modifications.
  119. **
  120. ** 01 17 2013 cm.chang
  121. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  122. ** Use ucBssIndex to replace eNetworkTypeIndex
  123. **
  124. ** 09 17 2012 cm.chang
  125. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  126. ** Duplicate source from MT6620 v2.3 driver branch
  127. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  128. **
  129. ** 09 04 2012 cp.wu
  130. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  131. ** sync for NVRAM warning scan result generation for CFG80211.
  132. **
  133. ** 08 30 2012 cp.wu
  134. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  135. ** check pending scan only by the pointer instead of fgIsRegistered flag.
  136. **
  137. ** 08 24 2012 cp.wu
  138. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  139. ** .
  140. **
  141. ** 08 24 2012 cp.wu
  142. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  143. ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
  144. **
  145. ** 08 24 2012 yuche.tsai
  146. ** NULL
  147. ** Fix bug of invitation request.
  148. **
  149. ** 08 20 2012 yuche.tsai
  150. ** NULL
  151. ** Try to fix frame register KE issue.
  152. *
  153. * 07 17 2012 yuche.tsai
  154. * NULL
  155. * Let netdev bring up.
  156. *
  157. * 07 17 2012 yuche.tsai
  158. * NULL
  159. * Compile no error before trial run.
  160. *
  161. * 06 13 2012 yuche.tsai
  162. * NULL
  163. * Update maintrunk driver.
  164. * Add support for driver compose assoc request frame.
  165. *
  166. * 05 31 2012 terry.wu
  167. * NULL
  168. * .
  169. *
  170. * 03 26 2012 cp.wu
  171. * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
  172. * invoke put_cred() after get_current_cred() calls.
  173. *
  174. * 03 07 2012 yuche.tsai
  175. * NULL
  176. * Fix compile error when WiFi Direct is off.
  177. *
  178. * 03 02 2012 terry.wu
  179. * NULL
  180. * Snc CFG80211 modification for ICS migration from branch 2.2.
  181. *
  182. * 02 20 2012 cp.wu
  183. * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
  184. * do not need to invoke free() while firmware image file doesn't exist
  185. *
  186. * 01 05 2012 wh.su
  187. * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
  188. * Adding the related ioctl / wlan oid function to set the Tx power cfg.
  189. *
  190. * 01 02 2012 wh.su
  191. * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
  192. * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
  193. *
  194. * 11 21 2011 cp.wu
  195. * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing
  196. * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer
  197. * add more checking for such cases
  198. *
  199. * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered.
  200. * add some tweaking to protect such cases because that net device has become invalid.
  201. *
  202. * 11 18 2011 yuche.tsai
  203. * NULL
  204. * CONFIG P2P support RSSI query, default turned off.
  205. *
  206. * 11 16 2011 yuche.tsai
  207. * NULL
  208. * Avoid using work thread.
  209. *
  210. * 11 10 2011 cp.wu
  211. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  212. * 1. eliminaite direct calls to printk in porting layer.
  213. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  214. *
  215. * 10 12 2011 wh.su
  216. * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
  217. * adding the 802.11w related function and define .
  218. *
  219. * 09 23 2011 yuche.tsai
  220. * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue
  221. * Regulation domain feature check in.
  222. *
  223. * 08 12 2011 cp.wu
  224. * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
  225. * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC.
  226. *
  227. * 07 18 2011 chinghwa.yu
  228. * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
  229. * Add CMD/Event for RDD and BWCS.
  230. *
  231. * 06 13 2011 eddie.chen
  232. * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni
  233. * Add tx rx statistics and netif_rx_ni.
  234. *
  235. * 04 15 2011 chinghwa.yu
  236. * [WCXRP00000065] Update BoW design and settings
  237. * Add BOW short range mode.
  238. *
  239. * 04 12 2011 cp.wu
  240. * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated
  241. * network type
  242. * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
  243. *
  244. * 04 08 2011 cp.wu
  245. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  246. * correct i4TxPendingFrameNum decreasing.
  247. *
  248. * 03 23 2011 cp.wu
  249. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  250. * apply multi-queue operation only for linux kernel > 2.6.26
  251. *
  252. * 03 21 2011 cp.wu
  253. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  254. * portability for compatible with linux 2.6.12.
  255. *
  256. * 03 21 2011 cp.wu
  257. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  258. * improve portability for awareness of early version of linux kernel and wireless extension.
  259. *
  260. * 03 18 2011 cp.wu
  261. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  262. * after system running for a long period
  263. * refix ...
  264. *
  265. * 03 18 2011 cp.wu
  266. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  267. * after system running for a long period
  268. * correct compiling warning/error.
  269. *
  270. * 03 18 2011 cp.wu
  271. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  272. * after system running for a long period
  273. * add more robust fault tolerance design when pre-allocation failed. (rarely happen)
  274. *
  275. * 03 17 2011 cp.wu
  276. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  277. * after system running for a long period
  278. * use pre-allocated buffer for storing enhanced interrupt response as well
  279. *
  280. * 03 16 2011 cp.wu
  281. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  282. * after system running for a long period
  283. * 1. pre-allocate physical continuous buffer while module is being loaded
  284. * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
  285. *
  286. * The windows part remained the same as before, but added similar APIs to hide the difference.
  287. *
  288. * 03 15 2011 cp.wu
  289. * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
  290. * memory consumption
  291. * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
  292. * 2. Use common coalescing buffer for both TX/RX directions
  293. *
  294. *
  295. * 03 14 2011 jeffrey.chang
  296. * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message
  297. * fix kernel build warning message
  298. *
  299. * 03 07 2011 terry.wu
  300. * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
  301. * Toggle non-standard debug messages to comments.
  302. *
  303. * 03 06 2011 chinghwa.yu
  304. * [WCXRP00000065] Update BoW design and settings
  305. * Sync BOW Driver to latest person development branch version..
  306. *
  307. * 03 03 2011 jeffrey.chang
  308. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  309. * support concurrent network
  310. *
  311. * 03 03 2011 jeffrey.chang
  312. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  313. * modify net device relative functions to support multiple H/W queues
  314. *
  315. * 03 02 2011 cp.wu
  316. * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after
  317. * connection is built.
  318. * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
  319. *
  320. * 02 21 2011 cp.wu
  321. * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
  322. * simplify logic for checking NVRAM existence only once.
  323. *
  324. * 01 24 2011 cp.wu
  325. * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
  326. * 1. add an extra counter for tracking pending forward frames.
  327. * 2. notify TX service thread as well when there is pending forward frame
  328. * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
  329. *
  330. * 01 19 2011 cp.wu
  331. * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
  332. * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
  333. *
  334. * 01 12 2011 cp.wu
  335. * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
  336. * implementation of separate BT_OVER_WIFI data path.
  337. *
  338. * 01 10 2011 cp.wu
  339. * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues
  340. * due to multiple access
  341. * use mutex to protect kalIoctl() for thread safe.
  342. *
  343. * 11 26 2010 cp.wu
  344. * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field
  345. * checking
  346. * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used
  347. * to indicate user is attached
  348. * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown
  349. *
  350. * 11 04 2010 wh.su
  351. * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
  352. * adding the p2p random ssid support.
  353. *
  354. * 11 02 2010 jeffrey.chang
  355. * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets
  356. * .
  357. *
  358. * 11 01 2010 cp.wu
  359. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
  360. * Add implementation for querying current TX rate from firmware auto rate module
  361. * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
  362. * 2) Remove CNM CH-RECOVER event handling
  363. * 3) cfg read/write API renamed with kal prefix for unified naming rules.
  364. *
  365. * 11 01 2010 yarco.yang
  366. * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
  367. * Add code to run WlanIST in SDIO callback.
  368. *
  369. * 10 26 2010 cp.wu
  370. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
  371. * Support NIC capability query command
  372. * 1) update NVRAM content template to ver 1.02
  373. * 2) add compile option for querying NIC capability (default: off)
  374. * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
  375. * 4) correct auto-rate compiler error under linux (treat warning as error)
  376. * 5) simplify usage of NVRAM and REG_INFO_T
  377. * 6) add version checking between driver and firmware
  378. *
  379. * 10 25 2010 jeffrey.chang
  380. * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
  381. * Remove redundant code which cause mismatch of power control release
  382. *
  383. * 10 25 2010 jeffrey.chang
  384. * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
  385. * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control
  386. *
  387. * 10 18 2010 jeffrey.chang
  388. * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
  389. * refine the scan ioctl to prevent hanging of Android UI
  390. *
  391. * 10 18 2010 cp.wu
  392. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
  393. * The mac address is all zero at android
  394. * complete implementation of Android NVRAM access
  395. *
  396. * 10 06 2010 cp.wu
  397. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
  398. * if there is NVRAM, then use MAC address on NVRAM as default MAC address.
  399. *
  400. * 10 06 2010 cp.wu
  401. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  402. * code reorganization to improve isolation between GLUE and CORE layers.
  403. *
  404. * 10 05 2010 cp.wu
  405. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
  406. * 1) add NVRAM access API
  407. * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
  408. * 3) add OID implementation for NVRAM read/write service
  409. *
  410. * 09 21 2010 cp.wu
  411. * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS
  412. * associated
  413. * Do a complete reset with STA-REC null checking for RF test re-entry
  414. *
  415. * 09 21 2010 kevin.huang
  416. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  417. * Eliminate Linux Compile Warning
  418. *
  419. * 09 07 2010 wh.su
  420. * NULL
  421. * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
  422. *
  423. * 09 03 2010 kevin.huang
  424. * NULL
  425. * Refine #include sequence and solve recursive/nested #include issue
  426. *
  427. * 08 30 2010 cp.wu
  428. * NULL
  429. * API added: nicTxPendingPackets(), for simplifying porting layer
  430. *
  431. * 08 20 2010 yuche.tsai
  432. * NULL
  433. * Support second interface indicate when enabling P2P.
  434. *
  435. * 08 18 2010 yarco.yang
  436. * NULL
  437. * 1. Fixed HW checksum offload function not work under Linux issue.
  438. * 2. Add debug message.
  439. *
  440. * 08 16 2010 jeffrey.chang
  441. * NULL
  442. * remove redundant code which cause kernel panic
  443. *
  444. * 08 16 2010 cp.wu
  445. * NULL
  446. * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
  447. *
  448. * 08 02 2010 jeffrey.chang
  449. * NULL
  450. * 1) modify tx service thread to avoid busy looping
  451. * 2) add spin lock declartion for linux build
  452. *
  453. * 07 29 2010 cp.wu
  454. * NULL
  455. * simplify post-handling after TX_DONE interrupt is handled.
  456. *
  457. * 07 28 2010 jeffrey.chang
  458. * NULL
  459. * 1) remove unused spinlocks
  460. * 2) enable encyption ioctls
  461. * 3) fix scan ioctl which may cause supplicant to hang
  462. *
  463. * 07 23 2010 cp.wu
  464. *
  465. * 1) re-enable AIS-FSM beacon timeout handling.
  466. * 2) scan done API revised
  467. *
  468. * 07 23 2010 jeffrey.chang
  469. *
  470. * add new KAL api
  471. *
  472. * 07 23 2010 jeffrey.chang
  473. *
  474. * bug fix: allocate regInfo when disabling firmware download
  475. *
  476. * 07 23 2010 jeffrey.chang
  477. *
  478. * use glue layer api to decrease or increase counter atomically
  479. *
  480. * 07 22 2010 jeffrey.chang
  481. *
  482. * modify tx thread and remove some spinlock
  483. *
  484. * 07 22 2010 jeffrey.chang
  485. *
  486. * use different spin lock for security frame
  487. *
  488. * 07 22 2010 jeffrey.chang
  489. *
  490. * add new spinlock
  491. *
  492. * 07 19 2010 jeffrey.chang
  493. *
  494. * add spinlock for pending security frame count
  495. *
  496. * 07 19 2010 jeffrey.chang
  497. *
  498. * adjust the timer unit to microsecond
  499. *
  500. * 07 19 2010 jeffrey.chang
  501. *
  502. * timer should return value greater than zero
  503. *
  504. * 07 19 2010 jeffrey.chang
  505. *
  506. * add kal api for scanning done
  507. *
  508. * 07 19 2010 jeffrey.chang
  509. *
  510. * modify cmd/data path for new design
  511. *
  512. * 07 19 2010 jeffrey.chang
  513. *
  514. * add new kal api
  515. *
  516. * 07 19 2010 jeffrey.chang
  517. *
  518. * for linux driver migration
  519. *
  520. * 07 19 2010 jeffrey.chang
  521. *
  522. * Linux port modification
  523. *
  524. * 07 08 2010 cp.wu
  525. *
  526. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  527. *
  528. * 06 23 2010 yarco.yang
  529. * [WPD00003837][MT6620]Data Path Refine
  530. * Merge g_arStaRec[] into adapter->arStaRec[]
  531. *
  532. * 06 21 2010 cp.wu
  533. * [WPD00003833][MT6620 and MT5931] Driver migration
  534. * change MAC address updating logic.
  535. *
  536. * 06 06 2010 kevin.huang
  537. * [WPD00003832][MT6620 5931] Create driver base
  538. * [MT6620 5931] Create driver base
  539. *
  540. * 06 01 2010 cp.wu
  541. * [WPD00001943]Create WiFi test driver framework on WinXP
  542. * remove unused files.
  543. *
  544. * 05 29 2010 jeffrey.chang
  545. * [WPD00003826]Initial import for Linux port
  546. * fix private ioctl for rftest
  547. *
  548. * 05 29 2010 jeffrey.chang
  549. * [WPD00003826]Initial import for Linux port
  550. * workaround for fixing request_firmware() failure on android 2.1
  551. *
  552. * 05 28 2010 jeffrey.chang
  553. * [WPD00003826]Initial import for Linux port
  554. * fix kernel panic when debug mode enabled
  555. *
  556. * 05 26 2010 jeffrey.chang
  557. * [WPD00003826]Initial import for Linux port
  558. * 1) Modify set mac address code
  559. * 2) remove power management macro
  560. *
  561. * 05 17 2010 cp.wu
  562. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  563. * 1) add timeout handler mechanism for pending command packets
  564. * 2) add p2p add/removal key
  565. *
  566. * 05 14 2010 jeffrey.chang
  567. * [WPD00003826]Initial import for Linux port
  568. * Disable network interface after disassociation
  569. *
  570. * 05 10 2010 cp.wu
  571. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  572. * fill network type field while doing frame identification.
  573. *
  574. * 05 07 2010 jeffrey.chang
  575. * [WPD00003826]Initial import for Linux port
  576. * prevent supplicant accessing driver during resume
  577. *
  578. * 04 27 2010 cp.wu
  579. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  580. * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame
  581. *
  582. * 04 27 2010 jeffrey.chang
  583. * [WPD00003826]Initial import for Linux port
  584. * 1) fix firmware download bug
  585. * 2) remove query statistics for acelerating firmware download
  586. *
  587. * 04 27 2010 jeffrey.chang
  588. * [WPD00003826]Initial import for Linux port
  589. * follow Linux's firmware framework, and remove unused kal API
  590. *
  591. * 04 22 2010 jeffrey.chang
  592. * [WPD00003826]Initial import for Linux port
  593. *
  594. * 1) modify rx path code for supporting Wi-Fi direct
  595. * 2) modify config.h since Linux dont need to consider retaining packet
  596. *
  597. * 04 21 2010 jeffrey.chang
  598. * [WPD00003826]Initial import for Linux port
  599. * add for private ioctl support
  600. *
  601. * 04 15 2010 jeffrey.chang
  602. * [WPD00003826]Initial import for Linux port
  603. * change firmware name
  604. *
  605. * 04 14 2010 jeffrey.chang
  606. * [WPD00003826]Initial import for Linux port
  607. * flush pending TX packets while unloading driver
  608. *
  609. * 04 14 2010 jeffrey.chang
  610. * [WPD00003826]Initial import for Linux port
  611. * Set driver own before handling cmd queue
  612. *
  613. * 04 14 2010 jeffrey.chang
  614. * [WPD00003826]Initial import for Linux port
  615. * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
  616. * 2) fix ioctl
  617. *
  618. * 04 14 2010 cp.wu
  619. * [WPD00001943]Create WiFi test driver framework on WinXP
  620. * information buffer for query oid/ioctl is now buffered in prCmdInfo
  621. * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability
  622. *
  623. * 04 13 2010 cp.wu
  624. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  625. * add framework for BT-over-Wi-Fi support.
  626. * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler
  627. * * * * * * * * * * * * * * * * * * capability
  628. * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically
  629. * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose
  630. *
  631. * 04 09 2010 jeffrey.chang
  632. * [WPD00003826]Initial import for Linux port
  633. * fix spinlock usage
  634. *
  635. * 04 09 2010 jeffrey.chang
  636. * [WPD00003826]Initial import for Linux port
  637. * add spinlock for i4TxPendingFrameNum access
  638. *
  639. * 04 09 2010 jeffrey.chang
  640. * [WPD00003826]Initial import for Linux port
  641. * 1) add spinlock
  642. * * 2) add KAPI for handling association info
  643. *
  644. * 04 09 2010 jeffrey.chang
  645. * [WPD00003826]Initial import for Linux port
  646. * fix spinlock usage
  647. *
  648. * 04 09 2010 jeffrey.chang
  649. * [WPD00003826]Initial import for Linux port
  650. * adding firmware download KAPI
  651. *
  652. * 04 07 2010 jeffrey.chang
  653. * [WPD00003826]Initial import for Linux port
  654. * Set MAC address from firmware
  655. *
  656. * 04 07 2010 cp.wu
  657. * [WPD00001943]Create WiFi test driver framework on WinXP
  658. * 1. free cmdinfo after command is emiited.
  659. * 2. for BoW frames, user priority is extracted from sk_buff directly.
  660. *
  661. * 04 07 2010 cp.wu
  662. * [WPD00001943]Create WiFi test driver framework on WinXP
  663. * finish non-glue layer access to glue variables
  664. *
  665. * 04 07 2010 cp.wu
  666. * [WPD00001943]Create WiFi test driver framework on WinXP
  667. * accessing to firmware load/start address, and access to OID handling information
  668. * * * are now handled in glue layer
  669. *
  670. * 04 07 2010 cp.wu
  671. * [WPD00001943]Create WiFi test driver framework on WinXP
  672. * rWlanInfo should be placed at adapter rather than glue due to most operations
  673. * * * * * * * are done in adapter layer.
  674. *
  675. * 04 07 2010 cp.wu
  676. * [WPD00001943]Create WiFi test driver framework on WinXP
  677. * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
  678. *
  679. * 04 06 2010 jeffrey.chang
  680. * [WPD00003826]Initial import for Linux port
  681. * (1)deliver the kalOidComplete status to upper layer
  682. * (2) fix spin lock
  683. *
  684. * 04 06 2010 cp.wu
  685. * [WPD00001943]Create WiFi test driver framework on WinXP
  686. * add KAL API: kalFlushPendingTxPackets(), and take use of the API
  687. *
  688. * 04 06 2010 cp.wu
  689. * [WPD00001943]Create WiFi test driver framework on WinXP
  690. * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
  691. *
  692. * 04 06 2010 jeffrey.chang
  693. * [WPD00003826]Initial import for Linux port
  694. * add timeout check in the kalOidComplete
  695. *
  696. * 04 06 2010 jeffrey.chang
  697. * [WPD00003826]Initial import for Linux port
  698. * improve none-glue code portability
  699. *
  700. * 04 06 2010 cp.wu
  701. * [WPD00001943]Create WiFi test driver framework on WinXP
  702. * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
  703. *
  704. * 04 06 2010 cp.wu
  705. * [WPD00001943]Create WiFi test driver framework on WinXP
  706. * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
  707. *
  708. * 04 06 2010 cp.wu
  709. * [WPD00001943]Create WiFi test driver framework on WinXP
  710. * 1) for some OID, never do timeout expiration
  711. * * * 2) add 2 kal API for later integration
  712. *
  713. * 04 06 2010 jeffrey.chang
  714. * [WPD00003826]Initial import for Linux port
  715. * raising the priority of processing interrupt
  716. *
  717. * 04 01 2010 jeffrey.chang
  718. * [WPD00003826]Initial import for Linux port
  719. * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in
  720. *
  721. * 03 30 2010 jeffrey.chang
  722. * [WPD00003826]Initial import for Linux port
  723. * emulate NDIS Pending OID facility
  724. *
  725. * 03 28 2010 jeffrey.chang
  726. * [WPD00003826]Initial import for Linux port
  727. * adding secondary command queue for improving non-glue code portability
  728. *
  729. * 03 26 2010 jeffrey.chang
  730. * [WPD00003826]Initial import for Linux port
  731. * [WPD00003826] Initial import for Linux port
  732. * adding firmware download kal api
  733. *
  734. * 03 25 2010 cp.wu
  735. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  736. * add Bluetooth-over-Wifi frame header check
  737. *
  738. * 03 24 2010 jeffrey.chang
  739. * [WPD00003826]Initial import for Linux port
  740. * initial import for Linux port
  741. ** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090
  742. ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
  743. ** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090
  744. ** Add Linux SDIO (with mmc core) support.
  745. ** Add Linux 2.6.21, 2.6.25, 2.6.26.
  746. ** Fix compile warning in Linux.
  747. ** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090
  748. ** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
  749. ** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088
  750. ** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding
  751. ** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461
  752. ** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL
  753. ** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088
  754. ** remove non-used code for code review, add assert check
  755. ** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461
  756. ** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461
  757. ** Rename KAL function
  758. ** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461
  759. ** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084
  760. ** rename wlanoid
  761. ** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084
  762. ** remove un-used KAL function
  763. ** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461
  764. ** Move Query Media Status to GLUE
  765. ** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461
  766. ** change awake queue threshold and remove code which mark #if 0
  767. ** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461
  768. ** Add iwpriv support for AdHocMode setting
  769. ** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084
  770. ** add KAL function to setting pattern search function enable/ disable
  771. ** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461
  772. ** Add comment
  773. ** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461
  774. ** Add update MAC Address for Linux
  775. ** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084
  776. ** update function for initial value access
  777. ** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088
  778. ** use kal update associate request at linux
  779. ** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385
  780. ** 1. add Query Registry Mac address function.
  781. ** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084
  782. ** modify KAL set network address/ checksum offload part
  783. ** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461
  784. ** Add debug option - Packet Order for Linux
  785. ** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084
  786. ** modify the argument of kalQueryPacketInfo()
  787. ** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425
  788. ** 1. Revise csum offload
  789. ** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425
  790. ** 1. Fix bugs
  791. **
  792. ** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461
  793. ** Fix Windows RX multiple packet retain problem
  794. ** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088
  795. ** <workaround> CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit
  796. ** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425
  797. ** 1. Modify for CSUM offloading with Tx Fragment
  798. ** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461
  799. ** Add Tx Fragmentation Support
  800. ** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088
  801. ** add the WPS code, indicate the mgmt frame to upper layer
  802. ** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461
  803. ** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
  804. ** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425
  805. ** 1. Update wlanQueryInformation
  806. ** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425
  807. ** 1. Refine multicast list code
  808. ** 2. Refine TCP/IP csum offload code
  809. **
  810. ** Revision 1.5 2007/07/17 13:01:18 MTK01088
  811. ** add associate req and rsp function
  812. **
  813. ** Revision 1.4 2007/07/13 05:19:19 MTK01084
  814. ** provide timer set functions
  815. **
  816. ** Revision 1.3 2007/06/27 02:18:51 MTK01461
  817. ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
  818. **
  819. ** Revision 1.2 2007/06/25 06:16:24 MTK01461
  820. ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
  821. **
  822. */
  823. /*******************************************************************************
  824. * C O M P I L E R F L A G S
  825. ********************************************************************************
  826. */
  827. /*******************************************************************************
  828. * E X T E R N A L R E F E R E N C E S
  829. ********************************************************************************
  830. */
  831. #include "gl_os.h"
  832. #include "gl_kal.h"
  833. #include "gl_wext.h"
  834. #include "precomp.h"
  835. #if CFG_SUPPORT_AGPS_ASSIST
  836. #include <net/netlink.h>
  837. #endif
  838. /*******************************************************************************
  839. * C O N S T A N T S
  840. ********************************************************************************
  841. */
  842. /*******************************************************************************
  843. * D A T A T Y P E S
  844. ********************************************************************************
  845. */
  846. /*******************************************************************************
  847. * P U B L I C D A T A
  848. ********************************************************************************
  849. */
  850. #if DBG
  851. int allocatedMemSize = 0;
  852. #endif
  853. /*******************************************************************************
  854. * P R I V A T E D A T A
  855. ********************************************************************************
  856. */
  857. static PVOID pvIoBuffer;
  858. static UINT_32 pvIoBufferSize;
  859. static UINT_32 pvIoBufferUsage;
  860. /*******************************************************************************
  861. * M A C R O S
  862. ********************************************************************************
  863. */
  864. /*******************************************************************************
  865. * F U N C T I O N D E C L A R A T I O N S
  866. ********************************************************************************
  867. */
  868. /*******************************************************************************
  869. * F U N C T I O N S
  870. ********************************************************************************
  871. */
  872. #if CFG_ENABLE_FW_DOWNLOAD
  873. static struct file *filp;
  874. static uid_t orgfsuid;
  875. static gid_t orgfsgid;
  876. static mm_segment_t orgfs;
  877. static PUINT_8 apucFwPath[] = {
  878. (PUINT_8) "/storage/sdcard0/",
  879. (PUINT_8) "/etc/firmware/",
  880. NULL
  881. };
  882. /* E2 */
  883. static PUINT_8 apucFwNameE2[] = {
  884. (PUINT_8) CFG_FW_FILENAME "_MT6630_E2",
  885. (PUINT_8) CFG_FW_FILENAME "_MT6630",
  886. NULL
  887. };
  888. /* E3 */
  889. static PUINT_8 apucFwNameE3[] = {
  890. (PUINT_8) CFG_FW_FILENAME "_MT6630_E3",
  891. (PUINT_8) CFG_FW_FILENAME "_MT6630",
  892. (PUINT_8) CFG_FW_FILENAME "_MT6630_E2",
  893. NULL
  894. };
  895. /* Default */
  896. static PUINT_8 apucFwName[] = {
  897. (PUINT_8) CFG_FW_FILENAME "_MT6630",
  898. (PUINT_8) CFG_FW_FILENAME "_MT6630_E2",
  899. (PUINT_8) CFG_FW_FILENAME "_MT6630_E3",
  900. NULL
  901. };
  902. static PPUINT_8 appucFwNameTable[] = {
  903. apucFwName,
  904. apucFwNameE2,
  905. apucFwNameE3,
  906. apucFwNameE3,
  907. };
  908. /*----------------------------------------------------------------------------*/
  909. /*!
  910. * \brief This function is provided by GLUE Layer for internal driver stack to
  911. * open firmware image in kernel space
  912. *
  913. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  914. *
  915. * \retval WLAN_STATUS_SUCCESS.
  916. * \retval WLAN_STATUS_FAILURE.
  917. *
  918. */
  919. /*----------------------------------------------------------------------------*/
  920. WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo)
  921. {
  922. UINT_8 ucPathIdx, ucNameIdx;
  923. PPUINT_8 apucNameTable;
  924. UINT_8 ucMaxEcoVer = (sizeof(appucFwNameTable) / sizeof(PPUINT_8));
  925. UINT_8 ucCurEcoVer = wlanGetEcoVersion(prGlueInfo->prAdapter);
  926. UINT_8 aucFwName[128];
  927. BOOLEAN fgResult = FALSE;
  928. /* FIX ME: since we don't have hotplug script in the filesystem
  929. * , so the request_firmware() KAPI can not work properly
  930. */
  931. /* save uid and gid used for filesystem access.
  932. * set user and group to 0(root) */
  933. struct cred *cred = (struct cred *)get_current_cred();
  934. orgfsuid = cred->fsuid.val;
  935. orgfsgid = cred->fsgid.val;
  936. cred->fsuid.val = cred->fsgid.val = 0;
  937. ASSERT(prGlueInfo);
  938. orgfs = get_fs();
  939. set_fs(get_ds());
  940. /* Get FW name table */
  941. if (ucMaxEcoVer < ucCurEcoVer)
  942. apucNameTable = apucFwName;
  943. else
  944. apucNameTable = appucFwNameTable[ucCurEcoVer - 1];
  945. /* Try to open FW binary */
  946. for (ucPathIdx = 0; apucFwPath[ucPathIdx]; ucPathIdx++) {
  947. for (ucNameIdx = 0; apucNameTable[ucNameIdx]; ucNameIdx++) {
  948. kalSprintf(aucFwName, "%s%s", apucFwPath[ucPathIdx], apucNameTable[ucNameIdx]);
  949. filp = filp_open(aucFwName, O_RDONLY, 0);
  950. if (IS_ERR(filp)) {
  951. DBGLOG(INIT, TRACE, "Open FW image: %s failed, errno[%d]\n",
  952. aucFwName, ERR_PTR((LONG) filp));
  953. continue;
  954. } else {
  955. DBGLOG(INIT, TRACE, "Open FW image: %s done\n", aucFwName);
  956. fgResult = TRUE;
  957. break;
  958. }
  959. }
  960. if (fgResult)
  961. break;
  962. }
  963. /* Check result */
  964. if (fgResult) {
  965. DBGLOG(INIT, INFO, "Open FW image: %s done\n", aucFwName);
  966. } else {
  967. DBGLOG(INIT, ERROR, "Open FW image failed! Cur/Max ECO Ver[E%u/E%u]\n", ucCurEcoVer, ucMaxEcoVer);
  968. /* Dump tried FW path/name */
  969. for (ucPathIdx = 0; apucFwPath[ucPathIdx]; ucPathIdx++) {
  970. for (ucNameIdx = 0; apucNameTable[ucNameIdx]; ucNameIdx++) {
  971. kalSprintf(aucFwName, "%s%s", apucFwPath[ucPathIdx], apucNameTable[ucNameIdx]);
  972. filp = filp_open(aucFwName, O_RDONLY, 0);
  973. if (IS_ERR(filp)) {
  974. DBGLOG(INIT, INFO, "Open FW image: %s failed, errno[%d]\n",
  975. aucFwName, ERR_PTR((LONG) filp));
  976. } else {
  977. DBGLOG(INIT, INFO, "Open FW image: %s done\n", aucFwName);
  978. }
  979. }
  980. }
  981. goto error_open;
  982. }
  983. return WLAN_STATUS_SUCCESS;
  984. error_open:
  985. /* restore */
  986. set_fs(orgfs);
  987. cred->fsuid.val = orgfsuid;
  988. cred->fsgid.val = orgfsgid;
  989. put_cred(cred);
  990. return WLAN_STATUS_FAILURE;
  991. }
  992. /*----------------------------------------------------------------------------*/
  993. /*!
  994. * \brief This function is provided by GLUE Layer for internal driver stack to
  995. * release firmware image in kernel space
  996. *
  997. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  998. *
  999. * \retval WLAN_STATUS_SUCCESS.
  1000. * \retval WLAN_STATUS_FAILURE.
  1001. *
  1002. */
  1003. /*----------------------------------------------------------------------------*/
  1004. WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo)
  1005. {
  1006. ASSERT(prGlueInfo);
  1007. if ((filp != NULL) && !IS_ERR(filp)) {
  1008. /* close firmware file */
  1009. filp_close(filp, NULL);
  1010. /* restore */
  1011. set_fs(orgfs);
  1012. {
  1013. struct cred *cred = (struct cred *)get_current_cred();
  1014. cred->fsuid.val = orgfsuid;
  1015. cred->fsgid.val = orgfsgid;
  1016. put_cred(cred);
  1017. }
  1018. filp = NULL;
  1019. }
  1020. return WLAN_STATUS_SUCCESS;
  1021. }
  1022. /*----------------------------------------------------------------------------*/
  1023. /*!
  1024. * \brief This function is provided by GLUE Layer for internal driver stack to
  1025. * load firmware image in kernel space
  1026. *
  1027. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1028. *
  1029. * \retval WLAN_STATUS_SUCCESS.
  1030. * \retval WLAN_STATUS_FAILURE.
  1031. *
  1032. */
  1033. /*----------------------------------------------------------------------------*/
  1034. WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size)
  1035. {
  1036. ASSERT(prGlueInfo);
  1037. ASSERT(pu4Size);
  1038. ASSERT(prBuf);
  1039. /* l = filp->f_path.dentry->d_inode->i_size; */
  1040. /* the object must have a read method */
  1041. if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) {
  1042. goto error_read;
  1043. } else {
  1044. filp->f_pos = u4Offset;
  1045. *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos);
  1046. }
  1047. return WLAN_STATUS_SUCCESS;
  1048. error_read:
  1049. return WLAN_STATUS_FAILURE;
  1050. }
  1051. /*----------------------------------------------------------------------------*/
  1052. /*!
  1053. * \brief This function is provided by GLUE Layer for internal driver stack to
  1054. * query firmware image size in kernel space
  1055. *
  1056. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1057. *
  1058. * \retval WLAN_STATUS_SUCCESS.
  1059. * \retval WLAN_STATUS_FAILURE.
  1060. *
  1061. */
  1062. /*----------------------------------------------------------------------------*/
  1063. WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size)
  1064. {
  1065. ASSERT(prGlueInfo);
  1066. ASSERT(pu4Size);
  1067. *pu4Size = filp->f_path.dentry->d_inode->i_size;
  1068. return WLAN_STATUS_SUCCESS;
  1069. }
  1070. /*----------------------------------------------------------------------------*/
  1071. /*!
  1072. * \brief This routine is used to load firmware image
  1073. *
  1074. * \param pvGlueInfo Pointer of GLUE Data Structure
  1075. * \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image
  1076. * \param pu4FileLength File length and memory mapped length as well
  1077. * \retval Map File Handle, used for unammping
  1078. */
  1079. /*----------------------------------------------------------------------------*/
  1080. PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength)
  1081. {
  1082. DEBUGFUNC("kalFirmwareImageMapping");
  1083. ASSERT(prGlueInfo);
  1084. ASSERT(ppvMapFileBuf);
  1085. ASSERT(pu4FileLength);
  1086. do {
  1087. UINT_32 u4FwSize = 0;
  1088. PVOID prFwBuffer = NULL;
  1089. /* <1> Open firmware */
  1090. if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS)
  1091. break;
  1092. /* <2> Query firmare size */
  1093. kalFirmwareSize(prGlueInfo, &u4FwSize);
  1094. /* <3> Use vmalloc for allocating large memory trunk */
  1095. prFwBuffer = vmalloc(ALIGN_4(u4FwSize));
  1096. /* <4> Load image binary into buffer */
  1097. if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) {
  1098. vfree(prFwBuffer);
  1099. kalFirmwareClose(prGlueInfo);
  1100. break;
  1101. }
  1102. /* <5> write back info */
  1103. *pu4FileLength = u4FwSize;
  1104. *ppvMapFileBuf = prFwBuffer;
  1105. return prFwBuffer;
  1106. } while (FALSE);
  1107. return NULL;
  1108. }
  1109. /*----------------------------------------------------------------------------*/
  1110. /*!
  1111. * \brief This routine is used to unload firmware image mapped memory
  1112. *
  1113. * \param pvGlueInfo Pointer of GLUE Data Structure
  1114. * \param pvFwHandle Pointer to mapping handle
  1115. * \param pvMapFileBuf Pointer to memory-mapped firmware image
  1116. *
  1117. * \retval none
  1118. */
  1119. /*----------------------------------------------------------------------------*/
  1120. VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf)
  1121. {
  1122. DEBUGFUNC("kalFirmwareImageUnmapping");
  1123. ASSERT(prGlueInfo);
  1124. /* pvMapFileBuf might be NULL when file doesn't exist */
  1125. if (pvMapFileBuf)
  1126. vfree(pvMapFileBuf);
  1127. kalFirmwareClose(prGlueInfo);
  1128. }
  1129. #endif
  1130. #if 0
  1131. /*----------------------------------------------------------------------------*/
  1132. /*!
  1133. * \brief This routine is used to load firmware image
  1134. *
  1135. * \param pvGlueInfo Pointer of GLUE Data Structure
  1136. * \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image
  1137. * \param pu4FileLength File length and memory mapped length as well
  1138. * \retval Map File Handle, used for unammping
  1139. */
  1140. /*----------------------------------------------------------------------------*/
  1141. PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength)
  1142. {
  1143. INT_32 i4Ret = 0;
  1144. DEBUGFUNC("kalFirmwareImageMapping");
  1145. ASSERT(prGlueInfo);
  1146. ASSERT(ppvMapFileBuf);
  1147. ASSERT(pu4FileLength);
  1148. do {
  1149. GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo;
  1150. prGlueInfo->prFw = NULL;
  1151. /* <1> Open firmware */
  1152. i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, &prHifInfo->func->dev);
  1153. if (i4Ret) {
  1154. DBGLOG(INIT, INFO, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret);
  1155. } else {
  1156. *pu4FileLength = prGlueInfo->prFw->size;
  1157. *ppvMapFileBuf = prGlueInfo->prFw->data;
  1158. return prGlueInfo->prFw->data;
  1159. }
  1160. } while (FALSE);
  1161. return NULL;
  1162. }
  1163. /*----------------------------------------------------------------------------*/
  1164. /*!
  1165. * \brief This routine is used to unload firmware image mapped memory
  1166. *
  1167. * \param pvGlueInfo Pointer of GLUE Data Structure
  1168. * \param pvFwHandle Pointer to mapping handle
  1169. * \param pvMapFileBuf Pointer to memory-mapped firmware image
  1170. *
  1171. * \retval none
  1172. */
  1173. /*----------------------------------------------------------------------------*/
  1174. VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf)
  1175. {
  1176. DEBUGFUNC("kalFirmwareImageUnmapping");
  1177. ASSERT(prGlueInfo);
  1178. ASSERT(pvMapFileBuf);
  1179. release_firmware(prGlueInfo->prFw);
  1180. }
  1181. #endif
  1182. /*----------------------------------------------------------------------------*/
  1183. /*!
  1184. * \brief This function is provided by GLUE Layer for internal driver stack to acquire
  1185. * OS SPIN_LOCK.
  1186. *
  1187. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1188. * \param[in] rLockCategory Specify which SPIN_LOCK
  1189. * \param[out] pu4Flags Pointer of a variable for saving IRQ flags
  1190. *
  1191. * \return (none)
  1192. */
  1193. /*----------------------------------------------------------------------------*/
  1194. VOID kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT PULONG plFlags)
  1195. {
  1196. ULONG ulFlags = 0;
  1197. ASSERT(prGlueInfo);
  1198. ASSERT(plFlags);
  1199. if (rLockCategory < SPIN_LOCK_NUM) {
  1200. #if CFG_USE_SPIN_LOCK_BOTTOM_HALF
  1201. spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
  1202. #else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
  1203. spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], ulFlags);
  1204. #endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
  1205. *plFlags = ulFlags;
  1206. }
  1207. } /* end of kalAcquireSpinLock() */
  1208. /*----------------------------------------------------------------------------*/
  1209. /*!
  1210. * \brief This function is provided by GLUE Layer for internal driver stack to release
  1211. * OS SPIN_LOCK.
  1212. *
  1213. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1214. * \param[in] rLockCategory Specify which SPIN_LOCK
  1215. * \param[in] u4Flags Saved IRQ flags
  1216. *
  1217. * \return (none)
  1218. */
  1219. /*----------------------------------------------------------------------------*/
  1220. VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN ULONG ulFlags)
  1221. {
  1222. ASSERT(prGlueInfo);
  1223. if (rLockCategory < SPIN_LOCK_NUM) {
  1224. #if CFG_USE_SPIN_LOCK_BOTTOM_HALF
  1225. spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
  1226. #else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
  1227. spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], ulFlags);
  1228. #endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
  1229. }
  1230. } /* end of kalReleaseSpinLock() */
  1231. /*----------------------------------------------------------------------------*/
  1232. /*!
  1233. * \brief This function is provided by GLUE Layer for internal driver stack to acquire
  1234. * OS MUTEX.
  1235. *
  1236. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1237. * \param[in] rMutexCategory Specify which MUTEX
  1238. *
  1239. * \return (none)
  1240. */
  1241. /*----------------------------------------------------------------------------*/
  1242. VOID kalAcquireMutex(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_MUTEX_CATEGORY_E rMutexCategory)
  1243. {
  1244. ASSERT(prGlueInfo);
  1245. if (rMutexCategory < MUTEX_NUM) {
  1246. DBGLOG(INIT, TRACE, "MUTEX_LOCK[%u] Try to acquire\n", rMutexCategory);
  1247. mutex_lock(&prGlueInfo->arMutex[rMutexCategory]);
  1248. DBGLOG(INIT, TRACE, "MUTEX_LOCK[%u] Acquired\n", rMutexCategory);
  1249. }
  1250. } /* end of kalAcquireMutex() */
  1251. /*----------------------------------------------------------------------------*/
  1252. /*!
  1253. * \brief This function is provided by GLUE Layer for internal driver stack to release
  1254. * OS MUTEX.
  1255. *
  1256. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1257. * \param[in] rMutexCategory Specify which MUTEX
  1258. *
  1259. * \return (none)
  1260. */
  1261. /*----------------------------------------------------------------------------*/
  1262. VOID kalReleaseMutex(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_MUTEX_CATEGORY_E rMutexCategory)
  1263. {
  1264. ASSERT(prGlueInfo);
  1265. if (rMutexCategory < MUTEX_NUM) {
  1266. mutex_unlock(&prGlueInfo->arMutex[rMutexCategory]);
  1267. DBGLOG(INIT, TRACE, "MUTEX_UNLOCK[%u]\n", rMutexCategory);
  1268. }
  1269. } /* end of kalReleaseMutex() */
  1270. /*----------------------------------------------------------------------------*/
  1271. /*!
  1272. * \brief This function is provided by GLUE Layer for internal driver stack to update
  1273. * current MAC address.
  1274. *
  1275. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1276. * \param[in] pucMacAddr Pointer of current MAC address
  1277. *
  1278. * \return (none)
  1279. */
  1280. /*----------------------------------------------------------------------------*/
  1281. VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr)
  1282. {
  1283. ASSERT(prGlueInfo);
  1284. ASSERT(pucMacAddr);
  1285. if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr))
  1286. memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN);
  1287. }
  1288. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1289. /*----------------------------------------------------------------------------*/
  1290. /*!
  1291. * \brief To query the packet information for offload related parameters.
  1292. *
  1293. * \param[in] pvPacket Pointer to the packet descriptor.
  1294. * \param[in] pucFlag Points to the offload related parameter.
  1295. *
  1296. * \return (none)
  1297. *
  1298. */
  1299. /*----------------------------------------------------------------------------*/
  1300. VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag)
  1301. {
  1302. struct sk_buff *skb = (struct sk_buff *)pvPacket;
  1303. UINT_8 ucFlag = 0;
  1304. ASSERT(pvPacket);
  1305. ASSERT(pucFlag);
  1306. if (skb->ip_summed == CHECKSUM_PARTIAL) {
  1307. #if DBG
  1308. /* Kevin: do double check, we can remove this part in Normal Driver.
  1309. * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so
  1310. * we'll process IP packet only.
  1311. */
  1312. if (skb->protocol != htons(ETH_P_IP)) {
  1313. /* DBGLOG(INIT, INFO, "Wrong skb->protocol( = %08x)
  1314. for TX Checksum Offload.\n", skb->protocol); */
  1315. } else
  1316. #endif
  1317. ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN);
  1318. }
  1319. *pucFlag = ucFlag;
  1320. } /* kalQueryChksumOffloadParam */
  1321. /* 4 2007/10/8, mikewu, this is rewritten by Mike */
  1322. /*----------------------------------------------------------------------------*/
  1323. /*!
  1324. * \brief To update the checksum offload status to the packet to be indicated to OS.
  1325. *
  1326. * \param[in] pvPacket Pointer to the packet descriptor.
  1327. * \param[in] pucFlag Points to the offload related parameter.
  1328. *
  1329. * \return (none)
  1330. *
  1331. */
  1332. /*----------------------------------------------------------------------------*/
  1333. VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[])
  1334. {
  1335. struct sk_buff *skb = (struct sk_buff *)pvPacket;
  1336. ASSERT(pvPacket);
  1337. if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)
  1338. && ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS)
  1339. || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) {
  1340. skb->ip_summed = CHECKSUM_UNNECESSARY;
  1341. } else {
  1342. skb->ip_summed = CHECKSUM_NONE;
  1343. #if DBG
  1344. if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)
  1345. DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n");
  1346. else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED)
  1347. DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n");
  1348. else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED)
  1349. DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n");
  1350. else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED)
  1351. DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n");
  1352. #endif
  1353. }
  1354. } /* kalUpdateRxCSUMOffloadParam */
  1355. #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
  1356. /*----------------------------------------------------------------------------*/
  1357. /*!
  1358. * \brief This function is called to free packet allocated from kalPacketAlloc.
  1359. *
  1360. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1361. * \param[in] pvPacket Pointer of the packet descriptor
  1362. *
  1363. * \return (none)
  1364. */
  1365. /*----------------------------------------------------------------------------*/
  1366. VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket)
  1367. {
  1368. dev_kfree_skb((struct sk_buff *)pvPacket);
  1369. }
  1370. /*----------------------------------------------------------------------------*/
  1371. /*!
  1372. * \brief Only handles driver own creating packet (coalescing buffer).
  1373. *
  1374. * \param prGlueInfo Pointer of GLUE Data Structure
  1375. * \param u4Size Pointer of Packet Handle
  1376. * \param ppucData Status Code for OS upper layer
  1377. *
  1378. * \return NULL: Failed to allocate skb, Not NULL get skb
  1379. */
  1380. /*----------------------------------------------------------------------------*/
  1381. PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData)
  1382. {
  1383. struct sk_buff *prSkb = dev_alloc_skb(u4Size);
  1384. if (prSkb) {
  1385. *ppucData = (PUINT_8) (prSkb->data);
  1386. kalResetPacket(prGlueInfo, (P_NATIVE_PACKET) prSkb);
  1387. }
  1388. #if DBG
  1389. {
  1390. PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0];
  1391. *pu4Head = (UINT_32) prSkb->head;
  1392. DBGLOG(RX, TRACE, "prSkb->head = %#lx, prSkb->cb = %#lx\n", (UINT_32) prSkb->head, *pu4Head);
  1393. }
  1394. #endif
  1395. return (PVOID) prSkb;
  1396. }
  1397. /*----------------------------------------------------------------------------*/
  1398. /*!
  1399. * \brief Process the received packet for indicating to OS.
  1400. *
  1401. * \param[in] prGlueInfo Pointer to the Adapter structure.
  1402. * \param[in] pvPacket Pointer of the packet descriptor
  1403. * \param[in] pucPacketStart The starting address of the buffer of Rx packet.
  1404. * \param[in] u4PacketLen The packet length.
  1405. * \param[in] pfgIsRetain Is the packet to be retained.
  1406. * \param[in] aerCSUM The result of TCP/ IP checksum offload.
  1407. *
  1408. * \retval WLAN_STATUS_SUCCESS.
  1409. * \retval WLAN_STATUS_FAILURE.
  1410. *
  1411. */
  1412. /*----------------------------------------------------------------------------*/
  1413. WLAN_STATUS
  1414. kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen,
  1415. /* IN PBOOLEAN pfgIsRetain, */
  1416. IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[])
  1417. {
  1418. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1419. struct sk_buff *skb = (struct sk_buff *)pvPacket;
  1420. skb->data = (unsigned char *)pucPacketStart;
  1421. /* Reset skb */
  1422. skb_reset_tail_pointer(skb);
  1423. skb_trim(skb, 0);
  1424. /* Put data */
  1425. skb_put(skb, u4PacketLen);
  1426. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1427. kalUpdateRxCSUMOffloadParam(skb, aerCSUM);
  1428. #endif
  1429. return rStatus;
  1430. }
  1431. /*----------------------------------------------------------------------------*/
  1432. /*!
  1433. * \brief To indicate an array of received packets is available for higher
  1434. * level protocol uses.
  1435. *
  1436. * \param[in] prGlueInfo Pointer to the Adapter structure.
  1437. * \param[in] apvPkts The packet array to be indicated
  1438. * \param[in] ucPktNum The number of packets to be indicated
  1439. *
  1440. * \retval TRUE Success.
  1441. *
  1442. */
  1443. /*----------------------------------------------------------------------------*/
  1444. WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum)
  1445. {
  1446. UINT_8 ucIdx = 0;
  1447. ASSERT(prGlueInfo);
  1448. ASSERT(apvPkts);
  1449. for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++)
  1450. kalRxIndicateOnePkt(prGlueInfo, apvPkts[ucIdx]);
  1451. KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &prGlueInfo->rTimeoutWakeLock,
  1452. MSEC_TO_JIFFIES(WAKE_LOCK_RX_TIMEOUT));
  1453. return WLAN_STATUS_SUCCESS;
  1454. }
  1455. /*----------------------------------------------------------------------------*/
  1456. /*!
  1457. * \brief To indicate one received packets is available for higher
  1458. * level protocol uses.
  1459. *
  1460. * \param[in] prGlueInfo Pointer to the Adapter structure.
  1461. * \param[in] pvPkt The packet to be indicated
  1462. *
  1463. * \retval TRUE Success.
  1464. *
  1465. */
  1466. /*----------------------------------------------------------------------------*/
  1467. WLAN_STATUS kalRxIndicateOnePkt(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPkt)
  1468. {
  1469. struct net_device *prNetDev = prGlueInfo->prDevHandler;
  1470. struct sk_buff *prSkb = NULL;
  1471. UINT_8 bssIdx = 0;
  1472. ASSERT(prGlueInfo);
  1473. ASSERT(pvPkt);
  1474. prSkb = pvPkt;
  1475. #if DBG && 0
  1476. do {
  1477. PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0];
  1478. UINT_32 u4HeadValue = 0;
  1479. kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue));
  1480. DBGLOG(RX, TRACE, "prSkb->head = 0x%p, prSkb->cb = 0x%lx\n", pu4Head, u4HeadValue);
  1481. } while (0);
  1482. #endif
  1483. #if 1
  1484. bssIdx = GLUE_GET_PKT_BSS_IDX(prSkb);
  1485. prNetDev = (struct net_device *)wlanGetNetInterfaceByBssIdx(prGlueInfo, bssIdx);
  1486. if (!prNetDev) {
  1487. prNetDev = prGlueInfo->prDevHandler;
  1488. } else if (bssIdx == NET_DEV_P2P_IDX) {
  1489. if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) {
  1490. DBGLOG(RX, INFO, "bssIdx = %d P2PNetRegState=%d\n",
  1491. bssIdx, prGlueInfo->prAdapter->rP2PNetRegState);
  1492. prNetDev = prGlueInfo->prDevHandler;
  1493. }
  1494. }
  1495. #if CFG_SUPPORT_SNIFFER
  1496. if (prGlueInfo->fgIsEnableMon)
  1497. prNetDev = prGlueInfo->prMonDevHandler;
  1498. #endif
  1499. prNetDev->stats.rx_bytes += prSkb->len;
  1500. prNetDev->stats.rx_packets++;
  1501. #else
  1502. if (GLUE_GET_PKT_IS_P2P(prSkb)) {
  1503. /* P2P */
  1504. #if CFG_ENABLE_WIFI_DIRECT
  1505. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1506. prNetDev = kalP2PGetDevHdlr(prGlueInfo);
  1507. /* prNetDev->stats.rx_bytes += prSkb->len; */
  1508. /* prNetDev->stats.rx_packets++; */
  1509. prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len;
  1510. prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++;
  1511. #else
  1512. prNetDev = prGlueInfo->prDevHandler;
  1513. #endif
  1514. } else if (GLUE_GET_PKT_IS_PAL(prSkb)) {
  1515. /* BOW */
  1516. #if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH
  1517. if (prGlueInfo->rBowInfo.fgIsNetRegistered)
  1518. prNetDev = prGlueInfo->rBowInfo.prDevHandler;
  1519. #else
  1520. prNetDev = prGlueInfo->prDevHandler;
  1521. #endif
  1522. } else {
  1523. /* AIS */
  1524. prNetDev = prGlueInfo->prDevHandler;
  1525. prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
  1526. prGlueInfo->rNetDevStats.rx_packets++;
  1527. }
  1528. #endif
  1529. STATS_RX_PKT_INFO_DISPLAY(prSkb->data);
  1530. prNetDev->last_rx = jiffies;
  1531. #if CFG_SUPPORT_SNIFFER
  1532. if (prGlueInfo->fgIsEnableMon) {
  1533. skb_reset_mac_header(prSkb);
  1534. prSkb->ip_summed = CHECKSUM_UNNECESSARY;
  1535. prSkb->pkt_type = PACKET_OTHERHOST;
  1536. prSkb->protocol = htons(ETH_P_802_2);
  1537. } else {
  1538. prSkb->protocol = eth_type_trans(prSkb, prNetDev);
  1539. }
  1540. #else
  1541. prSkb->protocol = eth_type_trans(prSkb, prNetDev);
  1542. #endif
  1543. prSkb->dev = prNetDev;
  1544. /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */
  1545. /* DBGLOG(RX, EVENT, ("kalRxIndicatePkts len = %d\n", prSkb->len)); */
  1546. if (prSkb->tail > prSkb->end) {
  1547. DBGLOG(RX, ERROR,
  1548. "kalRxIndicateOnePkt [prSkb = 0x%p][prSkb->len = %d][prSkb->protocol = 0x%02X] %p,%p\n",
  1549. (PUINT_8) prSkb, prSkb->len, prSkb->protocol, prSkb->tail, prSkb->end);
  1550. DBGLOG_MEM32(RX, ERROR, (PUINT_32) prSkb->data, prSkb->len);
  1551. }
  1552. if (!in_interrupt())
  1553. netif_rx_ni(prSkb); /* only in non-interrupt context */
  1554. else
  1555. netif_rx(prSkb);
  1556. wlanReturnPacket(prGlueInfo->prAdapter, NULL);
  1557. return WLAN_STATUS_SUCCESS;
  1558. }
  1559. /*----------------------------------------------------------------------------*/
  1560. /*!
  1561. * \brief Called by driver to indicate event to upper layer, for example, the wpa
  1562. * supplicant or wireless tools.
  1563. *
  1564. * \param[in] pvAdapter Pointer to the adapter descriptor.
  1565. * \param[in] eStatus Indicated status.
  1566. * \param[in] pvBuf Indicated message buffer.
  1567. * \param[in] u4BufLen Indicated message buffer size.
  1568. *
  1569. * \return (none)
  1570. *
  1571. */
  1572. /*----------------------------------------------------------------------------*/
  1573. VOID
  1574. kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen)
  1575. {
  1576. UINT_32 bufLen;
  1577. P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf;
  1578. P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus;
  1579. P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1);
  1580. PARAM_MAC_ADDRESS arBssid;
  1581. struct cfg80211_scan_request *prScanRequest = NULL;
  1582. PARAM_SSID_T ssid;
  1583. struct ieee80211_channel *prChannel = NULL;
  1584. struct cfg80211_bss *bss;
  1585. UINT_8 ucChannelNum;
  1586. P_BSS_DESC_T prBssDesc = NULL;
  1587. GLUE_SPIN_LOCK_DECLARATION();
  1588. kalMemZero(arBssid, MAC_ADDR_LEN);
  1589. ASSERT(prGlueInfo);
  1590. switch (eStatus) {
  1591. case WLAN_STATUS_ROAM_OUT_FIND_BEST:
  1592. case WLAN_STATUS_MEDIA_CONNECT:
  1593. prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED;
  1594. /* indicate assoc event */
  1595. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen);
  1596. wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen);
  1597. /* switch netif on */
  1598. netif_carrier_on(prGlueInfo->prDevHandler);
  1599. do {
  1600. /* print message on console */
  1601. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen);
  1602. ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ?
  1603. (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0';
  1604. DBGLOG(INIT, INFO, "[wifi] %s netif_carrier_on [ssid:%s " MACSTR "]\n",
  1605. prGlueInfo->prDevHandler->name, ssid.aucSsid, MAC2STR(arBssid));
  1606. } while (0);
  1607. if (prGlueInfo->fgIsRegistered == TRUE) {
  1608. struct cfg80211_bss *bss_others = NULL;
  1609. UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */
  1610. /* retrieve channel */
  1611. ucChannelNum =
  1612. wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter,
  1613. prGlueInfo->prAdapter->prAisBssInfo->ucBssIndex);
  1614. if (ucChannelNum <= 14) {
  1615. prChannel =
  1616. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  1617. ieee80211_channel_to_frequency
  1618. (ucChannelNum, IEEE80211_BAND_2GHZ));
  1619. } else {
  1620. prChannel =
  1621. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  1622. ieee80211_channel_to_frequency
  1623. (ucChannelNum, IEEE80211_BAND_5GHZ));
  1624. }
  1625. /* ensure BSS exists */
  1626. bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid,
  1627. ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
  1628. if (bss == NULL) {
  1629. /* create BSS on-the-fly */
  1630. prBssDesc = ((P_AIS_FSM_INFO_T)
  1631. (&(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo)))->prTargetBssDesc;
  1632. if (prBssDesc != NULL) {
  1633. bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo),
  1634. prChannel,
  1635. CFG80211_BSS_FTYPE_PRESP,
  1636. arBssid,
  1637. 0, /* TSF */
  1638. WLAN_CAPABILITY_ESS,
  1639. prBssDesc->u2BeaconInterval, /* beacon interval */
  1640. prBssDesc->aucIEBuf, /* IE */
  1641. prBssDesc->u2IELength, /* IE Length */
  1642. RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */
  1643. GFP_KERNEL);
  1644. }
  1645. }
  1646. /* remove all bsses that before and only channel different with the current connected one
  1647. if without this patch, UI will show channel A is connected even if AP has change channel
  1648. from A to B */
  1649. while (ucLoopCnt--) {
  1650. bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid,
  1651. ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
  1652. if (bss && bss_others && bss_others != bss) {
  1653. DBGLOG(SCN, INFO, "remove BSSes that only channel different\n");
  1654. cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others);
  1655. } else
  1656. break;
  1657. }
  1658. /* CFG80211 Indication */
  1659. if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) {
  1660. cfg80211_roamed_bss(prGlueInfo->prDevHandler,
  1661. bss,
  1662. prGlueInfo->aucReqIe,
  1663. prGlueInfo->u4ReqIeLength,
  1664. prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL);
  1665. } else {
  1666. cfg80211_connect_result(prGlueInfo->prDevHandler, arBssid,
  1667. prGlueInfo->aucReqIe,
  1668. prGlueInfo->u4ReqIeLength,
  1669. prGlueInfo->aucRspIe,
  1670. prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL);
  1671. }
  1672. }
  1673. break;
  1674. case WLAN_STATUS_MEDIA_DISCONNECT:
  1675. case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY:
  1676. /* indicate disassoc event */
  1677. wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0);
  1678. /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first,
  1679. after associated success, at joinComplete(), do netif_carier_on,
  1680. but for unknown reason, the supplicant 1x pkt will not called the driver
  1681. hardStartXmit, for template workaround these bugs, add this compiling flag
  1682. */
  1683. /* switch netif off */
  1684. #if 1 /* CONSOLE_MESSAGE */
  1685. DBGLOG(INIT, INFO, "[wifi] %s netif_carrier_off\n", prGlueInfo->prDevHandler->name);
  1686. #endif
  1687. netif_carrier_off(prGlueInfo->prDevHandler);
  1688. if (prGlueInfo->fgIsRegistered == TRUE) {
  1689. P_BSS_INFO_T prBssInfo = prGlueInfo->prAdapter->prAisBssInfo;
  1690. UINT_16 u2DeauthReason = 0;
  1691. if (prBssInfo)
  1692. u2DeauthReason = prBssInfo->u2DeauthReason;
  1693. /* CFG80211 Indication */
  1694. cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0,
  1695. eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, GFP_KERNEL);
  1696. }
  1697. prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
  1698. break;
  1699. case WLAN_STATUS_SCAN_COMPLETE:
  1700. /* indicate scan complete event */
  1701. wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0);
  1702. DBGLOG(SCN, EVENT, "scan complete, cfg80211 scan request is %p\n", prGlueInfo->prScanRequest);
  1703. /* 1. reset first for newly incoming request */
  1704. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1705. if (prGlueInfo->prScanRequest != NULL) {
  1706. prScanRequest = prGlueInfo->prScanRequest;
  1707. prGlueInfo->prScanRequest = NULL;
  1708. } else
  1709. DBGLOG(SCN, WARN, "scan complete but cfg80211 scan request is NULL\n");
  1710. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1711. /* 2. then CFG80211 Indication */
  1712. if (prScanRequest != NULL)
  1713. cfg80211_scan_done(prScanRequest, FALSE);
  1714. break;
  1715. #if 0
  1716. case WLAN_STATUS_MSDU_OK:
  1717. if (netif_running(prGlueInfo->prDevHandler))
  1718. netif_wake_queue(prGlueInfo->prDevHandler);
  1719. break;
  1720. #endif
  1721. case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION:
  1722. if (pStatus) {
  1723. switch (pStatus->eStatusType) {
  1724. case ENUM_STATUS_TYPE_AUTHENTICATION:
  1725. /* indicate (UC/GC) MIC ERROR event only */
  1726. if ((pAuth->arRequest[0].u4Flags ==
  1727. PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ||
  1728. (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) {
  1729. cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL,
  1730. (pAuth->arRequest[0].u4Flags ==
  1731. PARAM_AUTH_REQUEST_PAIRWISE_ERROR)
  1732. ? NL80211_KEYTYPE_PAIRWISE :
  1733. NL80211_KEYTYPE_GROUP, 0, NULL, GFP_KERNEL);
  1734. wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE,
  1735. (unsigned char *)&pAuth->arRequest[0],
  1736. pAuth->arRequest[0].u4Length);
  1737. }
  1738. break;
  1739. case ENUM_STATUS_TYPE_CANDIDATE_LIST:
  1740. {
  1741. UINT_32 i = 0;
  1742. P_PARAM_PMKID_CANDIDATE_T prPmkidCand =
  1743. (P_PARAM_PMKID_CANDIDATE_T) &pPmkid->arCandidateList[0];
  1744. for (i = 0; i < pPmkid->u4NumCandidates; i++) {
  1745. wext_indicate_wext_event(prGlueInfo,
  1746. IWEVPMKIDCAND,
  1747. (unsigned char *)&pPmkid->arCandidateList[i],
  1748. pPmkid->u4NumCandidates);
  1749. prPmkidCand += sizeof(PARAM_PMKID_CANDIDATE_T);
  1750. }
  1751. }
  1752. break;
  1753. default:
  1754. /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */
  1755. /*
  1756. */
  1757. break;
  1758. }
  1759. }
  1760. break;
  1761. #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
  1762. case WLAN_STATUS_BWCS_UPDATE:
  1763. {
  1764. wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T));
  1765. }
  1766. break;
  1767. #endif
  1768. case WLAN_STATUS_JOIN_TIMEOUT:
  1769. {
  1770. P_BSS_DESC_T prBssDesc = prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc;
  1771. if (prBssDesc)
  1772. COPY_MAC_ADDR(arBssid, prBssDesc->aucBSSID);
  1773. cfg80211_connect_result(prGlueInfo->prDevHandler,
  1774. arBssid,
  1775. prGlueInfo->aucReqIe,
  1776. prGlueInfo->u4ReqIeLength,
  1777. prGlueInfo->aucRspIe,
  1778. prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL);
  1779. break;
  1780. }
  1781. default:
  1782. break;
  1783. }
  1784. } /* kalIndicateStatusAndComplete */
  1785. /*----------------------------------------------------------------------------*/
  1786. /*!
  1787. * \brief This routine is called to update the (re)association request
  1788. * information to the structure used to query and set
  1789. * OID_802_11_ASSOCIATION_INFORMATION.
  1790. *
  1791. * \param[in] prGlueInfo Pointer to the Glue structure.
  1792. * \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association
  1793. * Request frame from the AP.
  1794. * \param[in] u4FrameBodyLen The length of the frame body of the last
  1795. * (Re)Association Request frame.
  1796. * \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame.
  1797. *
  1798. * \return (none)
  1799. *
  1800. */
  1801. /*----------------------------------------------------------------------------*/
  1802. VOID
  1803. kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo,
  1804. IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest)
  1805. {
  1806. PUINT_8 cp;
  1807. ASSERT(prGlueInfo);
  1808. /* reset */
  1809. prGlueInfo->u4ReqIeLength = 0;
  1810. if (fgReassocRequest) {
  1811. if (u4FrameBodyLen < 15)
  1812. return;
  1813. } else {
  1814. if (u4FrameBodyLen < 9)
  1815. return;
  1816. }
  1817. cp = pucFrameBody;
  1818. if (fgReassocRequest) {
  1819. /* Capability information field 2 */
  1820. /* Listen interval field 2 */
  1821. /* Current AP address 6 */
  1822. cp += 10;
  1823. u4FrameBodyLen -= 10;
  1824. } else {
  1825. /* Capability information field 2 */
  1826. /* Listen interval field 2 */
  1827. cp += 4;
  1828. u4FrameBodyLen -= 4;
  1829. }
  1830. wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen);
  1831. if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) {
  1832. prGlueInfo->u4ReqIeLength = u4FrameBodyLen;
  1833. kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen);
  1834. }
  1835. }
  1836. /*----------------------------------------------------------------------------*/
  1837. /*!
  1838. * @brief This routine is called to update the (re)association
  1839. * response information to the structure used to reply with
  1840. * cfg80211_connect_result
  1841. *
  1842. * @param prGlueInfo Pointer to adapter descriptor
  1843. * @param pucFrameBody Pointer to the frame body of the last (Re)Association
  1844. * Response frame from the AP
  1845. * @param u4FrameBodyLen The length of the frame body of the last
  1846. * (Re)Association Response frame
  1847. *
  1848. * @return (none)
  1849. */
  1850. /*----------------------------------------------------------------------------*/
  1851. VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen)
  1852. {
  1853. UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */
  1854. UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset;
  1855. ASSERT(prGlueInfo);
  1856. /* reset */
  1857. prGlueInfo->u4RspIeLength = 0;
  1858. if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) {
  1859. prGlueInfo->u4RspIeLength = u4IELength;
  1860. kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength);
  1861. }
  1862. } /* kalUpdateReAssocRspInfo */
  1863. VOID kalResetPacket(IN P_GLUE_INFO_T prGlueInfo, IN P_NATIVE_PACKET prPacket)
  1864. {
  1865. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  1866. /* Reset cb */
  1867. kalMemZero(prSkb->cb, sizeof(prSkb->cb));
  1868. }
  1869. /*----------------------------------------------------------------------------*/
  1870. /*
  1871. * \brief This function is TX entry point of NET DEVICE.
  1872. *
  1873. * \param[in] prSkb Pointer of the sk_buff to be sent
  1874. * \param[in] prDev Pointer to struct net_device
  1875. * \param[in] prGlueInfo Pointer of prGlueInfo
  1876. * \param[in] ucBssIndex BSS index of this net device
  1877. *
  1878. * \retval WLAN_STATUS
  1879. */
  1880. /*----------------------------------------------------------------------------*/
  1881. WLAN_STATUS
  1882. kalHardStartXmit(struct sk_buff *prSkb, IN struct net_device *prDev, P_GLUE_INFO_T prGlueInfo, UINT_8 ucBssIndex)
  1883. {
  1884. P_QUE_ENTRY_T prQueueEntry = NULL;
  1885. P_QUE_T prTxQueue = NULL;
  1886. UINT_16 u2QueueIdx = 0;
  1887. GLUE_SPIN_LOCK_DECLARATION();
  1888. ASSERT(prSkb);
  1889. ASSERT(prGlueInfo);
  1890. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  1891. DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n");
  1892. dev_kfree_skb(prSkb);
  1893. return WLAN_STATUS_ADAPTER_NOT_READY;
  1894. }
  1895. prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
  1896. prTxQueue = &prGlueInfo->rTxQueue;
  1897. GLUE_SET_PKT_BSS_IDX(prSkb, ucBssIndex);
  1898. #if CFG_DBG_GPIO_PINS
  1899. /* TX request from OS */
  1900. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
  1901. kalUdelay(1);
  1902. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
  1903. #endif
  1904. /* Parsing frame info */
  1905. if (!wlanProcessTxFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb)) {
  1906. /* Cannot extract packet */
  1907. DBGLOG(INIT, INFO, "Cannot extract content, skip this frame\n");
  1908. dev_kfree_skb(prSkb);
  1909. return WLAN_STATUS_INVALID_PACKET;
  1910. }
  1911. /* Tx profiling */
  1912. wlanTxProfilingTagPacket(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb, TX_PROF_TAG_OS_TO_DRV);
  1913. /* Handle normal data frame */
  1914. u2QueueIdx = skb_get_queue_mapping(prSkb);
  1915. if (u2QueueIdx >= CFG_MAX_TXQ_NUM) {
  1916. DBGLOG(INIT, INFO, "Incorrect queue index, skip this frame\n");
  1917. dev_kfree_skb(prSkb);
  1918. return WLAN_STATUS_INVALID_PACKET;
  1919. }
  1920. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1921. QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
  1922. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1923. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
  1924. GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]);
  1925. if (GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx])
  1926. >= prGlueInfo->prAdapter->rWifiVar.u4NetifStopTh) {
  1927. netif_stop_subqueue(prDev, u2QueueIdx);
  1928. DBGLOG(TX, INFO,
  1929. "Stop subqueue for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%ld] PER-Q_CNT[%ld]\n",
  1930. ucBssIndex, u2QueueIdx, prSkb->len,
  1931. GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum),
  1932. GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex]
  1933. [u2QueueIdx]));
  1934. }
  1935. /* Update NetDev statisitcs */
  1936. prDev->stats.tx_bytes += prSkb->len;
  1937. prDev->stats.tx_packets++;
  1938. DBGLOG(TX, LOUD,
  1939. "Enqueue frame for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%ld] PER-Q_CNT[%ld]\n",
  1940. ucBssIndex, u2QueueIdx, prSkb->len,
  1941. GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum),
  1942. GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]));
  1943. kalSetEvent(prGlueInfo);
  1944. return WLAN_STATUS_SUCCESS;
  1945. } /* end of kalHardStartXmit() */
  1946. WLAN_STATUS kalResetStats(IN struct net_device *prDev)
  1947. {
  1948. DBGLOG(QM, LOUD, "Reset NetDev[0x%p] statistics\n", prDev);
  1949. kalMemZero(kalGetStats(prDev), sizeof(struct net_device_stats));
  1950. return WLAN_STATUS_SUCCESS;
  1951. }
  1952. /*----------------------------------------------------------------------------*/
  1953. /*!
  1954. * \brief A method of struct net_device, to get the network interface statistical
  1955. * information.
  1956. *
  1957. * Whenever an application needs to get statistics for the interface, this method
  1958. * is called. This happens, for example, when ifconfig or netstat -i is run.
  1959. *
  1960. * \param[in] prDev Pointer to struct net_device.
  1961. *
  1962. * \return net_device_stats buffer pointer.
  1963. */
  1964. /*----------------------------------------------------------------------------*/
  1965. PVOID kalGetStats(IN struct net_device *prDev)
  1966. {
  1967. return (PVOID) &prDev->stats;
  1968. } /* end of wlanGetStats() */
  1969. /*----------------------------------------------------------------------------*/
  1970. /*!
  1971. * \brief Notify OS with SendComplete event of the specific packet. Linux should
  1972. * free packets here.
  1973. *
  1974. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  1975. * \param[in] pvPacket Pointer of Packet Handle
  1976. * \param[in] status Status Code for OS upper layer
  1977. *
  1978. * \return -
  1979. */
  1980. /*----------------------------------------------------------------------------*/
  1981. VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket)
  1982. {
  1983. struct net_device *prDev = NULL;
  1984. struct sk_buff *prSkb = NULL;
  1985. UINT_16 u2QueueIdx = 0;
  1986. UINT_8 ucBssIndex = 0;
  1987. BOOLEAN fgIsValidDevice = TRUE;
  1988. ASSERT(pvPacket);
  1989. /* ASSERT(prGlueInfo->i4TxPendingFrameNum); */
  1990. prSkb = (struct sk_buff *)pvPacket;
  1991. u2QueueIdx = skb_get_queue_mapping(prSkb);
  1992. ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
  1993. ucBssIndex = GLUE_GET_PKT_BSS_IDX(pvPacket);
  1994. #if CFG_ENABLE_WIFI_DIRECT
  1995. {
  1996. P_BSS_INFO_T prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIndex);
  1997. /* in case packet was sent after P2P device is unregistered */
  1998. if ((prBssInfo->eNetworkType == NETWORK_TYPE_P2P) &&
  1999. (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE)) {
  2000. fgIsValidDevice = FALSE;
  2001. }
  2002. }
  2003. #endif
  2004. #if 0
  2005. if ((GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) <= 0)) {
  2006. UINT_8 ucBssIdx;
  2007. UINT_16 u2QIdx;
  2008. DBGLOG(INIT, INFO, "TxPendingFrameNum[%u] CurFrameId[%u]\n", prGlueInfo->i4TxPendingFrameNum,
  2009. GLUE_GET_PKT_ARRIVAL_TIME(pvPacket));
  2010. for (ucBssIdx = 0; ucBssIdx < HW_BSSID_NUM; ucBssIdx++) {
  2011. for (u2QIdx = 0; u2QIdx < CFG_MAX_TXQ_NUM; u2QIdx++) {
  2012. DBGLOG(INIT, INFO, "BSS[%u] Q[%u] TxPendingFrameNum[%u]\n",
  2013. ucBssIdx, u2QIdx, prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIdx][u2QIdx]);
  2014. }
  2015. }
  2016. }
  2017. ASSERT((GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) > 0));
  2018. #endif
  2019. GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
  2020. GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]);
  2021. DBGLOG(TX, LOUD,
  2022. "Release frame for BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%ld] PER-Q_CNT[%ld]\n",
  2023. ucBssIndex, u2QueueIdx, prSkb->len,
  2024. GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum),
  2025. GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]));
  2026. prDev = prSkb->dev;
  2027. ASSERT(prDev);
  2028. if (fgIsValidDevice == TRUE) {
  2029. UINT_32 u4StartTh = prGlueInfo->prAdapter->rWifiVar.u4NetifStartTh;
  2030. if (netif_subqueue_stopped(prDev, prSkb) &&
  2031. prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx] <= u4StartTh) {
  2032. netif_wake_subqueue(prDev, u2QueueIdx);
  2033. DBGLOG(TX, INFO,
  2034. "WakeUp Queue BSS[%u] QIDX[%u] PKT_LEN[%u] TOT_CNT[%ld] PER-Q_CNT[%ld]\n",
  2035. ucBssIndex, u2QueueIdx, prSkb->len,
  2036. GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum),
  2037. GLUE_GET_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex]
  2038. [u2QueueIdx]));
  2039. }
  2040. }
  2041. dev_kfree_skb((struct sk_buff *)pvPacket);
  2042. DBGLOG(TX, LOUD, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum);
  2043. }
  2044. /*----------------------------------------------------------------------------*/
  2045. /*!
  2046. * \brief Copy Mac Address setting from registry. It's All Zeros in Linux.
  2047. *
  2048. * \param[in] prAdapter Pointer to the Adapter structure
  2049. *
  2050. * \param[out] paucMacAddr Pointer to the Mac Address buffer
  2051. *
  2052. * \retval WLAN_STATUS_SUCCESS
  2053. *
  2054. * \note
  2055. */
  2056. /*----------------------------------------------------------------------------*/
  2057. VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr)
  2058. {
  2059. UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }
  2060. DEBUGFUNC("kalQueryRegistryMacAddr");
  2061. ASSERT(prGlueInfo);
  2062. ASSERT(paucMacAddr);
  2063. kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN);
  2064. } /* end of kalQueryRegistryMacAddr() */
  2065. #if CFG_SUPPORT_EXT_CONFIG
  2066. /*----------------------------------------------------------------------------*/
  2067. /*!
  2068. * \brief Read external configuration, ex. NVRAM or file
  2069. *
  2070. * \param[in] prGlueInfo Pointer of GLUE Data Structure
  2071. *
  2072. * \return none
  2073. */
  2074. /*----------------------------------------------------------------------------*/
  2075. UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo)
  2076. {
  2077. ASSERT(prGlueInfo);
  2078. /* External data is given from user space by ioctl or /proc, not read by
  2079. driver.
  2080. */
  2081. if (0 != prGlueInfo->u4ExtCfgLength)
  2082. DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n");
  2083. else
  2084. DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n");
  2085. return prGlueInfo->u4ExtCfgLength;
  2086. }
  2087. #endif
  2088. BOOLEAN
  2089. kalIPv4FrameClassifier(IN P_GLUE_INFO_T prGlueInfo,
  2090. IN P_NATIVE_PACKET prPacket, IN PUINT_8 pucIpHdr, OUT P_TX_PACKET_INFO prTxPktInfo)
  2091. {
  2092. UINT_8 ucIpVersion;
  2093. /* UINT_16 u2IpId; */
  2094. /* IPv4 version check */
  2095. ucIpVersion = (pucIpHdr[0] & IP_VERSION_MASK) >> IP_VERSION_OFFSET;
  2096. if (ucIpVersion != IP_VERSION_4) {
  2097. DBGLOG(TX, WARN, "Invalid IPv4 packet version: %u\n", ucIpVersion);
  2098. return FALSE;
  2099. }
  2100. /* WLAN_GET_FIELD_16(&pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET], &u2IpId); */
  2101. if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) {
  2102. PUINT_8 pucUdpHdr = &pucIpHdr[IPV4_HDR_LEN];
  2103. UINT_16 u2DstPort;
  2104. /* UINT_16 u2SrcPort; */
  2105. /* DBGLOG_MEM8(INIT, INFO, pucUdpHdr, 256); */
  2106. /* Get UDP DST port */
  2107. WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_DST_PORT_OFFSET], &u2DstPort);
  2108. /* DBGLOG(INIT, INFO, ("UDP DST[%u]\n", u2DstPort)); */
  2109. /* Get UDP SRC port */
  2110. /* WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_SRC_PORT_OFFSET], &u2SrcPort); */
  2111. /* BOOTP/DHCP protocol */
  2112. if ((u2DstPort == IP_PORT_BOOTP_SERVER) || (u2DstPort == IP_PORT_BOOTP_CLIENT)) {
  2113. P_BOOTP_PROTOCOL_T prBootp = (P_BOOTP_PROTOCOL_T) &pucUdpHdr[UDP_HDR_LEN];
  2114. UINT_32 u4DhcpMagicCode;
  2115. WLAN_GET_FIELD_BE32(&prBootp->aucOptions[0], &u4DhcpMagicCode);
  2116. #if 0
  2117. DBGLOG(INIT, INFO, "DHCP MGC[0x%08x] XID[%u] OPT[%u] TYPE[%u]\n",
  2118. u4DhcpMagicCode, prBootp->u4TransId, prBootp->aucOptions[4],
  2119. prBootp->aucOptions[6]);
  2120. #endif
  2121. if (u4DhcpMagicCode == DHCP_MAGIC_NUMBER) {
  2122. UINT_32 u4Xid;
  2123. WLAN_GET_FIELD_BE32(&prBootp->u4TransId, &u4Xid);
  2124. DBGLOG(TX, INFO, "DHCP PKT[0x%p] XID[0x%08x] OPT[%u] TYPE[%u]\n",
  2125. prPacket, u4Xid, prBootp->aucOptions[4], prBootp->aucOptions[6]);
  2126. prTxPktInfo->u2Flag |= BIT(ENUM_PKT_DHCP);
  2127. }
  2128. }
  2129. }
  2130. return TRUE;
  2131. }
  2132. /*----------------------------------------------------------------------------*/
  2133. /*!
  2134. * @brief This inline function is to extract some packet information, including
  2135. * user priority, packet length, destination address, 802.1x and BT over Wi-Fi
  2136. * or not.
  2137. *
  2138. * @param prGlueInfo Pointer to the glue structure
  2139. * @param prPacket Packet descriptor
  2140. * @param prTxPktInfo Extracted packet info
  2141. *
  2142. * @retval TRUE Success to extract information
  2143. * @retval FALSE Fail to extract correct information
  2144. */
  2145. /*----------------------------------------------------------------------------*/
  2146. BOOLEAN
  2147. kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo,
  2148. IN P_NATIVE_PACKET prPacket, OUT P_TX_PACKET_INFO prTxPktInfo)
  2149. {
  2150. UINT_32 u4PacketLen;
  2151. UINT_16 u2EtherTypeLen;
  2152. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  2153. PUINT_8 aucLookAheadBuf = NULL;
  2154. UINT_8 ucEthTypeLenOffset = ETHER_HEADER_LEN - ETHER_TYPE_LEN;
  2155. PUINT_8 pucNextProtocol = NULL;
  2156. u4PacketLen = prSkb->len;
  2157. if (u4PacketLen < ETHER_HEADER_LEN) {
  2158. DBGLOG(INIT, WARN, "Invalid Ether packet length: %lu\n", u4PacketLen);
  2159. return FALSE;
  2160. }
  2161. aucLookAheadBuf = prSkb->data;
  2162. STATS_TX_PKT_INFO_DISPLAY(aucLookAheadBuf);
  2163. /* Reset Packet Info */
  2164. kalMemZero(prTxPktInfo, sizeof(TX_PACKET_INFO));
  2165. /* 4 <0> Obtain Ether Type/Len */
  2166. WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen);
  2167. /* 4 <1> Skip 802.1Q header (VLAN Tagging) */
  2168. if (u2EtherTypeLen == ETH_P_VLAN) {
  2169. prTxPktInfo->u2Flag |= BIT(ENUM_PKT_VLAN_EXIST);
  2170. ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN;
  2171. WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen);
  2172. }
  2173. /* 4 <2> Obtain next protocol pointer */
  2174. pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + ETHER_TYPE_LEN];
  2175. /* 4 <3> Handle ethernet format */
  2176. switch (u2EtherTypeLen) {
  2177. /* IPv4 */
  2178. case ETH_P_IPV4:
  2179. /* IPv4 header length check */
  2180. if (u4PacketLen < (ucEthTypeLenOffset + ETHER_TYPE_LEN + IPV4_HDR_LEN)) {
  2181. DBGLOG(INIT, WARN, "Invalid IPv4 packet length: %lu\n", u4PacketLen);
  2182. break;
  2183. }
  2184. kalIPv4FrameClassifier(prGlueInfo, prPacket, pucNextProtocol, prTxPktInfo);
  2185. break;
  2186. #if 0
  2187. /* IPv6 */
  2188. case ETH_P_IPV6:
  2189. {
  2190. PUINT_8 pucIpHdr = pucNextProtocol;
  2191. UINT_8 ucIpVersion;
  2192. /* IPv6 header length check */
  2193. if (u4PacketLen < (ucEthTypeLenOffset + ETHER_TYPE_LEN + IPV6_HDR_LEN)) {
  2194. DBGLOG(INIT, WARN, "Invalid IPv6 packet length: %lu\n", u4PacketLen);
  2195. return FALSE;
  2196. }
  2197. /* IPv6 version check */
  2198. ucIpVersion = (pucIpHdr[0] & IP_VERSION_MASK) >> IP_VERSION_OFFSET;
  2199. if (ucIpVersion != IP_VERSION_6) {
  2200. DBGLOG(INIT, WARN, "Invalid IPv6 packet version: %u\n", ucIpVersion);
  2201. return FALSE;
  2202. }
  2203. /* Get the DSCP value from the header of IP packet. */
  2204. ucUserPriority = ((pucIpHdr[0] & IPV6_HDR_TC_PREC_MASK) >> IPV6_HDR_TC_PREC_OFFSET);
  2205. }
  2206. break;
  2207. #endif
  2208. case ETH_P_ARP:
  2209. {
  2210. UINT_16 u2ArpOp;
  2211. WLAN_GET_FIELD_BE16(&pucNextProtocol[ARP_OPERATION_OFFSET], &u2ArpOp);
  2212. DBGLOG(TX, INFO, "ARP %s PKT[0x%p] TAR MAC/IP[" MACSTR "]/[" IPV4STR "]\n",
  2213. u2ArpOp == ARP_OPERATION_REQUEST ? "REQ" : "RSP",
  2214. prPacket, MAC2STR(&pucNextProtocol[ARP_TARGET_MAC_OFFSET]),
  2215. IPV4TOSTR(&pucNextProtocol[ARP_TARGET_IP_OFFSET]));
  2216. prTxPktInfo->u2Flag |= BIT(ENUM_PKT_ARP);
  2217. }
  2218. break;
  2219. case ETH_P_1X:
  2220. case ETH_P_PRE_1X:
  2221. #if CFG_SUPPORT_WAPI
  2222. case ETH_WPI_1X:
  2223. #endif
  2224. DBGLOG(TX, TRACE, "SECURITY PKT TX SEND, u2EtherTypeLen: 0x%x\n", u2EtherTypeLen);
  2225. prTxPktInfo->u2Flag |= BIT(ENUM_PKT_1X);
  2226. break;
  2227. default:
  2228. /* 4 <4> Handle 802.3 format if LEN <= 1500 */
  2229. if (u2EtherTypeLen <= ETH_802_3_MAX_LEN)
  2230. prTxPktInfo->u2Flag |= BIT(ENUM_PKT_802_3);
  2231. break;
  2232. }
  2233. /* 4 <4.1> Check for PAL (BT over Wi-Fi) */
  2234. /* Move to kalBowFrameClassifier */
  2235. /* 4 <5> Return the value of Priority Parameter. */
  2236. /* prSkb->priority is assigned by Linux wireless utility function(cfg80211_classify8021d) */
  2237. /* at net_dev selection callback (ndo_select_queue) */
  2238. prTxPktInfo->ucPriorityParam = prSkb->priority;
  2239. /* 4 <6> Retrieve Packet Information - DA */
  2240. /* Packet Length/ Destination Address */
  2241. prTxPktInfo->u4PacketLen = u4PacketLen;
  2242. kalMemCopy(prTxPktInfo->aucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN);
  2243. return TRUE;
  2244. } /* end of kalQoSFrameClassifier() */
  2245. BOOLEAN kalGetEthDestAddr(IN P_GLUE_INFO_T prGlueInfo, IN P_NATIVE_PACKET prPacket, OUT PUINT_8 pucEthDestAddr)
  2246. {
  2247. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  2248. PUINT_8 aucLookAheadBuf = NULL;
  2249. /* Sanity Check */
  2250. if (!prPacket || !prGlueInfo)
  2251. return FALSE;
  2252. aucLookAheadBuf = prSkb->data;
  2253. kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN);
  2254. return TRUE;
  2255. }
  2256. VOID
  2257. kalOidComplete(IN P_GLUE_INFO_T prGlueInfo,
  2258. IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus)
  2259. {
  2260. ASSERT(prGlueInfo);
  2261. /* remove timeout check timer */
  2262. wlanoidClearTimeoutCheck(prGlueInfo->prAdapter);
  2263. prGlueInfo->rPendStatus = rOidStatus;
  2264. prGlueInfo->u4OidCompleteFlag = 1;
  2265. /* complete ONLY if there are waiters */
  2266. if (!completion_done(&prGlueInfo->rPendComp)) {
  2267. complete(&prGlueInfo->rPendComp);
  2268. } else {
  2269. DBGLOG(INIT, WARN, "SKIP multiple OID complete!\n");
  2270. WARN_ON(TRUE);
  2271. }
  2272. /* else let it timeout on kalIoctl entry */
  2273. }
  2274. VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo)
  2275. {
  2276. }
  2277. /*----------------------------------------------------------------------------*/
  2278. /*!
  2279. * @brief This function is used to transfer linux ioctl to OID, and we
  2280. * need to specify the behavior of the OID by ourself
  2281. *
  2282. * @param prGlueInfo Pointer to the glue structure
  2283. * @param pvInfoBuf Data buffer
  2284. * @param u4InfoBufLen Data buffer length
  2285. * @param fgRead Is this a read OID
  2286. * @param fgWaitResp does this OID need to wait for values
  2287. * @param fgCmd does this OID compose command packet
  2288. * @param pu4QryInfoLen The data length of the return values
  2289. *
  2290. * @retval TRUE Success to extract information
  2291. * @retval FALSE Fail to extract correct information
  2292. */
  2293. /*----------------------------------------------------------------------------*/
  2294. /* todo: enqueue the i/o requests for multiple processes access */
  2295. /* */
  2296. /* currently, return -1 */
  2297. /* */
  2298. /* static GL_IO_REQ_T OidEntry; */
  2299. WLAN_STATUS
  2300. kalIoctl(IN P_GLUE_INFO_T prGlueInfo,
  2301. IN PFN_OID_HANDLER_FUNC pfnOidHandler,
  2302. IN PVOID pvInfoBuf,
  2303. IN UINT_32 u4InfoBufLen, IN BOOL fgRead, IN BOOL fgWaitResp, IN BOOL fgCmd, OUT PUINT_32 pu4QryInfoLen)
  2304. {
  2305. P_GL_IO_REQ_T prIoReq = NULL;
  2306. WLAN_STATUS ret = WLAN_STATUS_SUCCESS;
  2307. if (fgIsResetting == TRUE)
  2308. return WLAN_STATUS_SUCCESS;
  2309. /* GLUE_SPIN_LOCK_DECLARATION(); */
  2310. ASSERT(prGlueInfo);
  2311. /* <1> Check if driver is halt */
  2312. /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */
  2313. /* return WLAN_STATUS_ADAPTER_NOT_READY; */
  2314. /* } */
  2315. if (down_interruptible(&g_halt_sem))
  2316. return WLAN_STATUS_FAILURE;
  2317. if (g_u4HaltFlag) {
  2318. up(&g_halt_sem);
  2319. return WLAN_STATUS_ADAPTER_NOT_READY;
  2320. }
  2321. if (down_interruptible(&prGlueInfo->ioctl_sem)) {
  2322. up(&g_halt_sem);
  2323. return WLAN_STATUS_FAILURE;
  2324. }
  2325. /* <2> TODO: thread-safe */
  2326. /* <3> point to the OidEntry of Glue layer */
  2327. prIoReq = &(prGlueInfo->OidEntry);
  2328. ASSERT(prIoReq);
  2329. /* <4> Compose the I/O request */
  2330. prIoReq->prAdapter = prGlueInfo->prAdapter;
  2331. prIoReq->pfnOidHandler = pfnOidHandler;
  2332. prIoReq->pvInfoBuf = pvInfoBuf;
  2333. prIoReq->u4InfoBufLen = u4InfoBufLen;
  2334. prIoReq->pu4QryInfoLen = pu4QryInfoLen;
  2335. prIoReq->fgRead = fgRead;
  2336. prIoReq->fgWaitResp = fgWaitResp;
  2337. prIoReq->rStatus = WLAN_STATUS_FAILURE;
  2338. /* <5> Reset the status of pending OID */
  2339. prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE;
  2340. /* prGlueInfo->u4TimeoutFlag = 0; */
  2341. prGlueInfo->u4OidCompleteFlag = 0;
  2342. /* <6> Check if we use the command queue */
  2343. prIoReq->u4Flag = fgCmd;
  2344. /* <7> schedule the OID bit */
  2345. set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag);
  2346. /* <7.1> Hold wakelock to ensure OS won't be suspended */
  2347. KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &prGlueInfo->rTimeoutWakeLock,
  2348. MSEC_TO_JIFFIES(WAKE_LOCK_THREAD_WAKEUP_TIMEOUT));
  2349. /* <8> Wake up tx thread to handle kick start the I/O request */
  2350. wake_up_interruptible(&prGlueInfo->waitq);
  2351. /* <9> Block and wait for event or timeout, current the timeout is 2 secs */
  2352. wait_for_completion(&prGlueInfo->rPendComp);
  2353. {
  2354. /* Case 1: No timeout. */
  2355. /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */
  2356. if (prIoReq->rStatus == WLAN_STATUS_PENDING)
  2357. ret = prGlueInfo->rPendStatus;
  2358. else
  2359. ret = prIoReq->rStatus;
  2360. }
  2361. #if 0
  2362. else {
  2363. /* Case 2: timeout */
  2364. /* clear pending OID's cmd in CMD queue */
  2365. if (fgCmd) {
  2366. prGlueInfo->u4TimeoutFlag = 1;
  2367. wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
  2368. }
  2369. ret = WLAN_STATUS_FAILURE;
  2370. }
  2371. #endif
  2372. /* <10> Clear bit for error handling */
  2373. clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag);
  2374. up(&prGlueInfo->ioctl_sem);
  2375. up(&g_halt_sem);
  2376. return ret;
  2377. }
  2378. /*----------------------------------------------------------------------------*/
  2379. /*!
  2380. * \brief This routine is used to clear all pending security frames
  2381. *
  2382. * \param prGlueInfo Pointer of GLUE Data Structure
  2383. *
  2384. * \retval none
  2385. */
  2386. /*----------------------------------------------------------------------------*/
  2387. VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo)
  2388. {
  2389. P_QUE_T prCmdQue;
  2390. QUE_T rTempCmdQue;
  2391. P_QUE_T prTempCmdQue = &rTempCmdQue;
  2392. QUE_T rReturnCmdQue;
  2393. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  2394. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  2395. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  2396. GLUE_SPIN_LOCK_DECLARATION();
  2397. ASSERT(prGlueInfo);
  2398. QUEUE_INITIALIZE(prReturnCmdQue);
  2399. /* Clear pending security frames in prGlueInfo->rCmdQueue */
  2400. prCmdQue = &prGlueInfo->rCmdQueue;
  2401. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2402. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  2403. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2404. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2405. while (prQueueEntry) {
  2406. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  2407. if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
  2408. if (prCmdInfo->pfCmdTimeoutHandler)
  2409. prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
  2410. else
  2411. wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, TX_RESULT_QUEUE_CLEARANCE);
  2412. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  2413. } else {
  2414. QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry);
  2415. }
  2416. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2417. }
  2418. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2419. QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue);
  2420. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2421. }
  2422. /*----------------------------------------------------------------------------*/
  2423. /*!
  2424. * \brief This routine is used to clear pending security frames
  2425. * belongs to dedicated network type
  2426. *
  2427. * \param prGlueInfo Pointer of GLUE Data Structure
  2428. * \param eNetworkTypeIdx Network Type Index
  2429. *
  2430. * \retval none
  2431. */
  2432. /*----------------------------------------------------------------------------*/
  2433. VOID kalClearSecurityFramesByBssIdx(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucBssIndex)
  2434. {
  2435. P_QUE_T prCmdQue;
  2436. QUE_T rTempCmdQue;
  2437. P_QUE_T prTempCmdQue = &rTempCmdQue;
  2438. QUE_T rReturnCmdQue;
  2439. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  2440. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  2441. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  2442. GLUE_SPIN_LOCK_DECLARATION();
  2443. ASSERT(prGlueInfo);
  2444. QUEUE_INITIALIZE(prReturnCmdQue);
  2445. /* Clear pending security frames in prGlueInfo->rCmdQueue */
  2446. prCmdQue = &prGlueInfo->rCmdQueue;
  2447. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2448. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  2449. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2450. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2451. while (prQueueEntry) {
  2452. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  2453. if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->ucBssIndex == ucBssIndex) {
  2454. if (prCmdInfo->pfCmdTimeoutHandler)
  2455. prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
  2456. else
  2457. wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, TX_RESULT_QUEUE_CLEARANCE);
  2458. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  2459. } else {
  2460. QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry);
  2461. }
  2462. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2463. }
  2464. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2465. QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue);
  2466. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2467. }
  2468. /*----------------------------------------------------------------------------*/
  2469. /*!
  2470. * \brief This routine is used to clear all pending management frames
  2471. *
  2472. * \param prGlueInfo Pointer of GLUE Data Structure
  2473. *
  2474. * \retval none
  2475. */
  2476. /*----------------------------------------------------------------------------*/
  2477. VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo)
  2478. {
  2479. P_QUE_T prCmdQue;
  2480. QUE_T rTempCmdQue;
  2481. P_QUE_T prTempCmdQue = &rTempCmdQue;
  2482. QUE_T rReturnCmdQue;
  2483. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  2484. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  2485. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  2486. GLUE_SPIN_LOCK_DECLARATION();
  2487. ASSERT(prGlueInfo);
  2488. QUEUE_INITIALIZE(prReturnCmdQue);
  2489. /* Clear pending management frames in prGlueInfo->rCmdQueue */
  2490. prCmdQue = &prGlueInfo->rCmdQueue;
  2491. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2492. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  2493. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2494. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2495. while (prQueueEntry) {
  2496. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  2497. if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
  2498. wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, TX_RESULT_QUEUE_CLEARANCE);
  2499. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  2500. } else {
  2501. QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry);
  2502. }
  2503. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2504. }
  2505. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2506. QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue);
  2507. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2508. }
  2509. /*----------------------------------------------------------------------------*/
  2510. /*!
  2511. * \brief This routine is used to clear all pending management frames
  2512. * belongs to dedicated network type
  2513. * \param prGlueInfo Pointer of GLUE Data Structure
  2514. *
  2515. * \retval none
  2516. */
  2517. /*----------------------------------------------------------------------------*/
  2518. VOID kalClearMgmtFramesByBssIdx(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucBssIndex)
  2519. {
  2520. P_QUE_T prCmdQue;
  2521. QUE_T rTempCmdQue;
  2522. P_QUE_T prTempCmdQue = &rTempCmdQue;
  2523. QUE_T rReturnCmdQue;
  2524. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  2525. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  2526. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  2527. GLUE_SPIN_LOCK_DECLARATION();
  2528. ASSERT(prGlueInfo);
  2529. QUEUE_INITIALIZE(prReturnCmdQue);
  2530. /* Clear pending management frames in prGlueInfo->rCmdQueue */
  2531. prCmdQue = &prGlueInfo->rCmdQueue;
  2532. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2533. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  2534. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2535. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2536. while (prQueueEntry) {
  2537. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  2538. if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && prCmdInfo->ucBssIndex == ucBssIndex) {
  2539. wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, TX_RESULT_QUEUE_CLEARANCE);
  2540. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  2541. } else {
  2542. QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry);
  2543. }
  2544. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2545. }
  2546. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2547. QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue);
  2548. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2549. } /* kalClearMgmtFramesByBssIdx */
  2550. /*----------------------------------------------------------------------------*/
  2551. /*!
  2552. * \brief This routine is used to clear all commands in command queue
  2553. * \param prGlueInfo Pointer of GLUE Data Structure
  2554. *
  2555. * \retval none
  2556. */
  2557. /*----------------------------------------------------------------------------*/
  2558. VOID kalClearCommandQueue(IN P_GLUE_INFO_T prGlueInfo)
  2559. {
  2560. P_QUE_T prCmdQue;
  2561. QUE_T rTempCmdQue;
  2562. P_QUE_T prTempCmdQue = &rTempCmdQue;
  2563. QUE_T rReturnCmdQue;
  2564. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  2565. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  2566. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  2567. GLUE_SPIN_LOCK_DECLARATION();
  2568. ASSERT(prGlueInfo);
  2569. QUEUE_INITIALIZE(prReturnCmdQue);
  2570. /* Clear ALL in prGlueInfo->rCmdQueue */
  2571. prCmdQue = &prGlueInfo->rCmdQueue;
  2572. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2573. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  2574. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2575. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2576. while (prQueueEntry) {
  2577. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  2578. if (prCmdInfo->pfCmdTimeoutHandler)
  2579. prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
  2580. else
  2581. wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo, TX_RESULT_QUEUE_CLEARANCE);
  2582. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  2583. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  2584. }
  2585. }
  2586. UINT_32 kalProcessTxPacket(P_GLUE_INFO_T prGlueInfo, struct sk_buff *prSkb)
  2587. {
  2588. UINT_32 u4Status = WLAN_STATUS_SUCCESS;
  2589. if (NULL == prSkb) {
  2590. DBGLOG(INIT, WARN, "prSkb == NULL in tx\n");
  2591. return u4Status;
  2592. }
  2593. /* Handle security frame */
  2594. if (GLUE_TEST_PKT_FLAG(prSkb, ENUM_PKT_1X)) {
  2595. if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb)) {
  2596. u4Status = WLAN_STATUS_SUCCESS;
  2597. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  2598. } else {
  2599. u4Status = WLAN_STATUS_RESOURCES;
  2600. }
  2601. }
  2602. /* Handle normal frame */
  2603. else
  2604. u4Status = wlanEnqueueTxPacket(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb);
  2605. return u4Status;
  2606. }
  2607. /*----------------------------------------------------------------------------*/
  2608. /*!
  2609. * \brief This routine is used to process Tx request to tx_thread
  2610. *
  2611. * \param prGlueInfo Pointer of GLUE Data Structure
  2612. *
  2613. * \retval none
  2614. */
  2615. /*----------------------------------------------------------------------------*/
  2616. VOID kalProcessTxReq(P_GLUE_INFO_T prGlueInfo, PBOOLEAN pfgNeedHwAccess)
  2617. {
  2618. P_QUE_T prCmdQue = NULL;
  2619. P_QUE_T prTxQueue = NULL;
  2620. QUE_T rTempQue;
  2621. P_QUE_T prTempQue = &rTempQue;
  2622. QUE_T rTempReturnQue;
  2623. P_QUE_T prTempReturnQue = &rTempReturnQue;
  2624. P_QUE_ENTRY_T prQueueEntry = NULL;
  2625. /* struct sk_buff *prSkb = NULL; */
  2626. UINT_32 u4Status;
  2627. #if CFG_SUPPORT_MULTITHREAD
  2628. UINT_32 u4CmdCount = 0;
  2629. #endif
  2630. UINT_32 u4TxLoopCount;
  2631. /* for spin lock acquire and release */
  2632. GLUE_SPIN_LOCK_DECLARATION();
  2633. prTxQueue = &prGlueInfo->rTxQueue;
  2634. prCmdQue = &prGlueInfo->rCmdQueue;
  2635. QUEUE_INITIALIZE(prTempQue);
  2636. QUEUE_INITIALIZE(prTempReturnQue);
  2637. u4TxLoopCount = prGlueInfo->prAdapter->rWifiVar.u4TxFromOsLoopCount;
  2638. /* Process Mailbox Messages */
  2639. wlanProcessMboxMessage(prGlueInfo->prAdapter);
  2640. /* Process CMD request */
  2641. #if CFG_SUPPORT_MULTITHREAD
  2642. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2643. u4CmdCount = prCmdQue->u4NumElem;
  2644. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  2645. if (u4CmdCount > 0) {
  2646. #else
  2647. if (prCmdQue->u4NumElem > 0) {
  2648. if (*pfgNeedHwAccess == FALSE) {
  2649. *pfgNeedHwAccess = TRUE;
  2650. wlanAcquirePowerControl(prGlueInfo->prAdapter);
  2651. }
  2652. #endif
  2653. wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue);
  2654. }
  2655. while (u4TxLoopCount--) {
  2656. while (QUEUE_IS_NOT_EMPTY(prTxQueue)) {
  2657. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  2658. QUEUE_MOVE_ALL(prTempQue, prTxQueue);
  2659. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  2660. /* Handle Packet Tx */
  2661. while (QUEUE_IS_NOT_EMPTY(prTempQue)) {
  2662. QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
  2663. if (NULL == prQueueEntry)
  2664. break;
  2665. u4Status =
  2666. kalProcessTxPacket(prGlueInfo,
  2667. (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry));
  2668. #if 0
  2669. prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
  2670. ASSERT(prSkb);
  2671. if (NULL == prSkb) {
  2672. DBGLOG(INIT, WARN, "prSkb == NULL in tx\n");
  2673. continue;
  2674. }
  2675. /* Handle security frame */
  2676. if (GLUE_GET_PKT_IS_1X(prSkb)) {
  2677. if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb)) {
  2678. u4Status = WLAN_STATUS_SUCCESS;
  2679. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  2680. } else {
  2681. u4Status = WLAN_STATUS_RESOURCES;
  2682. }
  2683. }
  2684. /* Handle normal frame */
  2685. else
  2686. u4Status = wlanEnqueueTxPacket(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb);
  2687. #endif
  2688. /* Enqueue packet back into TxQueue if resource is not enough */
  2689. if (u4Status == WLAN_STATUS_RESOURCES) {
  2690. QUEUE_INSERT_TAIL(prTempReturnQue, prQueueEntry);
  2691. break;
  2692. }
  2693. }
  2694. if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0)
  2695. wlanTxPendingPackets(prGlueInfo->prAdapter, pfgNeedHwAccess);
  2696. /* Enqueue packet back into TxQueue if resource is not enough */
  2697. if (QUEUE_IS_NOT_EMPTY(prTempReturnQue)) {
  2698. QUEUE_CONCATENATE_QUEUES(prTempReturnQue, prTempQue);
  2699. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  2700. QUEUE_CONCATENATE_QUEUES_HEAD(prTxQueue, prTempReturnQue);
  2701. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  2702. break;
  2703. }
  2704. }
  2705. if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0)
  2706. wlanTxPendingPackets(prGlueInfo->prAdapter, pfgNeedHwAccess);
  2707. }
  2708. }
  2709. #if CFG_SUPPORT_MULTITHREAD
  2710. /*----------------------------------------------------------------------------*/
  2711. /*!
  2712. * @brief
  2713. *
  2714. * @param data data pointer to private data of hif_thread
  2715. *
  2716. * @retval If the function succeeds, the return value is 0.
  2717. * Otherwise, an error code is returned.
  2718. *
  2719. */
  2720. /*----------------------------------------------------------------------------*/
  2721. int hif_thread(void *data)
  2722. {
  2723. struct net_device *dev = data;
  2724. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
  2725. int ret = 0;
  2726. KAL_WAKE_LOCK_T rHifThreadWakeLock;
  2727. KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &rHifThreadWakeLock, "WLAN hif_thread");
  2728. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rHifThreadWakeLock);
  2729. DBGLOG(INIT, INFO, "hif_thread starts running ID=%d\n", KAL_GET_CURRENT_THREAD_ID());
  2730. prGlueInfo->u4HifThreadPid = KAL_GET_CURRENT_THREAD_ID();
  2731. set_user_nice(current, prGlueInfo->prAdapter->rWifiVar.cThreadNice);
  2732. while (TRUE) {
  2733. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2734. DBGLOG(INIT, INFO, "hif_thread should stop now...\n");
  2735. break;
  2736. }
  2737. /* Unlock wakelock if hif_thread going to idle */
  2738. if (!(prGlueInfo->ulFlag & GLUE_FLAG_HIF_PROCESS))
  2739. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rHifThreadWakeLock);
  2740. /*
  2741. * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT
  2742. * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT
  2743. *
  2744. */
  2745. do {
  2746. ret = wait_event_interruptible(prGlueInfo->waitq_hif,
  2747. ((prGlueInfo->ulFlag & GLUE_FLAG_HIF_PROCESS) != 0));
  2748. } while (ret != 0);
  2749. if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rHifThreadWakeLock))
  2750. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rHifThreadWakeLock);
  2751. wlanAcquirePowerControl(prGlueInfo->prAdapter);
  2752. /* Handle Interrupt */
  2753. if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) {
  2754. /* the Wi-Fi interrupt is already disabled in mmc thread,
  2755. so we set the flag only to enable the interrupt later */
  2756. prGlueInfo->prAdapter->fgIsIntEnable = FALSE;
  2757. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2758. /* Should stop now... skip pending interrupt */
  2759. DBGLOG(INIT, INFO, "ignore pending interrupt\n");
  2760. } else {
  2761. /* DBGLOG(INIT, INFO, ("HIF Interrupt!\n")); */
  2762. wlanIST(prGlueInfo->prAdapter);
  2763. }
  2764. }
  2765. /* TX Commands */
  2766. if (test_and_clear_bit(GLUE_FLAG_HIF_TX_CMD_BIT, &prGlueInfo->ulFlag))
  2767. wlanTxCmdMthread(prGlueInfo->prAdapter);
  2768. /* Process TX data packet to SDIO request */
  2769. if (test_and_clear_bit(GLUE_FLAG_HIF_TX_BIT, &prGlueInfo->ulFlag))
  2770. nicTxMsduQueueMthread(prGlueInfo->prAdapter);
  2771. /* Set FW own */
  2772. if (test_and_clear_bit(GLUE_FLAG_HIF_FW_OWN_BIT, &prGlueInfo->ulFlag))
  2773. prGlueInfo->prAdapter->fgWiFiInSleepyState = TRUE;
  2774. /* Release to FW own */
  2775. wlanReleasePowerControl(prGlueInfo->prAdapter);
  2776. }
  2777. complete(&prGlueInfo->rHifHaltComp);
  2778. if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rHifThreadWakeLock))
  2779. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rHifThreadWakeLock);
  2780. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &rHifThreadWakeLock);
  2781. return 0;
  2782. }
  2783. int rx_thread(void *data)
  2784. {
  2785. struct net_device *dev = data;
  2786. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
  2787. QUE_T rTempRxQue;
  2788. P_QUE_T prTempRxQue = NULL;
  2789. P_QUE_ENTRY_T prQueueEntry = NULL;
  2790. int ret = 0;
  2791. KAL_WAKE_LOCK_T rRxThreadWakeLock;
  2792. UINT_32 u4LoopCount;
  2793. /* for spin lock acquire and release */
  2794. KAL_SPIN_LOCK_DECLARATION();
  2795. KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &rRxThreadWakeLock, "WLAN rx_thread");
  2796. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rRxThreadWakeLock);
  2797. DBGLOG(INIT, INFO, "rx_thread starts running ID=%d\n", KAL_GET_CURRENT_THREAD_ID());
  2798. prGlueInfo->u4RxThreadPid = KAL_GET_CURRENT_THREAD_ID();
  2799. set_user_nice(current, prGlueInfo->prAdapter->rWifiVar.cThreadNice);
  2800. prTempRxQue = &rTempRxQue;
  2801. while (TRUE) {
  2802. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2803. DBGLOG(INIT, INFO, "rx_thread should stop now...\n");
  2804. break;
  2805. }
  2806. /* Unlock wakelock if rx_thread going to idle */
  2807. if (!(prGlueInfo->ulFlag & GLUE_FLAG_RX_PROCESS))
  2808. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rRxThreadWakeLock);
  2809. /*
  2810. * sleep on waitqueue if no events occurred.
  2811. */
  2812. do {
  2813. ret = wait_event_interruptible(prGlueInfo->waitq_rx,
  2814. ((prGlueInfo->ulFlag & GLUE_FLAG_RX_PROCESS) != 0));
  2815. } while (ret != 0);
  2816. if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rRxThreadWakeLock))
  2817. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rRxThreadWakeLock);
  2818. if (test_and_clear_bit(GLUE_FLAG_RX_TO_OS_BIT, &prGlueInfo->ulFlag)) {
  2819. u4LoopCount = prGlueInfo->prAdapter->rWifiVar.u4Rx2OsLoopCount;
  2820. while (u4LoopCount--) {
  2821. while (QUEUE_IS_NOT_EMPTY(&prGlueInfo->prAdapter->rRxQueue)) {
  2822. QUEUE_INITIALIZE(prTempRxQue);
  2823. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_RX_TO_OS_QUE);
  2824. QUEUE_MOVE_ALL(prTempRxQue, &prGlueInfo->prAdapter->rRxQueue);
  2825. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_RX_TO_OS_QUE);
  2826. while (QUEUE_IS_NOT_EMPTY(prTempRxQue)) {
  2827. QUEUE_REMOVE_HEAD(prTempRxQue, prQueueEntry, P_QUE_ENTRY_T);
  2828. kalRxIndicateOnePkt(prGlueInfo,
  2829. (PVOID) GLUE_GET_PKT_DESCRIPTOR(prQueueEntry));
  2830. }
  2831. KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &prGlueInfo->rTimeoutWakeLock,
  2832. MSEC_TO_JIFFIES(WAKE_LOCK_RX_TIMEOUT));
  2833. }
  2834. }
  2835. }
  2836. }
  2837. complete(&prGlueInfo->rRxHaltComp);
  2838. if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rRxThreadWakeLock))
  2839. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rRxThreadWakeLock);
  2840. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &rRxThreadWakeLock);
  2841. return 0;
  2842. }
  2843. #endif
  2844. /*----------------------------------------------------------------------------*/
  2845. /*!
  2846. * @brief This function is a kernel thread function for handling command packets
  2847. * Tx requests and interrupt events
  2848. *
  2849. * @param data data pointer to private data of tx_thread
  2850. *
  2851. * @retval If the function succeeds, the return value is 0.
  2852. * Otherwise, an error code is returned.
  2853. *
  2854. */
  2855. /*----------------------------------------------------------------------------*/
  2856. int tx_thread(void *data)
  2857. {
  2858. struct net_device *dev = data;
  2859. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
  2860. P_GL_IO_REQ_T prIoReq = NULL;
  2861. int ret = 0;
  2862. BOOLEAN fgNeedHwAccess = FALSE;
  2863. KAL_WAKE_LOCK_T rTxThreadWakeLock;
  2864. #if CFG_SUPPORT_MULTITHREAD
  2865. prGlueInfo->u4TxThreadPid = KAL_GET_CURRENT_THREAD_ID();
  2866. #endif
  2867. current->flags |= PF_NOFREEZE;
  2868. ASSERT(prGlueInfo);
  2869. ASSERT(prGlueInfo->prAdapter);
  2870. set_user_nice(current, prGlueInfo->prAdapter->rWifiVar.cThreadNice);
  2871. KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &rTxThreadWakeLock, "WLAN tx_thread");
  2872. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rTxThreadWakeLock);
  2873. DBGLOG(INIT, INFO, "tx_thread starts running...\n");
  2874. while (TRUE) {
  2875. #if CFG_ENABLE_WIFI_DIRECT
  2876. /*run p2p multicast list work. */
  2877. if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag))
  2878. p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
  2879. #endif
  2880. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2881. DBGLOG(INIT, INFO, "tx_thread should stop now...\n");
  2882. break;
  2883. }
  2884. /* Unlock wakelock if tx_thread going to idle */
  2885. if (!(prGlueInfo->ulFlag & GLUE_FLAG_TX_PROCESS))
  2886. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rTxThreadWakeLock);
  2887. /*
  2888. * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT
  2889. * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT
  2890. *
  2891. */
  2892. do {
  2893. ret = wait_event_interruptible(prGlueInfo->waitq,
  2894. ((prGlueInfo->ulFlag & GLUE_FLAG_TX_PROCESS) != 0));
  2895. } while (ret != 0);
  2896. if (!KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rTxThreadWakeLock))
  2897. KAL_WAKE_LOCK(prGlueInfo->prAdapter, &rTxThreadWakeLock);
  2898. #if CFG_DBG_GPIO_PINS
  2899. /* TX thread Wake up */
  2900. mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW);
  2901. #endif
  2902. #if CFG_ENABLE_WIFI_DIRECT
  2903. /*run p2p multicast list work. */
  2904. if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag))
  2905. p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
  2906. if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) {
  2907. p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter,
  2908. prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter);
  2909. }
  2910. #endif
  2911. if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) {
  2912. P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL;
  2913. prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo);
  2914. prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter;
  2915. }
  2916. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2917. DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n");
  2918. break;
  2919. }
  2920. fgNeedHwAccess = FALSE;
  2921. #if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN
  2922. if (prGlueInfo->fgEnSdioTestPattern == TRUE) {
  2923. if (fgNeedHwAccess == FALSE) {
  2924. fgNeedHwAccess = TRUE;
  2925. wlanAcquirePowerControl(prGlueInfo->prAdapter);
  2926. }
  2927. if (prGlueInfo->fgIsSdioTestInitialized == FALSE) {
  2928. /* enable PRBS mode */
  2929. kalDevRegWrite(prGlueInfo, MCR_WTMCR, 0x00080002);
  2930. prGlueInfo->fgIsSdioTestInitialized = TRUE;
  2931. }
  2932. if (prGlueInfo->fgSdioReadWriteMode == TRUE) {
  2933. /* read test */
  2934. kalDevPortRead(prGlueInfo,
  2935. MCR_WTMDR,
  2936. 256,
  2937. prGlueInfo->aucSdioTestBuffer, sizeof(prGlueInfo->aucSdioTestBuffer));
  2938. } else {
  2939. /* write test */
  2940. kalDevPortWrite(prGlueInfo,
  2941. MCR_WTMDR,
  2942. 172,
  2943. prGlueInfo->aucSdioTestBuffer, sizeof(prGlueInfo->aucSdioTestBuffer));
  2944. }
  2945. }
  2946. #endif
  2947. #if CFG_SUPPORT_MULTITHREAD
  2948. #else
  2949. /* Handle Interrupt */
  2950. if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) {
  2951. if (fgNeedHwAccess == FALSE) {
  2952. fgNeedHwAccess = TRUE;
  2953. wlanAcquirePowerControl(prGlueInfo->prAdapter);
  2954. }
  2955. /* the Wi-Fi interrupt is already disabled in mmc thread,
  2956. so we set the flag only to enable the interrupt later */
  2957. prGlueInfo->prAdapter->fgIsIntEnable = FALSE;
  2958. /* wlanISR(prGlueInfo->prAdapter, TRUE); */
  2959. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2960. /* Should stop now... skip pending interrupt */
  2961. DBGLOG(INIT, INFO, "ignore pending interrupt\n");
  2962. } else {
  2963. wlanIST(prGlueInfo->prAdapter);
  2964. }
  2965. }
  2966. #endif
  2967. /* transfer ioctl to OID request */
  2968. #if 0
  2969. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  2970. DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n");
  2971. break;
  2972. }
  2973. #endif
  2974. do {
  2975. if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) {
  2976. /* get current prIoReq */
  2977. prIoReq = &(prGlueInfo->OidEntry);
  2978. if (FALSE == prIoReq->fgRead) {
  2979. prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter,
  2980. prIoReq->pfnOidHandler,
  2981. prIoReq->pvInfoBuf,
  2982. prIoReq->u4InfoBufLen,
  2983. prIoReq->pu4QryInfoLen);
  2984. } else {
  2985. prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter,
  2986. prIoReq->pfnOidHandler,
  2987. prIoReq->pvInfoBuf,
  2988. prIoReq->u4InfoBufLen,
  2989. prIoReq->pu4QryInfoLen);
  2990. }
  2991. if (prIoReq->rStatus != WLAN_STATUS_PENDING) {
  2992. /* complete ONLY if there are waiters */
  2993. if (!completion_done(&prGlueInfo->rPendComp)) {
  2994. complete(&prGlueInfo->rPendComp);
  2995. } else {
  2996. DBGLOG(INIT, WARN,
  2997. "SKIP multiple OID complete!\n");
  2998. }
  2999. } else {
  3000. wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler);
  3001. }
  3002. }
  3003. } while (FALSE);
  3004. /*
  3005. *
  3006. * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent
  3007. * indicates the following requests occur
  3008. *
  3009. */
  3010. #if 0
  3011. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  3012. DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n");
  3013. break;
  3014. }
  3015. #endif
  3016. if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag))
  3017. kalProcessTxReq(prGlueInfo, &fgNeedHwAccess);
  3018. #if CFG_SUPPORT_MULTITHREAD
  3019. /* Process RX */
  3020. if (test_and_clear_bit(GLUE_FLAG_RX_BIT, &prGlueInfo->ulFlag))
  3021. nicRxProcessRFBs(prGlueInfo->prAdapter);
  3022. if (test_and_clear_bit(GLUE_FLAG_TX_CMD_DONE_BIT, &prGlueInfo->ulFlag))
  3023. wlanTxCmdDoneMthread(prGlueInfo->prAdapter);
  3024. #endif
  3025. /* Process RX, In linux, we don't need to free sk_buff by ourself */
  3026. /* In linux, we don't need to free sk_buff by ourself */
  3027. /* In linux, we don't do reset */
  3028. #if CFG_SUPPORT_MULTITHREAD
  3029. #else
  3030. if (fgNeedHwAccess == TRUE)
  3031. wlanReleasePowerControl(prGlueInfo->prAdapter);
  3032. #endif
  3033. /* handle cnmTimer time out */
  3034. if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag))
  3035. wlanTimerTimeoutCheck(prGlueInfo->prAdapter);
  3036. #if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN
  3037. if (prGlueInfo->fgEnSdioTestPattern == TRUE)
  3038. kalSetEvent(prGlueInfo);
  3039. #endif
  3040. #if CFG_DBG_GPIO_PINS
  3041. /* TX thread go to sleep */
  3042. if (!prGlueInfo->ulFlag)
  3043. mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH);
  3044. #endif
  3045. }
  3046. #if 0
  3047. if (fgNeedHwAccess == TRUE)
  3048. wlanReleasePowerControl(prGlueInfo->prAdapter);
  3049. #endif
  3050. /* flush the pending TX packets */
  3051. if (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum) > 0)
  3052. kalFlushPendingTxPackets(prGlueInfo);
  3053. /* flush pending security frames */
  3054. if (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum) > 0)
  3055. kalClearSecurityFrames(prGlueInfo);
  3056. /* remove pending oid */
  3057. wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
  3058. /* In linux, we don't need to free sk_buff by ourself */
  3059. DBGLOG(INIT, INFO, "mtk_sdiod stops\n");
  3060. complete(&prGlueInfo->rHaltComp);
  3061. if (KAL_WAKE_LOCK_ACTIVE(prGlueInfo->prAdapter, &rTxThreadWakeLock))
  3062. KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &rTxThreadWakeLock);
  3063. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &rTxThreadWakeLock);
  3064. return 0;
  3065. }
  3066. /*----------------------------------------------------------------------------*/
  3067. /*!
  3068. * \brief This routine is used to check if card is removed
  3069. *
  3070. * \param pvGlueInfo Pointer of GLUE Data Structure
  3071. *
  3072. * \retval TRUE: card is removed
  3073. * FALSE: card is still attached
  3074. */
  3075. /*----------------------------------------------------------------------------*/
  3076. BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo)
  3077. {
  3078. ASSERT(prGlueInfo);
  3079. return FALSE;
  3080. /* Linux MMC doesn't have removal notification yet */
  3081. }
  3082. /*----------------------------------------------------------------------------*/
  3083. /*!
  3084. * \brief This routine is used to send command to firmware for overriding netweork address
  3085. *
  3086. * \param pvGlueInfo Pointer of GLUE Data Structure
  3087. * \retval TRUE
  3088. * FALSE
  3089. */
  3090. /*----------------------------------------------------------------------------*/
  3091. BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr)
  3092. {
  3093. ASSERT(prGlueInfo);
  3094. if (prGlueInfo->fgIsMacAddrOverride == FALSE) {
  3095. #if !defined(CONFIG_X86)
  3096. UINT_32 i;
  3097. BOOLEAN fgIsReadError = FALSE;
  3098. for (i = 0; i < MAC_ADDR_LEN; i += 2) {
  3099. if (kalCfgDataRead16(prGlueInfo,
  3100. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
  3101. (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) {
  3102. fgIsReadError = TRUE;
  3103. break;
  3104. }
  3105. }
  3106. if (fgIsReadError == TRUE)
  3107. return FALSE;
  3108. else
  3109. return TRUE;
  3110. #else
  3111. /* x86 Linux doesn't need to override network address so far */
  3112. return FALSE;
  3113. #endif
  3114. } else {
  3115. COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride);
  3116. return TRUE;
  3117. }
  3118. }
  3119. /*----------------------------------------------------------------------------*/
  3120. /*!
  3121. * \brief This routine is used to flush pending TX packets in glue layer
  3122. *
  3123. * \param pvGlueInfo Pointer of GLUE Data Structure
  3124. *
  3125. * \retval none
  3126. */
  3127. /*----------------------------------------------------------------------------*/
  3128. VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo)
  3129. {
  3130. P_QUE_T prTxQue;
  3131. P_QUE_ENTRY_T prQueueEntry;
  3132. PVOID prPacket;
  3133. GLUE_SPIN_LOCK_DECLARATION();
  3134. ASSERT(prGlueInfo);
  3135. prTxQue = &(prGlueInfo->rTxQueue);
  3136. if (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum)) {
  3137. while (TRUE) {
  3138. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  3139. QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T);
  3140. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  3141. if (prQueueEntry == NULL)
  3142. break;
  3143. prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
  3144. kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED);
  3145. }
  3146. }
  3147. }
  3148. /*----------------------------------------------------------------------------*/
  3149. /*!
  3150. * \brief This routine is get indicated media state
  3151. *
  3152. * \param pvGlueInfo Pointer of GLUE Data Structure
  3153. *
  3154. * \retval
  3155. */
  3156. /*----------------------------------------------------------------------------*/
  3157. ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo)
  3158. {
  3159. ASSERT(prGlueInfo);
  3160. return prGlueInfo->eParamMediaStateIndicated;
  3161. }
  3162. /*----------------------------------------------------------------------------*/
  3163. /*!
  3164. * \brief This routine is used to set indicated media state
  3165. *
  3166. * \param pvGlueInfo Pointer of GLUE Data Structure
  3167. *
  3168. * \retval none
  3169. */
  3170. /*----------------------------------------------------------------------------*/
  3171. VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate)
  3172. {
  3173. ASSERT(prGlueInfo);
  3174. prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate;
  3175. }
  3176. /*----------------------------------------------------------------------------*/
  3177. /*!
  3178. * \brief This routine is used to clear pending OID staying in command queue
  3179. *
  3180. * \param prGlueInfo Pointer of GLUE Data Structure
  3181. *
  3182. * \retval none
  3183. */
  3184. /*----------------------------------------------------------------------------*/
  3185. VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo)
  3186. {
  3187. P_QUE_T prCmdQue;
  3188. QUE_T rTempCmdQue;
  3189. P_QUE_T prTempCmdQue = &rTempCmdQue;
  3190. QUE_T rReturnCmdQue;
  3191. P_QUE_T prReturnCmdQue = &rReturnCmdQue;
  3192. P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL;
  3193. P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL;
  3194. GLUE_SPIN_LOCK_DECLARATION();
  3195. ASSERT(prGlueInfo);
  3196. QUEUE_INITIALIZE(prReturnCmdQue);
  3197. prCmdQue = &prGlueInfo->rCmdQueue;
  3198. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3199. QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
  3200. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3201. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  3202. while (prQueueEntry) {
  3203. if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) {
  3204. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  3205. break;
  3206. }
  3207. QUEUE_INSERT_TAIL(prReturnCmdQue, prQueueEntry);
  3208. QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
  3209. }
  3210. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3211. QUEUE_CONCATENATE_QUEUES_HEAD(prCmdQue, prReturnCmdQue);
  3212. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3213. if (prCmdInfo) {
  3214. if (prCmdInfo->pfCmdTimeoutHandler)
  3215. prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
  3216. else
  3217. kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED);
  3218. prGlueInfo->u4OidCompleteFlag = 1;
  3219. cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
  3220. }
  3221. }
  3222. /*----------------------------------------------------------------------------*/
  3223. /*!
  3224. * \brief This routine is used to insert command into prCmdQueue
  3225. *
  3226. * \param prGlueInfo Pointer of GLUE Data Structure
  3227. * prQueueEntry Pointer of queue entry to be inserted
  3228. *
  3229. * \retval none
  3230. */
  3231. /*----------------------------------------------------------------------------*/
  3232. VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry)
  3233. {
  3234. P_QUE_T prCmdQue;
  3235. P_CMD_INFO_T prCmdInfo;
  3236. GLUE_SPIN_LOCK_DECLARATION();
  3237. ASSERT(prGlueInfo);
  3238. ASSERT(prQueueEntry);
  3239. prCmdQue = &prGlueInfo->rCmdQueue;
  3240. prCmdInfo = (P_CMD_INFO_T) prQueueEntry;
  3241. DBGLOG(TX, LOUD, "EN-Q CMD TYPE[%u] ID[0x%02X] SEQ[%u] to CMD Q\n",
  3242. prCmdInfo->eCmdType, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum);
  3243. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3244. QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
  3245. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
  3246. }
  3247. /*----------------------------------------------------------------------------*/
  3248. /*!
  3249. * @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with
  3250. * proper information
  3251. *
  3252. * @param pvGlueInfo Pointer of GLUE Data Structure
  3253. * @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet
  3254. *
  3255. * @return none
  3256. */
  3257. /*----------------------------------------------------------------------------*/
  3258. VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo)
  3259. {
  3260. /* to do */
  3261. }
  3262. /*----------------------------------------------------------------------------*/
  3263. /*!
  3264. * \brief This routine is used to get firmware load address from registry
  3265. *
  3266. * \param prGlueInfo Pointer of GLUE Data Structure
  3267. *
  3268. * \retval
  3269. */
  3270. /*----------------------------------------------------------------------------*/
  3271. UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo)
  3272. {
  3273. ASSERT(prGlueInfo);
  3274. return prGlueInfo->rRegInfo.u4LoadAddress;
  3275. }
  3276. /*----------------------------------------------------------------------------*/
  3277. /*!
  3278. * \brief This routine is used to get firmware start address from registry
  3279. *
  3280. * \param prGlueInfo Pointer of GLUE Data Structure
  3281. *
  3282. * \retval
  3283. */
  3284. /*----------------------------------------------------------------------------*/
  3285. UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo)
  3286. {
  3287. ASSERT(prGlueInfo);
  3288. return prGlueInfo->rRegInfo.u4StartAddress;
  3289. }
  3290. /*----------------------------------------------------------------------------*/
  3291. /*!
  3292. * * @brief Notify OS with SendComplete event of the specific packet. Linux should
  3293. * * free packets here.
  3294. * *
  3295. * * @param pvGlueInfo Pointer of GLUE Data Structure
  3296. * * @param pvPacket Pointer of Packet Handle
  3297. * * @param status Status Code for OS upper layer
  3298. * *
  3299. * * @return none
  3300. * */
  3301. /*----------------------------------------------------------------------------*/
  3302. /* / Todo */
  3303. VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus)
  3304. {
  3305. ASSERT(pvPacket);
  3306. /* dev_kfree_skb((struct sk_buff *) pvPacket); */
  3307. kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket);
  3308. GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  3309. }
  3310. UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo)
  3311. {
  3312. ASSERT(prGlueInfo);
  3313. return (UINT_32) (GLUE_GET_REF_CNT(prGlueInfo->i4TxPendingFrameNum));
  3314. }
  3315. /*----------------------------------------------------------------------------*/
  3316. /*!
  3317. * \brief This routine is used to retrieve the number of pending commands
  3318. * (including MMPDU, 802.1X and command packets)
  3319. *
  3320. * \param prGlueInfo Pointer of GLUE Data Structure
  3321. *
  3322. * \retval
  3323. */
  3324. /*----------------------------------------------------------------------------*/
  3325. UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo)
  3326. {
  3327. P_QUE_T prCmdQue;
  3328. ASSERT(prGlueInfo);
  3329. prCmdQue = &prGlueInfo->rCmdQueue;
  3330. return prCmdQue->u4NumElem;
  3331. }
  3332. /*----------------------------------------------------------------------------*/
  3333. /*!
  3334. * \brief Timer Initialization Procedure
  3335. *
  3336. * \param[in] prGlueInfo Pointer to GLUE Data Structure
  3337. * \param[in] prTimerHandler Pointer to timer handling function, whose only
  3338. * argument is "prAdapter"
  3339. *
  3340. * \retval none
  3341. *
  3342. */
  3343. /*----------------------------------------------------------------------------*/
  3344. /* static struct timer_list tickfn; */
  3345. VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler)
  3346. {
  3347. ASSERT(prGlueInfo);
  3348. init_timer(&(prGlueInfo->tickfn));
  3349. prGlueInfo->tickfn.function = prTimerHandler;
  3350. prGlueInfo->tickfn.data = (unsigned long)prGlueInfo;
  3351. }
  3352. /* Todo */
  3353. /*----------------------------------------------------------------------------*/
  3354. /*!
  3355. * \brief This routine is called to set the time to do the time out check.
  3356. *
  3357. * \param[in] prGlueInfo Pointer to GLUE Data Structure
  3358. * \param[in] rInterval Time out interval from current time.
  3359. *
  3360. * \retval TRUE Success.
  3361. */
  3362. /*----------------------------------------------------------------------------*/
  3363. BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval)
  3364. {
  3365. ASSERT(prGlueInfo);
  3366. del_timer_sync(&(prGlueInfo->tickfn));
  3367. prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC;
  3368. add_timer(&(prGlueInfo->tickfn));
  3369. return TRUE; /* success */
  3370. }
  3371. /*----------------------------------------------------------------------------*/
  3372. /*!
  3373. * \brief This routine is called to cancel
  3374. *
  3375. * \param[in] prGlueInfo Pointer to GLUE Data Structure
  3376. *
  3377. * \retval TRUE : Timer has been canceled
  3378. * FALAE : Timer doens't exist
  3379. */
  3380. /*----------------------------------------------------------------------------*/
  3381. BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo)
  3382. {
  3383. ASSERT(prGlueInfo);
  3384. clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag);
  3385. if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0)
  3386. return TRUE;
  3387. else
  3388. return FALSE;
  3389. }
  3390. /*----------------------------------------------------------------------------*/
  3391. /*!
  3392. * \brief This routine is a callback function for scanning done
  3393. *
  3394. * \param[in] prGlueInfo Pointer to GLUE Data Structure
  3395. *
  3396. * \retval none
  3397. *
  3398. */
  3399. /*----------------------------------------------------------------------------*/
  3400. VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status)
  3401. {
  3402. ASSERT(prGlueInfo);
  3403. scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL);
  3404. /* check for system configuration for generating error message on scan list */
  3405. wlanCheckSystemConfiguration(prGlueInfo->prAdapter);
  3406. kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
  3407. }
  3408. /*----------------------------------------------------------------------------*/
  3409. /*!
  3410. * \brief This routine is used to generate a random number
  3411. *
  3412. * \param none
  3413. *
  3414. * \retval UINT_32
  3415. */
  3416. /*----------------------------------------------------------------------------*/
  3417. UINT_32 kalRandomNumber(VOID)
  3418. {
  3419. UINT_32 number = 0;
  3420. get_random_bytes(&number, 4);
  3421. return number;
  3422. }
  3423. /*----------------------------------------------------------------------------*/
  3424. /*!
  3425. * \brief command timeout call-back function
  3426. *
  3427. * \param[in] prGlueInfo Pointer to the GLUE data structure.
  3428. *
  3429. * \retval (none)
  3430. */
  3431. /*----------------------------------------------------------------------------*/
  3432. VOID kalTimeoutHandler(unsigned long arg)
  3433. {
  3434. P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg;
  3435. ASSERT(prGlueInfo);
  3436. /* Notify tx thread for timeout event */
  3437. set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag);
  3438. wake_up_interruptible(&prGlueInfo->waitq);
  3439. }
  3440. VOID kalSetEvent(P_GLUE_INFO_T pr)
  3441. {
  3442. set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag);
  3443. wake_up_interruptible(&pr->waitq);
  3444. }
  3445. #if CFG_SUPPORT_MULTITHREAD
  3446. VOID kalSetTxEvent2Hif(P_GLUE_INFO_T pr)
  3447. {
  3448. if (!pr->hif_thread)
  3449. return;
  3450. KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, &pr->rTimeoutWakeLock, MSEC_TO_JIFFIES(WAKE_LOCK_THREAD_WAKEUP_TIMEOUT));
  3451. set_bit(GLUE_FLAG_HIF_TX_BIT, &pr->ulFlag);
  3452. wake_up_interruptible(&pr->waitq_hif);
  3453. }
  3454. VOID kalSetFwOwnEvent2Hif(P_GLUE_INFO_T pr)
  3455. {
  3456. if (!pr->hif_thread)
  3457. return;
  3458. KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, &pr->rTimeoutWakeLock, MSEC_TO_JIFFIES(WAKE_LOCK_THREAD_WAKEUP_TIMEOUT));
  3459. set_bit(GLUE_FLAG_HIF_FW_OWN_BIT, &pr->ulFlag);
  3460. wake_up_interruptible(&pr->waitq_hif);
  3461. }
  3462. VOID kalSetTxEvent2Rx(P_GLUE_INFO_T pr)
  3463. {
  3464. if (!pr->rx_thread)
  3465. return;
  3466. KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, &pr->rTimeoutWakeLock, MSEC_TO_JIFFIES(WAKE_LOCK_THREAD_WAKEUP_TIMEOUT));
  3467. set_bit(GLUE_FLAG_RX_TO_OS_BIT, &pr->ulFlag);
  3468. wake_up_interruptible(&pr->waitq_rx);
  3469. }
  3470. VOID kalSetTxCmdEvent2Hif(P_GLUE_INFO_T pr)
  3471. {
  3472. if (!pr->hif_thread)
  3473. return;
  3474. KAL_WAKE_LOCK_TIMEOUT(pr->prAdapter, &pr->rTimeoutWakeLock, MSEC_TO_JIFFIES(WAKE_LOCK_THREAD_WAKEUP_TIMEOUT));
  3475. set_bit(GLUE_FLAG_HIF_TX_CMD_BIT, &pr->ulFlag);
  3476. wake_up_interruptible(&pr->waitq_hif);
  3477. }
  3478. #endif
  3479. /*----------------------------------------------------------------------------*/
  3480. /*!
  3481. * \brief to check if configuration file (NVRAM/Registry) exists
  3482. *
  3483. * \param[in]
  3484. * prGlueInfo
  3485. *
  3486. * \return
  3487. * TRUE
  3488. * FALSE
  3489. */
  3490. /*----------------------------------------------------------------------------*/
  3491. BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo)
  3492. {
  3493. #if !defined(CONFIG_X86)
  3494. ASSERT(prGlueInfo);
  3495. return prGlueInfo->fgNvramAvailable;
  3496. #else
  3497. /* there is no configuration data for x86-linux */
  3498. return FALSE;
  3499. #endif
  3500. }
  3501. /*----------------------------------------------------------------------------*/
  3502. /*!
  3503. * \brief to retrieve Registry information
  3504. *
  3505. * \param[in]
  3506. * prGlueInfo
  3507. *
  3508. * \return
  3509. * Pointer of REG_INFO_T
  3510. */
  3511. /*----------------------------------------------------------------------------*/
  3512. P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo)
  3513. {
  3514. ASSERT(prGlueInfo);
  3515. return &(prGlueInfo->rRegInfo);
  3516. }
  3517. /*----------------------------------------------------------------------------*/
  3518. /*!
  3519. * \brief to retrieve version information of corresponding configuration file
  3520. *
  3521. * \param[in]
  3522. * prGlueInfo
  3523. *
  3524. * \param[out]
  3525. * pu2Part1CfgOwnVersion
  3526. * pu2Part1CfgPeerVersion
  3527. * pu2Part2CfgOwnVersion
  3528. * pu2Part2CfgPeerVersion
  3529. *
  3530. * \return
  3531. * NONE
  3532. */
  3533. /*----------------------------------------------------------------------------*/
  3534. VOID
  3535. kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo,
  3536. OUT PUINT_16 pu2Part1CfgOwnVersion,
  3537. OUT PUINT_16 pu2Part1CfgPeerVersion,
  3538. OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion)
  3539. {
  3540. ASSERT(prGlueInfo);
  3541. ASSERT(pu2Part1CfgOwnVersion);
  3542. ASSERT(pu2Part1CfgPeerVersion);
  3543. ASSERT(pu2Part2CfgOwnVersion);
  3544. ASSERT(pu2Part2CfgPeerVersion);
  3545. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion);
  3546. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion);
  3547. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion);
  3548. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion);
  3549. }
  3550. /*----------------------------------------------------------------------------*/
  3551. /*!
  3552. * \brief to check if the WPS is active or not
  3553. *
  3554. * \param[in]
  3555. * prGlueInfo
  3556. *
  3557. * \return
  3558. * TRUE
  3559. * FALSE
  3560. */
  3561. /*----------------------------------------------------------------------------*/
  3562. BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo)
  3563. {
  3564. ASSERT(prGlueInfo);
  3565. return prGlueInfo->fgWpsActive;
  3566. }
  3567. /*----------------------------------------------------------------------------*/
  3568. /*!
  3569. * \brief update RSSI and LinkQuality to GLUE layer
  3570. *
  3571. * \param[in]
  3572. * prGlueInfo
  3573. * eNetTypeIdx
  3574. * cRssi
  3575. * cLinkQuality
  3576. *
  3577. * \return
  3578. * None
  3579. */
  3580. /*----------------------------------------------------------------------------*/
  3581. VOID
  3582. kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo,
  3583. IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality)
  3584. {
  3585. struct iw_statistics *pStats = (struct iw_statistics *)NULL;
  3586. ASSERT(prGlueInfo);
  3587. switch (eNetTypeIdx) {
  3588. case KAL_NETWORK_TYPE_AIS_INDEX:
  3589. pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats));
  3590. break;
  3591. #if CFG_ENABLE_WIFI_DIRECT
  3592. #if CFG_SUPPORT_P2P_RSSI_QUERY
  3593. case KAL_NETWORK_TYPE_P2P_INDEX:
  3594. pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats));
  3595. break;
  3596. #endif
  3597. #endif
  3598. default:
  3599. break;
  3600. }
  3601. if (pStats) {
  3602. pStats->qual.qual = cLinkQuality;
  3603. pStats->qual.noise = 0;
  3604. pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED;
  3605. pStats->qual.level = 0x100 + cRssi;
  3606. pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
  3607. }
  3608. }
  3609. /*----------------------------------------------------------------------------*/
  3610. /*!
  3611. * \brief Pre-allocate I/O buffer
  3612. *
  3613. * \param[in]
  3614. * none
  3615. *
  3616. * \return
  3617. * TRUE
  3618. * FALSE
  3619. */
  3620. /*----------------------------------------------------------------------------*/
  3621. BOOLEAN kalInitIOBuffer(VOID)
  3622. {
  3623. UINT_32 u4Size;
  3624. if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE)
  3625. u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
  3626. else
  3627. u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
  3628. pvIoBuffer = kmalloc(u4Size, GFP_KERNEL);
  3629. if (pvIoBuffer) {
  3630. pvIoBufferSize = u4Size;
  3631. pvIoBufferUsage = 0;
  3632. return TRUE;
  3633. }
  3634. return FALSE;
  3635. }
  3636. /*----------------------------------------------------------------------------*/
  3637. /*!
  3638. * \brief Free pre-allocated I/O buffer
  3639. *
  3640. * \param[in]
  3641. * none
  3642. *
  3643. * \return
  3644. * none
  3645. */
  3646. /*----------------------------------------------------------------------------*/
  3647. VOID kalUninitIOBuffer(VOID)
  3648. {
  3649. kfree(pvIoBuffer);
  3650. pvIoBuffer = (PVOID) NULL;
  3651. pvIoBufferSize = 0;
  3652. pvIoBufferUsage = 0;
  3653. }
  3654. /*----------------------------------------------------------------------------*/
  3655. /*!
  3656. * \brief Dispatch pre-allocated I/O buffer
  3657. *
  3658. * \param[in]
  3659. * u4AllocSize
  3660. *
  3661. * \return
  3662. * PVOID for pointer of pre-allocated I/O buffer
  3663. */
  3664. /*----------------------------------------------------------------------------*/
  3665. PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize)
  3666. {
  3667. PVOID ret = (PVOID) NULL;
  3668. if (pvIoBuffer) {
  3669. if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) {
  3670. ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]);
  3671. pvIoBufferUsage += u4AllocSize;
  3672. }
  3673. } else {
  3674. /* fault tolerance */
  3675. ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE);
  3676. }
  3677. return ret;
  3678. }
  3679. /*----------------------------------------------------------------------------*/
  3680. /*!
  3681. * \brief Release all dispatched I/O buffer
  3682. *
  3683. * \param[in]
  3684. * none
  3685. *
  3686. * \return
  3687. * none
  3688. */
  3689. /*----------------------------------------------------------------------------*/
  3690. VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size)
  3691. {
  3692. if (pvIoBuffer) {
  3693. pvIoBufferUsage -= u4Size;
  3694. } else {
  3695. /* fault tolerance */
  3696. kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size);
  3697. }
  3698. }
  3699. /*----------------------------------------------------------------------------*/
  3700. /*!
  3701. * \brief
  3702. *
  3703. * \param[in] prAdapter Pointer of ADAPTER_T
  3704. *
  3705. * \return none
  3706. */
  3707. /*----------------------------------------------------------------------------*/
  3708. VOID
  3709. kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo,
  3710. IN ENUM_BAND_T eSpecificBand,
  3711. IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList)
  3712. {
  3713. rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum,
  3714. pucNumOfChannel, paucChannelList);
  3715. }
  3716. /*----------------------------------------------------------------------------*/
  3717. /*!
  3718. * \brief
  3719. *
  3720. * \param[in] prAdapter Pointer of ADAPTER_T
  3721. *
  3722. * \return none
  3723. */
  3724. /*----------------------------------------------------------------------------*/
  3725. BOOL kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo)
  3726. {
  3727. #if 0 /* Marked for MT6630 (New ucBssIndex) */
  3728. #if CFG_ENABLE_WIFI_DIRECT
  3729. if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) &&
  3730. p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo))
  3731. return TRUE;
  3732. #endif
  3733. #endif
  3734. return FALSE;
  3735. }
  3736. #if CFG_SUPPORT_802_11W
  3737. /*----------------------------------------------------------------------------*/
  3738. /*!
  3739. * \brief to check if the MFP is active or not
  3740. *
  3741. * \param[in]
  3742. * prGlueInfo
  3743. *
  3744. * \return
  3745. * TRUE
  3746. * FALSE
  3747. */
  3748. /*----------------------------------------------------------------------------*/
  3749. UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo)
  3750. {
  3751. ASSERT(prGlueInfo);
  3752. return prGlueInfo->rWpaInfo.u4Mfp;
  3753. }
  3754. #endif
  3755. struct file *kalFileOpen(const char *path, int flags, int rights)
  3756. {
  3757. struct file *filp = NULL;
  3758. mm_segment_t oldfs;
  3759. int err = 0;
  3760. oldfs = get_fs();
  3761. set_fs(get_ds());
  3762. filp = filp_open(path, flags, rights);
  3763. set_fs(oldfs);
  3764. if (IS_ERR(filp)) {
  3765. err = PTR_ERR(filp);
  3766. return NULL;
  3767. }
  3768. return filp;
  3769. }
  3770. VOID kalFileClose(struct file *file)
  3771. {
  3772. filp_close(file, NULL);
  3773. }
  3774. UINT_32 kalFileRead(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
  3775. {
  3776. mm_segment_t oldfs;
  3777. int ret;
  3778. oldfs = get_fs();
  3779. set_fs(get_ds());
  3780. ret = vfs_read(file, data, size, &offset);
  3781. set_fs(oldfs);
  3782. return ret;
  3783. }
  3784. UINT_32 kalFileWrite(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
  3785. {
  3786. mm_segment_t oldfs;
  3787. int ret;
  3788. oldfs = get_fs();
  3789. set_fs(get_ds());
  3790. ret = vfs_write(file, data, size, &offset);
  3791. set_fs(oldfs);
  3792. return ret;
  3793. }
  3794. UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size)
  3795. {
  3796. struct file *file = NULL;
  3797. UINT_32 ret;
  3798. UINT_32 u4Flags = 0;
  3799. if (fgDoAppend)
  3800. u4Flags = O_APPEND;
  3801. file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU);
  3802. ret = kalFileWrite(file, 0, pucData, u4Size);
  3803. kalFileClose(file);
  3804. return ret;
  3805. }
  3806. INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize)
  3807. {
  3808. struct file *file = NULL;
  3809. INT_32 ret = -1;
  3810. UINT_32 u4ReadSize = 0;
  3811. DBGLOG(INIT, TRACE, "kalReadToFile() path %s\n", pucPath);
  3812. file = kalFileOpen(pucPath, O_RDONLY, 0);
  3813. if ((file != NULL) && !IS_ERR(file)) {
  3814. u4ReadSize = kalFileRead(file, 0, pucData, u4Size);
  3815. kalFileClose(file);
  3816. if (pu4ReadSize)
  3817. *pu4ReadSize = u4ReadSize;
  3818. ret = 0;
  3819. }
  3820. return ret;
  3821. }
  3822. UINT_32 kalCheckPath(const PUINT_8 pucPath)
  3823. {
  3824. struct file *file = NULL;
  3825. UINT_32 u4Flags = 0;
  3826. file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU);
  3827. if (!file)
  3828. return -1;
  3829. kalFileClose(file);
  3830. return 1;
  3831. }
  3832. /*----------------------------------------------------------------------------*/
  3833. /*!
  3834. * \brief To indicate BSS-INFO to NL80211 as scanning result
  3835. *
  3836. * \param[in]
  3837. * prGlueInfo
  3838. * pucBeaconProbeResp
  3839. * u4FrameLen
  3840. *
  3841. *
  3842. *
  3843. * \return
  3844. * none
  3845. */
  3846. /*----------------------------------------------------------------------------*/
  3847. VOID
  3848. kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo,
  3849. IN PUINT_8 pucBeaconProbeResp,
  3850. IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength)
  3851. {
  3852. struct wiphy *wiphy;
  3853. struct ieee80211_channel *prChannel = NULL;
  3854. ASSERT(prGlueInfo);
  3855. wiphy = priv_to_wiphy(prGlueInfo);
  3856. /* search through channel entries */
  3857. if (ucChannelNum <= 14) {
  3858. prChannel =
  3859. ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
  3860. } else {
  3861. prChannel =
  3862. ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
  3863. }
  3864. if (prChannel != NULL && prGlueInfo->fgIsRegistered == TRUE) {
  3865. struct cfg80211_bss *bss;
  3866. #if CFG_SUPPORT_TSF_USING_BOOTTIME
  3867. struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp;
  3868. prMgmtFrame->u.beacon.timestamp = kalGetBootTime();
  3869. #endif
  3870. /* indicate to NL80211 subsystem */
  3871. bss = cfg80211_inform_bss_frame(wiphy,
  3872. prChannel,
  3873. (struct ieee80211_mgmt *)pucBeaconProbeResp,
  3874. u4FrameLen, i4SignalStrength * 100, GFP_KERNEL);
  3875. if (!bss) {
  3876. /* ToDo:: DBGLOG */
  3877. DBGLOG(REQ, WARN, "cfg80211_inform_bss_frame() returned with NULL\n");
  3878. } else
  3879. cfg80211_put_bss(wiphy, bss);
  3880. }
  3881. }
  3882. /*----------------------------------------------------------------------------*/
  3883. /*!
  3884. * \brief To indicate channel ready
  3885. *
  3886. * \param[in]
  3887. * prGlueInfo
  3888. *
  3889. * \return
  3890. * none
  3891. */
  3892. /*----------------------------------------------------------------------------*/
  3893. VOID
  3894. kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo,
  3895. IN UINT_64 u8Cookie,
  3896. IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs)
  3897. {
  3898. struct ieee80211_channel *prChannel = NULL;
  3899. enum nl80211_channel_type rChannelType;
  3900. /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */
  3901. if (prGlueInfo->fgIsRegistered == TRUE) {
  3902. if (ucChannelNum <= 14) {
  3903. prChannel =
  3904. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  3905. ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
  3906. } else {
  3907. prChannel =
  3908. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  3909. ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
  3910. }
  3911. switch (eSco) {
  3912. case CHNL_EXT_SCN:
  3913. rChannelType = NL80211_CHAN_NO_HT;
  3914. break;
  3915. case CHNL_EXT_SCA:
  3916. rChannelType = NL80211_CHAN_HT40MINUS;
  3917. break;
  3918. case CHNL_EXT_SCB:
  3919. rChannelType = NL80211_CHAN_HT40PLUS;
  3920. break;
  3921. case CHNL_EXT_RES:
  3922. default:
  3923. rChannelType = NL80211_CHAN_HT20;
  3924. break;
  3925. }
  3926. cfg80211_ready_on_channel(
  3927. prGlueInfo->prDevHandler->ieee80211_ptr,
  3928. u8Cookie, prChannel,
  3929. u4DurationMs, GFP_KERNEL);
  3930. }
  3931. }
  3932. /*----------------------------------------------------------------------------*/
  3933. /*!
  3934. * \brief To indicate channel expiration
  3935. *
  3936. * \param[in]
  3937. * prGlueInfo
  3938. *
  3939. * \return
  3940. * none
  3941. */
  3942. /*----------------------------------------------------------------------------*/
  3943. VOID
  3944. kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo,
  3945. IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum)
  3946. {
  3947. struct ieee80211_channel *prChannel = NULL;
  3948. enum nl80211_channel_type rChannelType;
  3949. ucChannelNum =
  3950. wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, prGlueInfo->prAdapter->prAisBssInfo->ucBssIndex);
  3951. if (prGlueInfo->fgIsRegistered == TRUE) {
  3952. if (ucChannelNum <= 14) {
  3953. prChannel =
  3954. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  3955. ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
  3956. } else {
  3957. prChannel =
  3958. ieee80211_get_channel(priv_to_wiphy(prGlueInfo),
  3959. ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
  3960. }
  3961. switch (eSco) {
  3962. case CHNL_EXT_SCN:
  3963. rChannelType = NL80211_CHAN_NO_HT;
  3964. break;
  3965. case CHNL_EXT_SCA:
  3966. rChannelType = NL80211_CHAN_HT40MINUS;
  3967. break;
  3968. case CHNL_EXT_SCB:
  3969. rChannelType = NL80211_CHAN_HT40PLUS;
  3970. break;
  3971. case CHNL_EXT_RES:
  3972. default:
  3973. rChannelType = NL80211_CHAN_HT20;
  3974. break;
  3975. }
  3976. cfg80211_remain_on_channel_expired(
  3977. prGlueInfo->prDevHandler->ieee80211_ptr,
  3978. u8Cookie, prChannel,
  3979. GFP_KERNEL);
  3980. }
  3981. }
  3982. /*----------------------------------------------------------------------------*/
  3983. /*!
  3984. * \brief To indicate Mgmt tx status
  3985. *
  3986. * \param[in]
  3987. * prGlueInfo
  3988. *
  3989. * \return
  3990. * none
  3991. */
  3992. /*----------------------------------------------------------------------------*/
  3993. VOID
  3994. kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo,
  3995. IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen)
  3996. {
  3997. do {
  3998. if ((prGlueInfo == NULL)
  3999. || (pucFrameBuf == NULL)
  4000. || (u4FrameLen == 0)) {
  4001. DBGLOG(AIS, TRACE,
  4002. "Unexpected pointer PARAM. 0x%lx, 0x%lx, %ld.", prGlueInfo, pucFrameBuf, u4FrameLen);
  4003. ASSERT(FALSE);
  4004. break;
  4005. }
  4006. cfg80211_mgmt_tx_status(
  4007. prGlueInfo->prDevHandler->ieee80211_ptr,
  4008. u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL);
  4009. } while (FALSE);
  4010. } /* kalIndicateMgmtTxStatus */
  4011. VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb)
  4012. {
  4013. INT_32 i4Freq = 0;
  4014. UINT_8 ucChnlNum = 0;
  4015. do {
  4016. if ((prGlueInfo == NULL) || (prSwRfb == NULL)) {
  4017. ASSERT(FALSE);
  4018. break;
  4019. }
  4020. ucChnlNum = (UINT_8) HAL_RX_STATUS_GET_CHNL_NUM(prSwRfb->prRxStatus);
  4021. i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000;
  4022. cfg80211_rx_mgmt(
  4023. prGlueInfo->prDevHandler->ieee80211_ptr,
  4024. i4Freq, /* in MHz */
  4025. RCPI_TO_dBm((UINT_8)
  4026. HAL_RX_STATUS_GET_RCPI(prSwRfb->prRxStatusGroup3)),
  4027. prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC);
  4028. } while (FALSE);
  4029. } /* kalIndicateRxMgmtFrame */
  4030. #if CFG_SUPPORT_SDIO_READ_WRITE_PATTERN
  4031. /*----------------------------------------------------------------------------*/
  4032. /*!
  4033. * \brief To configure SDIO test pattern mode
  4034. *
  4035. * \param[in]
  4036. * prGlueInfo
  4037. * fgEn
  4038. * fgRead
  4039. *
  4040. * \return
  4041. * TRUE
  4042. * FALSE
  4043. */
  4044. /*----------------------------------------------------------------------------*/
  4045. BOOLEAN kalSetSdioTestPattern(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgEn, IN BOOLEAN fgRead)
  4046. {
  4047. const UINT_8 aucPattern[] = {
  4048. 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
  4049. 0xaa, 0x55, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80,
  4050. 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f,
  4051. 0x40, 0x40, 0x40, 0xbf, 0x40, 0x40, 0x40, 0xbf,
  4052. 0xbf, 0xbf, 0x40, 0xbf, 0xbf, 0xbf, 0x20, 0x20,
  4053. 0x20, 0xdf, 0x20, 0x20, 0x20, 0xdf, 0xdf, 0xdf,
  4054. 0x20, 0xdf, 0xdf, 0xdf, 0x10, 0x10, 0x10, 0xef,
  4055. 0x10, 0x10, 0x10, 0xef, 0xef, 0xef, 0x10, 0xef,
  4056. 0xef, 0xef, 0x08, 0x08, 0x08, 0xf7, 0x08, 0x08,
  4057. 0x08, 0xf7, 0xf7, 0xf7, 0x08, 0xf7, 0xf7, 0xf7,
  4058. 0x04, 0x04, 0x04, 0xfb, 0x04, 0x04, 0x04, 0xfb,
  4059. 0xfb, 0xfb, 0x04, 0xfb, 0xfb, 0xfb, 0x02, 0x02,
  4060. 0x02, 0xfd, 0x02, 0x02, 0x02, 0xfd, 0xfd, 0xfd,
  4061. 0x02, 0xfd, 0xfd, 0xfd, 0x01, 0x01, 0x01, 0xfe,
  4062. 0x01, 0x01, 0x01, 0xfe, 0xfe, 0xfe, 0x01, 0xfe,
  4063. 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  4064. 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
  4065. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
  4066. 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
  4067. 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
  4068. 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff,
  4069. 0x00, 0x00, 0x00, 0xff
  4070. };
  4071. UINT_32 i;
  4072. ASSERT(prGlueInfo);
  4073. /* access to MCR_WTMCR to engage PRBS mode */
  4074. prGlueInfo->fgEnSdioTestPattern = fgEn;
  4075. prGlueInfo->fgSdioReadWriteMode = fgRead;
  4076. if (fgRead == FALSE) {
  4077. /* fill buffer for data to be written */
  4078. for (i = 0; i < sizeof(aucPattern); i++)
  4079. prGlueInfo->aucSdioTestBuffer[i] = aucPattern[i];
  4080. }
  4081. return TRUE;
  4082. }
  4083. #endif
  4084. #if (CFG_MET_PACKET_TRACE_SUPPORT == 1)
  4085. #define PROC_MET_PROF_CTRL "met_ctrl"
  4086. #define PROC_MET_PROF_PORT "met_port"
  4087. struct proc_dir_entry *pMetProcDir;
  4088. void *pMetGlobalData = NULL;
  4089. #endif
  4090. /*----------------------------------------------------------------------------*/
  4091. /*!
  4092. * \brief To indicate scheduled scan results are avilable
  4093. *
  4094. * \param[in]
  4095. * prGlueInfo
  4096. *
  4097. * \return
  4098. * None
  4099. */
  4100. /*----------------------------------------------------------------------------*/
  4101. VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo)
  4102. {
  4103. ASSERT(prGlueInfo);
  4104. cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo));
  4105. }
  4106. /*----------------------------------------------------------------------------*/
  4107. /*!
  4108. * \brief To indicate scheduled scan has been stopped
  4109. *
  4110. * \param[in]
  4111. * prGlueInfo
  4112. *
  4113. * \return
  4114. * None
  4115. */
  4116. /*----------------------------------------------------------------------------*/
  4117. VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo)
  4118. {
  4119. /* DBGLOG(SCN, INFO, ("-->kalSchedScanStopped\n" )); */
  4120. GLUE_SPIN_LOCK_DECLARATION();
  4121. ASSERT(prGlueInfo);
  4122. #if 1
  4123. /* 1. reset first for newly incoming request */
  4124. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  4125. if (prGlueInfo->prSchedScanRequest != NULL)
  4126. prGlueInfo->prSchedScanRequest = NULL;
  4127. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  4128. #endif
  4129. DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n");
  4130. /* 2. indication to cfg80211 */
  4131. /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread
  4132. due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */
  4133. DBGLOG(SCN, INFO, "start work queue to send event\n");
  4134. schedule_delayed_work(&sched_workq, 0);
  4135. DBGLOG(SCN, INFO, "Tx_thread return from kalSchedScanStoppped\n");
  4136. }
  4137. BOOLEAN
  4138. kalGetIPv4Address(IN struct net_device *prDev,
  4139. IN UINT_32 u4MaxNumOfAddr, OUT PUINT_8 pucIpv4Addrs, OUT PUINT_32 pu4NumOfIpv4Addr)
  4140. {
  4141. UINT_32 u4NumIPv4 = 0;
  4142. UINT_32 u4AddrLen = IPV4_ADDR_LEN;
  4143. struct in_ifaddr *prIfa;
  4144. /* 4 <1> Sanity check of netDevice */
  4145. if (!prDev || !(prDev->ip_ptr) || !((struct in_device *)(prDev->ip_ptr))->ifa_list) {
  4146. DBGLOG(INIT, INFO, "IPv4 address is not available for dev(0x%p)\n", prDev);
  4147. *pu4NumOfIpv4Addr = 0;
  4148. return FALSE;
  4149. }
  4150. prIfa = ((struct in_device *)(prDev->ip_ptr))->ifa_list;
  4151. /* 4 <2> copy the IPv4 address */
  4152. while ((u4NumIPv4 < u4MaxNumOfAddr) && prIfa) {
  4153. kalMemCopy(&pucIpv4Addrs[u4NumIPv4 * u4AddrLen], &prIfa->ifa_local, u4AddrLen);
  4154. prIfa = prIfa->ifa_next;
  4155. DBGLOG(INIT, INFO,
  4156. "IPv4 addr [%u][" IPV4STR "]\n", u4NumIPv4, IPV4TOSTR(&pucIpv4Addrs[u4NumIPv4 * u4AddrLen]));
  4157. u4NumIPv4++;
  4158. }
  4159. *pu4NumOfIpv4Addr = u4NumIPv4;
  4160. return TRUE;
  4161. }
  4162. BOOLEAN
  4163. kalGetIPv6Address(IN struct net_device *prDev,
  4164. IN UINT_32 u4MaxNumOfAddr, OUT PUINT_8 pucIpv6Addrs, OUT PUINT_32 pu4NumOfIpv6Addr)
  4165. {
  4166. UINT_32 u4NumIPv6 = 0;
  4167. UINT_32 u4AddrLen = IPV6_ADDR_LEN;
  4168. struct inet6_ifaddr *prIfa;
  4169. struct list_head *prAddrList;
  4170. /* 4 <1> Sanity check of netDevice */
  4171. if (!prDev || !(prDev->ip6_ptr)) {
  4172. DBGLOG(INIT, INFO, "IPv6 address is not available for dev(0x%p)\n", prDev);
  4173. *pu4NumOfIpv6Addr = 0;
  4174. return FALSE;
  4175. }
  4176. prAddrList = &((struct inet6_dev *)(prDev->ip6_ptr))->addr_list;
  4177. /* 4 <2> copy the IPv6 address */
  4178. list_for_each_entry(prIfa, prAddrList, if_list) {
  4179. kalMemCopy(&pucIpv6Addrs[u4NumIPv6 * u4AddrLen], &prIfa->addr, u4AddrLen);
  4180. DBGLOG(INIT, INFO,
  4181. "IPv6 addr [%u][" IPV6STR "]\n", u4NumIPv6, IPV6TOSTR(&pucIpv6Addrs[u4NumIPv6 * u4AddrLen]));
  4182. if ((u4NumIPv6 + 1) >= u4MaxNumOfAddr)
  4183. break;
  4184. u4NumIPv6++;
  4185. }
  4186. *pu4NumOfIpv6Addr = u4NumIPv6;
  4187. return TRUE;
  4188. }
  4189. VOID
  4190. kalSetNetAddress(IN P_GLUE_INFO_T prGlueInfo,
  4191. IN UINT_8 ucBssIdx,
  4192. IN PUINT_8 pucIPv4Addr, IN UINT_32 u4NumIPv4Addr, IN PUINT_8 pucIPv6Addr, IN UINT_32 u4NumIPv6Addr)
  4193. {
  4194. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  4195. UINT_32 u4SetInfoLen = 0;
  4196. UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
  4197. P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList;
  4198. P_PARAM_NETWORK_ADDRESS prParamNetAddr;
  4199. UINT_32 i, u4AddrLen;
  4200. /* 4 <1> Calculate buffer size */
  4201. /* IPv4 */
  4202. u4Len += (((sizeof(PARAM_NETWORK_ADDRESS) - 1) + IPV4_ADDR_LEN) * u4NumIPv4Addr);
  4203. /* IPv6 */
  4204. u4Len += (((sizeof(PARAM_NETWORK_ADDRESS) - 1) + IPV6_ADDR_LEN) * u4NumIPv6Addr);
  4205. /* 4 <2> Allocate buffer */
  4206. prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) kalMemAlloc(u4Len, VIR_MEM_TYPE);
  4207. if (!prParamNetAddrList) {
  4208. DBGLOG(INIT, WARN, "Fail to alloc buffer for setting BSS[%u] network address!\n", ucBssIdx);
  4209. return;
  4210. }
  4211. /* 4 <3> Fill up network address */
  4212. prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  4213. prParamNetAddrList->u4AddressCount = 0;
  4214. prParamNetAddrList->ucBssIdx = ucBssIdx;
  4215. /* 4 <3.1> Fill up IPv4 address */
  4216. u4AddrLen = IPV4_ADDR_LEN;
  4217. prParamNetAddr = prParamNetAddrList->arAddress;
  4218. for (i = 0; i < u4NumIPv4Addr; i++) {
  4219. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  4220. prParamNetAddr->u2AddressLength = u4AddrLen;
  4221. kalMemCopy(prParamNetAddr->aucAddress, &pucIPv4Addr[i * u4AddrLen], u4AddrLen);
  4222. prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr +
  4223. (ULONG) (u4AddrLen +
  4224. OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
  4225. }
  4226. prParamNetAddrList->u4AddressCount += u4NumIPv4Addr;
  4227. /* 4 <3.2> Fill up IPv6 address */
  4228. u4AddrLen = IPV6_ADDR_LEN;
  4229. for (i = 0; i < u4NumIPv6Addr; i++) {
  4230. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  4231. prParamNetAddr->u2AddressLength = u4AddrLen;
  4232. kalMemCopy(prParamNetAddr->aucAddress, &pucIPv6Addr[i * u4AddrLen], u4AddrLen);
  4233. prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr +
  4234. (ULONG) (u4AddrLen +
  4235. OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
  4236. }
  4237. prParamNetAddrList->u4AddressCount += u4NumIPv6Addr;
  4238. /* 4 <4> IOCTL to tx_thread */
  4239. rStatus = kalIoctl(prGlueInfo,
  4240. wlanoidSetNetworkAddress,
  4241. (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, &u4SetInfoLen);
  4242. if (rStatus != WLAN_STATUS_SUCCESS)
  4243. DBGLOG(REQ, WARN, "%s: Fail to set network address\n", __func__);
  4244. kalMemFree(prParamNetAddrList, VIR_MEM_TYPE, u4Len);
  4245. }
  4246. VOID kalSetNetAddressFromInterface(IN P_GLUE_INFO_T prGlueInfo, IN struct net_device *prDev, IN BOOLEAN fgSet)
  4247. {
  4248. UINT_32 u4NumIPv4, u4NumIPv6;
  4249. UINT_8 pucIPv4Addr[IPV4_ADDR_LEN * CFG_PF_ARP_NS_MAX_NUM], pucIPv6Addr[IPV6_ADDR_LEN * CFG_PF_ARP_NS_MAX_NUM];
  4250. P_NETDEV_PRIVATE_GLUE_INFO prNetDevPrivate = (P_NETDEV_PRIVATE_GLUE_INFO) NULL;
  4251. prNetDevPrivate = (P_NETDEV_PRIVATE_GLUE_INFO) netdev_priv(prDev);
  4252. if (prNetDevPrivate->prGlueInfo != prGlueInfo)
  4253. DBGLOG(REQ, WARN, "%s: unexpected prGlueInfo(0x%p)!\n", __func__, prNetDevPrivate->prGlueInfo);
  4254. u4NumIPv4 = 0;
  4255. u4NumIPv6 = 0;
  4256. if (fgSet) {
  4257. kalGetIPv4Address(prDev, CFG_PF_ARP_NS_MAX_NUM, pucIPv4Addr, &u4NumIPv4);
  4258. kalGetIPv6Address(prDev, CFG_PF_ARP_NS_MAX_NUM, pucIPv6Addr, &u4NumIPv6);
  4259. }
  4260. if (u4NumIPv4 + u4NumIPv6 > CFG_PF_ARP_NS_MAX_NUM) {
  4261. if (u4NumIPv4 >= CFG_PF_ARP_NS_MAX_NUM) {
  4262. u4NumIPv4 = CFG_PF_ARP_NS_MAX_NUM;
  4263. u4NumIPv6 = 0;
  4264. } else {
  4265. u4NumIPv6 = CFG_PF_ARP_NS_MAX_NUM - u4NumIPv4;
  4266. }
  4267. }
  4268. kalSetNetAddress(prGlueInfo, prNetDevPrivate->ucBssIdx, pucIPv4Addr, u4NumIPv4, pucIPv6Addr, u4NumIPv6);
  4269. }
  4270. #if CFG_MET_PACKET_TRACE_SUPPORT
  4271. BOOLEAN kalMetCheckProfilingPacket(IN P_GLUE_INFO_T prGlueInfo, IN P_NATIVE_PACKET prPacket)
  4272. {
  4273. UINT_32 u4PacketLen;
  4274. UINT_16 u2EtherTypeLen;
  4275. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  4276. PUINT_8 aucLookAheadBuf = NULL;
  4277. UINT_8 ucEthTypeLenOffset = ETHER_HEADER_LEN - ETHER_TYPE_LEN;
  4278. PUINT_8 pucNextProtocol = NULL;
  4279. u4PacketLen = prSkb->len;
  4280. if (u4PacketLen < ETHER_HEADER_LEN) {
  4281. DBGLOG(INIT, WARN, "Invalid Ether packet length: %lu\n", u4PacketLen);
  4282. return FALSE;
  4283. }
  4284. aucLookAheadBuf = prSkb->data;
  4285. /* 4 <0> Obtain Ether Type/Len */
  4286. WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen);
  4287. /* 4 <1> Skip 802.1Q header (VLAN Tagging) */
  4288. if (u2EtherTypeLen == ETH_P_VLAN) {
  4289. ucEthTypeLenOffset += ETH_802_1Q_HEADER_LEN;
  4290. WLAN_GET_FIELD_BE16(&aucLookAheadBuf[ucEthTypeLenOffset], &u2EtherTypeLen);
  4291. }
  4292. /* 4 <2> Obtain next protocol pointer */
  4293. pucNextProtocol = &aucLookAheadBuf[ucEthTypeLenOffset + ETHER_TYPE_LEN];
  4294. /* 4 <3> Handle ethernet format */
  4295. switch (u2EtherTypeLen) {
  4296. /* IPv4 */
  4297. case ETH_P_IPV4:
  4298. {
  4299. PUINT_8 pucIpHdr = pucNextProtocol;
  4300. UINT_8 ucIpVersion;
  4301. /* IPv4 header length check */
  4302. if (u4PacketLen < (ucEthTypeLenOffset + ETHER_TYPE_LEN + IPV4_HDR_LEN)) {
  4303. DBGLOG(INIT, WARN, "Invalid IPv4 packet length: %lu\n", u4PacketLen);
  4304. return FALSE;
  4305. }
  4306. /* IPv4 version check */
  4307. ucIpVersion = (pucIpHdr[0] & IP_VERSION_MASK) >> IP_VERSION_OFFSET;
  4308. if (ucIpVersion != IP_VERSION_4) {
  4309. DBGLOG(INIT, WARN, "Invalid IPv4 packet version: %u\n", ucIpVersion);
  4310. return FALSE;
  4311. }
  4312. if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) {
  4313. PUINT_8 pucUdpHdr = &pucIpHdr[IPV4_HDR_LEN];
  4314. UINT_16 u2UdpDstPort;
  4315. UINT_16 u2UdpSrcPort;
  4316. /* Get UDP DST port */
  4317. WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_DST_PORT_OFFSET], &u2UdpDstPort);
  4318. /* Get UDP SRC port */
  4319. WLAN_GET_FIELD_BE16(&pucUdpHdr[UDP_HDR_SRC_PORT_OFFSET], &u2UdpSrcPort);
  4320. if (u2UdpSrcPort == prGlueInfo->u2MetUdpPort) {
  4321. UINT_16 u2IpId;
  4322. /* Store IP ID for Tag */
  4323. WLAN_GET_FIELD_BE16(&pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET], &u2IpId);
  4324. #if 0
  4325. DBGLOG(INIT, INFO, "TX PKT PROTOCOL[0x%x] UDP DST port[%u] IP_ID[%u]\n",
  4326. pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET], u2UdpDstPort,
  4327. u2IpId);
  4328. #endif
  4329. GLUE_SET_PKT_IP_ID(prPacket, u2IpId);
  4330. return TRUE;
  4331. }
  4332. }
  4333. }
  4334. break;
  4335. default:
  4336. break;
  4337. }
  4338. return FALSE;
  4339. }
  4340. static unsigned long __read_mostly tracing_mark_write_addr;
  4341. static inline void __mt_update_tracing_mark_write_addr(void)
  4342. {
  4343. if (unlikely(0 == tracing_mark_write_addr))
  4344. tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write");
  4345. }
  4346. VOID kalMetTagPacket(IN P_GLUE_INFO_T prGlueInfo, IN P_NATIVE_PACKET prPacket, IN ENUM_TX_PROFILING_TAG_T eTag)
  4347. {
  4348. if (!prGlueInfo->fgMetProfilingEn)
  4349. return;
  4350. switch (eTag) {
  4351. case TX_PROF_TAG_OS_TO_DRV:
  4352. if (kalMetCheckProfilingPacket(prGlueInfo, prPacket)) {
  4353. __mt_update_tracing_mark_write_addr();
  4354. #ifdef CONFIG_TRACING /* #if CFG_MET_PACKET_TRACE_SUPPORT */
  4355. event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", current->tgid, "WIFI-CHIP",
  4356. GLUE_GET_PKT_IP_ID(prPacket));
  4357. #endif
  4358. GLUE_SET_PKT_FLAG_PROF_MET(prPacket);
  4359. }
  4360. break;
  4361. case TX_PROF_TAG_DRV_TX_DONE:
  4362. if (GLUE_GET_PKT_IS_PROF_MET(prPacket)) {
  4363. __mt_update_tracing_mark_write_addr();
  4364. #ifdef CONFIG_TRACING /* #if CFG_MET_PACKET_TRACE_SUPPORT */
  4365. event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", current->tgid, "WIFI-CHIP",
  4366. GLUE_GET_PKT_IP_ID(prPacket));
  4367. #endif
  4368. }
  4369. break;
  4370. case TX_PROF_TAG_MAC_TX_DONE:
  4371. break;
  4372. default:
  4373. break;
  4374. }
  4375. }
  4376. VOID kalMetInit(IN P_GLUE_INFO_T prGlueInfo)
  4377. {
  4378. prGlueInfo->fgMetProfilingEn = FALSE;
  4379. prGlueInfo->u2MetUdpPort = 0;
  4380. }
  4381. /*----------------------------------------------------------------------------*/
  4382. /*!
  4383. * \brief The PROC function for adjusting Debug Level to turn on/off debugging message.
  4384. *
  4385. * \param[in] file pointer to file.
  4386. * \param[in] buffer Buffer from user space.
  4387. * \param[in] count Number of characters to write
  4388. * \param[in] data Pointer to the private data structure.
  4389. *
  4390. * \return number of characters write from User Space.
  4391. */
  4392. /*----------------------------------------------------------------------------*/
  4393. #if 0
  4394. static ssize_t kalMetWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off)
  4395. {
  4396. char acBuf[128 + 1]; /* + 1 for "\0" */
  4397. UINT_32 u4CopySize;
  4398. int u16MetUdpPort;
  4399. int u8MetProfEnable;
  4400. IN P_GLUE_INFO_T prGlueInfo;
  4401. ssize_t result;
  4402. u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
  4403. result = copy_from_user(acBuf, buffer, u4CopySize);
  4404. acBuf[u4CopySize] = '\0';
  4405. if (sscanf(acBuf, " %d %d", &u8MetProfEnable, &u16MetUdpPort) == 2) {
  4406. DBGLOG(INIT, INFO,
  4407. "MET_PROF: Write MET PROC Enable=%d UDP_PORT=%d\n", u8MetProfEnable, u16MetUdpPort);
  4408. }
  4409. if (pMetGlobalData != NULL) {
  4410. prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData;
  4411. prGlueInfo->fgMetProfilingEn = (BOOLEAN) u8MetProfEnable;
  4412. prGlueInfo->u2MetUdpPort = (UINT_16) u16MetUdpPort;
  4413. }
  4414. return count;
  4415. }
  4416. #endif
  4417. static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off)
  4418. {
  4419. char acBuf[128 + 1]; /* + 1 for "\0" */
  4420. UINT_32 u4CopySize;
  4421. int u8MetProfEnable;
  4422. ssize_t result;
  4423. IN P_GLUE_INFO_T prGlueInfo;
  4424. u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
  4425. result = copy_from_user(acBuf, buffer, u4CopySize);
  4426. acBuf[u4CopySize] = '\0';
  4427. if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) {
  4428. DBGLOG(INIT, INFO,
  4429. "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable);
  4430. }
  4431. if (pMetGlobalData != NULL) {
  4432. prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData;
  4433. prGlueInfo->fgMetProfilingEn = (UINT_8) u8MetProfEnable;
  4434. }
  4435. return count;
  4436. }
  4437. static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off)
  4438. {
  4439. char acBuf[128 + 1]; /* + 1 for "\0" */
  4440. UINT_32 u4CopySize;
  4441. int u16MetUdpPort;
  4442. ssize_t result;
  4443. IN P_GLUE_INFO_T prGlueInfo;
  4444. u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
  4445. result = copy_from_user(acBuf, buffer, u4CopySize);
  4446. acBuf[u4CopySize] = '\0';
  4447. if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) {
  4448. DBGLOG(INIT, INFO,
  4449. "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort);
  4450. }
  4451. if (pMetGlobalData != NULL) {
  4452. prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData;
  4453. prGlueInfo->u2MetUdpPort = (UINT_16) u16MetUdpPort;
  4454. }
  4455. return count;
  4456. }
  4457. #if 0
  4458. const struct file_operations rMetProcFops = {
  4459. .write = kalMetWriteProcfs
  4460. };
  4461. #endif
  4462. const struct file_operations rMetProcCtrlFops = {
  4463. .write = kalMetCtrlWriteProcfs
  4464. };
  4465. const struct file_operations rMetProcPortFops = {
  4466. .write = kalMetPortWriteProcfs
  4467. };
  4468. int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo)
  4469. {
  4470. /* struct proc_dir_entry *pMetProcDir; */
  4471. if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
  4472. DBGLOG(INIT, ERROR, "init proc fs fail: proc_net == NULL\n");
  4473. return -ENOENT;
  4474. }
  4475. /*
  4476. * Directory: Root (/proc/net/wlan0)
  4477. */
  4478. pMetProcDir = proc_mkdir("wlan0", init_net.proc_net);
  4479. if (pMetProcDir == NULL)
  4480. return -ENOENT;
  4481. /*
  4482. /proc/net/wlan0
  4483. |-- met_ctrl (PROC_MET_PROF_CTRL)
  4484. */
  4485. /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */
  4486. proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops);
  4487. proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops);
  4488. pMetGlobalData = (void *)prGlueInfo;
  4489. return 0;
  4490. }
  4491. int kalMetRemoveProcfs(void)
  4492. {
  4493. if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
  4494. DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n");
  4495. return -ENOENT;
  4496. }
  4497. /* remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir);
  4498. remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); */
  4499. /* remove root directory (proc/net/wlan0) */
  4500. remove_proc_subtree("wlan0", init_net.proc_net);
  4501. /* clear MetGlobalData */
  4502. pMetGlobalData = NULL;
  4503. return 0;
  4504. }
  4505. #endif
  4506. #if CFG_SUPPORT_AGPS_ASSIST
  4507. BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen)
  4508. {
  4509. P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo;
  4510. struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo),
  4511. dataLen, GFP_KERNEL);
  4512. if (!skb) {
  4513. DBGLOG(AIS, TRACE, "kalIndicateAgpsNotify: alloc skb failed\n");
  4514. return FALSE;
  4515. }
  4516. /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */
  4517. if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0))
  4518. goto nla_put_failure;
  4519. if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0))
  4520. goto nla_put_failure;
  4521. if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0))
  4522. goto nla_put_failure;
  4523. /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */
  4524. if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0))
  4525. goto nla_put_failure;
  4526. cfg80211_testmode_event(skb, GFP_KERNEL);
  4527. return TRUE;
  4528. nla_put_failure:
  4529. kfree_skb(skb);
  4530. return FALSE;
  4531. }
  4532. #endif
  4533. UINT_64 kalGetBootTime(void)
  4534. {
  4535. struct timespec ts;
  4536. UINT_64 bootTime = 0;
  4537. get_monotonic_boottime(&ts);
  4538. bootTime = ts.tv_sec;
  4539. bootTime *= USEC_PER_SEC;
  4540. bootTime += ts.tv_nsec / NSEC_PER_USEC;
  4541. return bootTime;
  4542. }