gl_kal.c 146 KB

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