gl_init.c 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498
  1. /*
  2. * Copyright (C) 2011-2014 MediaTek Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify it under the terms of the
  5. * GNU General Public License version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  8. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. * See the GNU General Public License for more details.
  10. *
  11. * You should have received a copy of the GNU General Public License along with this program.
  12. * If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7
  16. */
  17. /*! \file gl_init.c
  18. \brief Main routines of Linux driver
  19. This file contains the main routines of Linux driver for MediaTek Inc. 802.11
  20. Wireless LAN Adapters.
  21. */
  22. /*
  23. ** Log: gl_init.c
  24. **
  25. ** 09 03 2013 cp.wu
  26. ** add path for reassociation
  27. *
  28. * 07 17 2012 yuche.tsai
  29. * NULL
  30. * Fix compile error.
  31. *
  32. * 07 17 2012 yuche.tsai
  33. * NULL
  34. * Fix compile error for JB.
  35. *
  36. * 07 17 2012 yuche.tsai
  37. * NULL
  38. * Let netdev bring up.
  39. *
  40. * 07 17 2012 yuche.tsai
  41. * NULL
  42. * Compile no error before trial run.
  43. *
  44. * 06 13 2012 yuche.tsai
  45. * NULL
  46. * Update maintrunk driver.
  47. * Add support for driver compose assoc request frame.
  48. *
  49. * 05 25 2012 yuche.tsai
  50. * NULL
  51. * Fix reset KE issue.
  52. *
  53. * 05 11 2012 cp.wu
  54. * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
  55. * show MAC address & source while initiliazation
  56. *
  57. * 03 02 2012 terry.wu
  58. * NULL
  59. * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);.
  60. *
  61. * 03 02 2012 terry.wu
  62. * NULL
  63. * Snc CFG80211 modification for ICS migration from branch 2.2.
  64. *
  65. * 03 02 2012 terry.wu
  66. * NULL
  67. * Sync CFG80211 modification from branch 2,2.
  68. *
  69. * 03 02 2012 terry.wu
  70. * NULL
  71. * Enable CFG80211 Support.
  72. *
  73. * 12 22 2011 george.huang
  74. * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency
  75. * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before
  76. * TX thread handling
  77. *
  78. * 11 18 2011 yuche.tsai
  79. * NULL
  80. * CONFIG P2P support RSSI query, default turned off.
  81. *
  82. * 11 14 2011 yuche.tsai
  83. * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
  84. * Fix large network type index assert in FW issue.
  85. *
  86. * 11 14 2011 cm.chang
  87. * NULL
  88. * Fix compiling warning
  89. *
  90. * 11 11 2011 yuche.tsai
  91. * NULL
  92. * Fix work thread cancel issue.
  93. *
  94. * 11 10 2011 cp.wu
  95. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  96. * 1. eliminaite direct calls to printk in porting layer.
  97. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  98. *
  99. * 10 06 2011 eddie.chen
  100. * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation
  101. * Add rlmDomainGetChnlList symbol.
  102. *
  103. * 09 22 2011 cm.chang
  104. * NULL
  105. * Safer writng stype to avoid unitialized regitry structure
  106. *
  107. * 09 21 2011 cm.chang
  108. * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
  109. * Avoid possible structure alignment problem
  110. *
  111. * 09 20 2011 chinglan.wang
  112. * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
  113. * .
  114. *
  115. * 09 08 2011 cm.chang
  116. * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
  117. * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
  118. *
  119. * 08 31 2011 cm.chang
  120. * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
  121. * .
  122. *
  123. * 08 11 2011 cp.wu
  124. * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
  125. * expose scnQuerySparseChannel() for P2P-FSM.
  126. *
  127. * 08 11 2011 cp.wu
  128. * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
  129. * sparse channel detection:
  130. * driver: collect sparse channel information with scan-done event
  131. *
  132. * 08 02 2011 yuche.tsai
  133. * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting
  134. * device issue.
  135. * Fix GO send deauth frame issue.
  136. *
  137. * 07 07 2011 wh.su
  138. * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL
  139. * Add the dumpMemory8 symbol export for debug mode.
  140. *
  141. * 07 06 2011 terry.wu
  142. * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
  143. * Improve BoW connection establishment speed.
  144. *
  145. * 07 05 2011 yuche.tsai
  146. * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
  147. * Export one symbol for enhancement.
  148. *
  149. * 06 13 2011 eddie.chen
  150. * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni
  151. * Add tx rx statistics and netif_rx_ni.
  152. *
  153. * 05 27 2011 cp.wu
  154. * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
  155. * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
  156. *
  157. * 05 18 2011 cp.wu
  158. * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
  159. * pass PHY_PARAM in NVRAM from driver to firmware.
  160. *
  161. * 05 09 2011 jeffrey.chang
  162. * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
  163. * support ARP filter through kernel notifier
  164. *
  165. * 05 03 2011 chinghwa.yu
  166. * [WCXRP00000065] Update BoW design and settings
  167. * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
  168. *
  169. * 04 27 2011 george.huang
  170. * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
  171. * Support P2P ARP filter setting on early suspend/ late resume
  172. *
  173. * 04 18 2011 terry.wu
  174. * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
  175. * Remove flag CFG_WIFI_DIRECT_MOVED.
  176. *
  177. * 04 15 2011 chinghwa.yu
  178. * [WCXRP00000065] Update BoW design and settings
  179. * Add BOW short range mode.
  180. *
  181. * 04 14 2011 yuche.tsai
  182. * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
  183. * Modify some driver connection flow or behavior to pass Sigma test more easier..
  184. *
  185. * 04 12 2011 cm.chang
  186. * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
  187. * .
  188. *
  189. * 04 11 2011 george.huang
  190. * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
  191. * export wlan functions to p2p
  192. *
  193. * 04 08 2011 pat.lu
  194. * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
  195. * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
  196. *
  197. * 04 08 2011 cp.wu
  198. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  199. * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair.
  200. *
  201. * 04 08 2011 eddie.chen
  202. * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
  203. * Fix for sigma
  204. *
  205. * 04 06 2011 cp.wu
  206. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  207. * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port
  208. * 2. update perm_addr as well for MAC address
  209. * 3. not calling check_mem_region() anymore for eHPI
  210. * 4. correct MSC_CS macro for 0-based notation
  211. *
  212. * 03 29 2011 cp.wu
  213. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
  214. * RESET_START and RESET_END events
  215. * fix typo.
  216. *
  217. * 03 29 2011 cp.wu
  218. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
  219. * RESET_START and RESET_END events
  220. * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
  221. *
  222. * 03 23 2011 cp.wu
  223. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  224. * apply multi-queue operation only for linux kernel > 2.6.26
  225. *
  226. * 03 22 2011 pat.lu
  227. * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
  228. * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
  229. *
  230. * 03 21 2011 cp.wu
  231. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  232. * portability for compatible with linux 2.6.12.
  233. *
  234. * 03 21 2011 cp.wu
  235. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  236. * improve portability for awareness of early version of linux kernel and wireless extension.
  237. *
  238. * 03 21 2011 cp.wu
  239. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  240. * portability improvement
  241. *
  242. * 03 18 2011 jeffrey.chang
  243. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  244. * remove early suspend functions
  245. *
  246. * 03 17 2011 cp.wu
  247. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  248. * after system running for a long period
  249. * reverse order to prevent probing racing.
  250. *
  251. * 03 16 2011 cp.wu
  252. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  253. * after system running for a long period
  254. * 1. pre-allocate physical continuous buffer while module is being loaded
  255. * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
  256. *
  257. * The windows part remained the same as before, but added similar APIs to hide the difference.
  258. *
  259. * 03 15 2011 jeffrey.chang
  260. * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
  261. * refine the queue_select function
  262. *
  263. * 03 10 2011 cp.wu
  264. * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
  265. * deprecate configuration used by MT6620 E2
  266. *
  267. * 03 10 2011 terry.wu
  268. * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
  269. * Remove unnecessary assert and message.
  270. *
  271. * 03 08 2011 terry.wu
  272. * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
  273. * Export nicQmUpdateWmmParms.
  274. *
  275. * 03 03 2011 jeffrey.chang
  276. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  277. * support concurrent network
  278. *
  279. * 03 03 2011 jeffrey.chang
  280. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  281. * modify net device relative functions to support multiple H/W queues
  282. *
  283. * 02 24 2011 george.huang
  284. * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
  285. * Support ARP filter during suspended
  286. *
  287. * 02 21 2011 cp.wu
  288. * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
  289. * simplify logic for checking NVRAM existence only once.
  290. *
  291. * 02 17 2011 terry.wu
  292. * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove
  293. * Fix deference a null pointer problem in wlanRemove.
  294. *
  295. * 02 16 2011 jeffrey.chang
  296. * NULL
  297. * fix compilig error
  298. *
  299. * 02 16 2011 jeffrey.chang
  300. * NULL
  301. * Add query ipv4 and ipv6 address during early suspend and late resume
  302. *
  303. * 02 15 2011 jeffrey.chang
  304. * NULL
  305. * to support early suspend in android
  306. *
  307. * 02 11 2011 yuche.tsai
  308. * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
  309. * Add one more export symbol.
  310. *
  311. * 02 10 2011 yuche.tsai
  312. * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
  313. * Add RX deauthentication & disassociation process under Hot-Spot mode.
  314. *
  315. * 02 09 2011 terry.wu
  316. * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
  317. * Halt p2p module init and exit until TxThread finished p2p register and unregister.
  318. *
  319. * 02 08 2011 george.huang
  320. * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
  321. * Support querying power mode OID.
  322. *
  323. * 02 08 2011 yuche.tsai
  324. * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
  325. * Export Deactivation Network.
  326. *
  327. * 02 01 2011 jeffrey.chang
  328. * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded
  329. * Unregister the KAL timer during driver unloading
  330. *
  331. * 01 26 2011 cm.chang
  332. * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
  333. * Allocate system RAM if fixed message or mgmt buffer is not available
  334. *
  335. * 01 19 2011 cp.wu
  336. * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
  337. * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
  338. *
  339. * 01 12 2011 cp.wu
  340. * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
  341. * implementation of separate BT_OVER_WIFI data path.
  342. *
  343. * 01 10 2011 cp.wu
  344. * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues
  345. * due to multiple access
  346. * use mutex to protect kalIoctl() for thread safe.
  347. *
  348. * 01 04 2011 cp.wu
  349. * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease
  350. * physically continuous memory demands
  351. * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure
  352. *
  353. * 12 15 2010 cp.wu
  354. * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver
  355. * remove set MAC address. MAC address is always loaded from NVRAM instead.
  356. *
  357. * 12 10 2010 kevin.huang
  358. * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
  359. * Add Linux Proc Support
  360. *
  361. * 11 01 2010 yarco.yang
  362. * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
  363. * Add GPIO debug function
  364. *
  365. * 11 01 2010 cp.wu
  366. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
  367. * Add implementation for querying current TX rate from firmware auto rate module
  368. * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
  369. * 2) Remove CNM CH-RECOVER event handling
  370. * 3) cfg read/write API renamed with kal prefix for unified naming rules.
  371. *
  372. * 10 26 2010 cp.wu
  373. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW]
  374. * Support NIC capability query command
  375. * 1) update NVRAM content template to ver 1.02
  376. * 2) add compile option for querying NIC capability (default: off)
  377. * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
  378. * 4) correct auto-rate compiler error under linux (treat warning as error)
  379. * 5) simplify usage of NVRAM and REG_INFO_T
  380. * 6) add version checking between driver and firmware
  381. *
  382. * 10 21 2010 chinghwa.yu
  383. * [WCXRP00000065] Update BoW design and settings
  384. * .
  385. *
  386. * 10 19 2010 jeffrey.chang
  387. * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK
  388. * HIF by default
  389. * Refine linux kernel module to the license of MTK and enable MTK HIF
  390. *
  391. * 10 18 2010 jeffrey.chang
  392. * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android
  393. * .
  394. *
  395. * 10 18 2010 cp.wu
  396. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
  397. * The mac address is all zero at android
  398. * complete implementation of Android NVRAM access
  399. *
  400. * 09 27 2010 chinghwa.yu
  401. * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
  402. * Update BCM/BoW design and settings.
  403. *
  404. * 09 23 2010 cp.wu
  405. * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
  406. * use firmware reported mac address right after wlanAdapterStart() as permanent address
  407. *
  408. * 09 21 2010 kevin.huang
  409. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  410. * Eliminate Linux Compile Warning
  411. *
  412. * 09 03 2010 kevin.huang
  413. * NULL
  414. * Refine #include sequence and solve recursive/nested #include issue
  415. *
  416. * 09 01 2010 wh.su
  417. * NULL
  418. * adding the wapi support for integration test.
  419. *
  420. * 08 18 2010 yarco.yang
  421. * NULL
  422. * 1. Fixed HW checksum offload function not work under Linux issue.
  423. * 2. Add debug message.
  424. *
  425. * 08 16 2010 yarco.yang
  426. * NULL
  427. * Support Linux x86
  428. *
  429. * 08 02 2010 jeffrey.chang
  430. * NULL
  431. * 1) modify tx service thread to avoid busy looping
  432. * 2) add spin lock declartion for linux build
  433. *
  434. * 07 29 2010 jeffrey.chang
  435. * NULL
  436. * fix memory leak for module unloading
  437. *
  438. * 07 28 2010 jeffrey.chang
  439. * NULL
  440. * 1) remove unused spinlocks
  441. * 2) enable encyption ioctls
  442. * 3) fix scan ioctl which may cause supplicant to hang
  443. *
  444. * 07 23 2010 jeffrey.chang
  445. *
  446. * bug fix: allocate regInfo when disabling firmware download
  447. *
  448. * 07 23 2010 jeffrey.chang
  449. *
  450. * use glue layer api to decrease or increase counter atomically
  451. *
  452. * 07 22 2010 jeffrey.chang
  453. *
  454. * add new spinlock
  455. *
  456. * 07 19 2010 jeffrey.chang
  457. *
  458. * modify cmd/data path for new design
  459. *
  460. * 07 08 2010 cp.wu
  461. *
  462. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  463. *
  464. * 06 06 2010 kevin.huang
  465. * [WPD00003832][MT6620 5931] Create driver base
  466. * [MT6620 5931] Create driver base
  467. *
  468. * 05 26 2010 jeffrey.chang
  469. * [WPD00003826]Initial import for Linux port
  470. * 1) Modify set mac address code
  471. * 2) remove power management macro
  472. *
  473. * 05 10 2010 cp.wu
  474. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  475. * implement basic wi-fi direct framework
  476. *
  477. * 05 07 2010 jeffrey.chang
  478. * [WPD00003826]Initial import for Linux port
  479. * prevent supplicant accessing driver during resume
  480. *
  481. * 05 07 2010 cp.wu
  482. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  483. * add basic framework for implementating P2P driver hook.
  484. *
  485. * 04 27 2010 jeffrey.chang
  486. * [WPD00003826]Initial import for Linux port
  487. * 1) fix firmware download bug
  488. * 2) remove query statistics for acelerating firmware download
  489. *
  490. * 04 27 2010 jeffrey.chang
  491. * [WPD00003826]Initial import for Linux port
  492. * follow Linux's firmware framework, and remove unused kal API
  493. *
  494. * 04 21 2010 jeffrey.chang
  495. * [WPD00003826]Initial import for Linux port
  496. * add for private ioctl support
  497. *
  498. * 04 19 2010 jeffrey.chang
  499. * [WPD00003826]Initial import for Linux port
  500. * Query statistics from firmware
  501. *
  502. * 04 19 2010 jeffrey.chang
  503. * [WPD00003826]Initial import for Linux port
  504. * modify tcp/ip checksum offload flags
  505. *
  506. * 04 16 2010 jeffrey.chang
  507. * [WPD00003826]Initial import for Linux port
  508. * fix tcp/ip checksum offload bug
  509. *
  510. * 04 13 2010 cp.wu
  511. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  512. * add framework for BT-over-Wi-Fi support.
  513. * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler
  514. * * * * * * * * * * * * * * * * * capability
  515. * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically
  516. * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose
  517. *
  518. * 04 09 2010 jeffrey.chang
  519. * [WPD00003826]Initial import for Linux port
  520. * fix spinlock usage
  521. *
  522. * 04 07 2010 jeffrey.chang
  523. * [WPD00003826]Initial import for Linux port
  524. * Set MAC address from firmware
  525. *
  526. * 04 07 2010 cp.wu
  527. * [WPD00001943]Create WiFi test driver framework on WinXP
  528. * rWlanInfo should be placed at adapter rather than glue due to most operations
  529. * * * * * * are done in adapter layer.
  530. *
  531. * 04 07 2010 jeffrey.chang
  532. * [WPD00003826]Initial import for Linux port
  533. * (1)improve none-glue code portability
  534. * * (2) disable set Multicast address during atomic context
  535. *
  536. * 04 06 2010 jeffrey.chang
  537. * [WPD00003826]Initial import for Linux port
  538. * adding debug module
  539. *
  540. * 03 31 2010 wh.su
  541. * [WPD00003816][MT6620 Wi-Fi] Adding the security support
  542. * modify the wapi related code for new driver's design.
  543. *
  544. * 03 30 2010 jeffrey.chang
  545. * [WPD00003826]Initial import for Linux port
  546. * emulate NDIS Pending OID facility
  547. *
  548. * 03 26 2010 jeffrey.chang
  549. * [WPD00003826]Initial import for Linux port
  550. * fix f/w download start and load address by using config.h
  551. *
  552. * 03 26 2010 jeffrey.chang
  553. * [WPD00003826]Initial import for Linux port
  554. * [WPD00003826] Initial import for Linux port
  555. * adding firmware download support
  556. *
  557. * 03 24 2010 jeffrey.chang
  558. * [WPD00003826]Initial import for Linux port
  559. * initial import for Linux port
  560. ** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090
  561. ** Fix compile error for Linux EHPI driver
  562. ** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090
  563. ** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests,
  564. ** and then stop hw.
  565. ** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090
  566. ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input
  567. ** parameters and pointers.
  568. ** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090
  569. ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
  570. ** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088
  571. ** remove non-used code
  572. ** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088
  573. ** adding the module parameter for wapi
  574. ** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090
  575. ** Add Linux SDIO (with mmc core) support.
  576. ** Add Linux 2.6.21, 2.6.25, 2.6.26.
  577. ** Fix compile warning in Linux.
  578. ** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088
  579. ** adding the code to check the wapi 1x frame
  580. ** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090
  581. ** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
  582. ** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461
  583. ** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY
  584. ** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088
  585. ** set the tid and 1x value at same packet reserved field
  586. ** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104
  587. ** Fix wrong variable name "prDev" in wlanStop()
  588. ** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461
  589. ** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY
  590. ** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461
  591. ** Update driver for Code review
  592. ** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461
  593. ** Update Driver for Code Review
  594. ** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461
  595. ** Update driver for code review
  596. ** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461
  597. ** Add support for linux statistics
  598. ** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461
  599. ** Fix ASSERT if removing module in BG_SSID_SCAN state
  600. ** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461
  601. ** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS
  602. ** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461
  603. ** Not use wlanoidSetCurrentAddrForLinux()
  604. ** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461
  605. ** Remove WMM Assoc Flag
  606. ** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084
  607. ** modify wlanISR interface
  608. ** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461
  609. ** Fix Unset Broadcast filter when setMulticast
  610. ** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461
  611. ** Move Query Media Status to GLUE
  612. ** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461
  613. ** Revise set multicast function by using windows oid style for LP own back
  614. ** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461
  615. ** Fix multicast setting in Linux and add comment
  616. ** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461
  617. ** Fix set mac address func in Linux
  618. ** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461
  619. ** Add set MAC Address
  620. ** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461
  621. ** For Linux, set net_device has feature with checksum offload by default
  622. ** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461
  623. ** Fix typo
  624. ** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088
  625. ** add 1x decide code for sw port control
  626. ** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461
  627. ** Rearrange the set off place of GLUE spin lock in HardStartXmit
  628. ** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461
  629. ** Add debug option - Packet Order for Linux and add debug level - Event
  630. ** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461
  631. ** Fix SPIN_LOCK protection
  632. ** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425
  633. ** 1. Set Rx multicast packets mode before setting the address list
  634. ** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461
  635. ** Add OS_TIMESTAMP to packet
  636. ** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088
  637. ** fixed the unload module issue
  638. ** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461
  639. ** Fix compile warnning
  640. ** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461
  641. ** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
  642. ** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425
  643. ** 1. Refine for multicast list
  644. ** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461
  645. ** Add VOIP SCAN Support & Refine Roaming
  646. ** Revision 1.4 2007/07/05 07:25:33 MTK01461
  647. ** Add Linux initial code, modify doc, add 11BB, RF init code
  648. **
  649. ** Revision 1.3 2007/06/27 02:18:50 MTK01461
  650. ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
  651. **
  652. ** Revision 1.2 2007/06/25 06:16:24 MTK01461
  653. ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
  654. **
  655. */
  656. /*******************************************************************************
  657. * C O M P I L E R F L A G S
  658. ********************************************************************************
  659. */
  660. /*******************************************************************************
  661. * E X T E R N A L R E F E R E N C E S
  662. ********************************************************************************
  663. */
  664. #include "gl_os.h"
  665. #include "debug.h"
  666. #include "wlan_lib.h"
  667. #include "gl_wext.h"
  668. #include "gl_cfg80211.h"
  669. #include "precomp.h"
  670. #if CFG_SUPPORT_AGPS_ASSIST
  671. #include "gl_kal.h"
  672. #endif
  673. #if defined(CONFIG_MTK_TC1_FEATURE)
  674. #include <tc1_partition.h>
  675. #endif
  676. #include "gl_vendor.h"
  677. /*******************************************************************************
  678. * C O N S T A N T S
  679. ********************************************************************************
  680. */
  681. /* #define MAX_IOREQ_NUM 10 */
  682. BOOLEAN fgIsUnderSuspend = false;
  683. #if CFG_ENABLE_WIFI_DIRECT
  684. spinlock_t g_p2p_lock;
  685. int g_u4P2PEnding = 0;
  686. int g_u4P2POnOffing = 0;
  687. #endif
  688. /*******************************************************************************
  689. * D A T A T Y P E S
  690. ********************************************************************************
  691. */
  692. /* Tasklet mechanism is like buttom-half in Linux. We just want to
  693. * send a signal to OS for interrupt defer processing. All resources
  694. * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
  695. */
  696. typedef struct _WLANDEV_INFO_T {
  697. struct net_device *prDev;
  698. } WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
  699. /*******************************************************************************
  700. * P U B L I C D A T A
  701. ********************************************************************************
  702. */
  703. MODULE_AUTHOR(NIC_AUTHOR);
  704. MODULE_DESCRIPTION(NIC_DESC);
  705. MODULE_SUPPORTED_DEVICE(NIC_NAME);
  706. MODULE_LICENSE("GPL");
  707. #define NIC_INF_NAME "wlan%d" /* interface name */
  708. #if CFG_TC1_FEATURE
  709. #define NIC_INF_NAME_IN_AP_MODE "legacy%d"
  710. #endif
  711. /* support to change debug module info dynamically */
  712. UINT_8 aucDebugModule[DBG_MODULE_NUM];
  713. UINT_32 u4DebugModule = 0;
  714. /* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */
  715. static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} };
  716. static UINT_32 u4WlanDevNum; /* How many NICs coexist now */
  717. /**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/
  718. struct delayed_work sched_workq;
  719. /*******************************************************************************
  720. * P R I V A T E D A T A
  721. ********************************************************************************
  722. */
  723. #if CFG_ENABLE_WIFI_DIRECT
  724. static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} };
  725. #endif
  726. #define CHAN2G(_channel, _freq, _flags) \
  727. { \
  728. .band = IEEE80211_BAND_2GHZ, \
  729. .center_freq = (_freq), \
  730. .hw_value = (_channel), \
  731. .flags = (_flags), \
  732. .max_antenna_gain = 0, \
  733. .max_power = 30, \
  734. }
  735. static struct ieee80211_channel mtk_2ghz_channels[] = {
  736. CHAN2G(1, 2412, 0),
  737. CHAN2G(2, 2417, 0),
  738. CHAN2G(3, 2422, 0),
  739. CHAN2G(4, 2427, 0),
  740. CHAN2G(5, 2432, 0),
  741. CHAN2G(6, 2437, 0),
  742. CHAN2G(7, 2442, 0),
  743. CHAN2G(8, 2447, 0),
  744. CHAN2G(9, 2452, 0),
  745. CHAN2G(10, 2457, 0),
  746. CHAN2G(11, 2462, 0),
  747. CHAN2G(12, 2467, 0),
  748. CHAN2G(13, 2472, 0),
  749. CHAN2G(14, 2484, 0),
  750. };
  751. #define CHAN5G(_channel, _flags) \
  752. { \
  753. .band = IEEE80211_BAND_5GHZ, \
  754. .center_freq = 5000 + (5 * (_channel)), \
  755. .hw_value = (_channel), \
  756. .flags = (_flags), \
  757. .max_antenna_gain = 0, \
  758. .max_power = 30, \
  759. }
  760. static struct ieee80211_channel mtk_5ghz_channels[] = {
  761. CHAN5G(34, 0), CHAN5G(36, 0),
  762. CHAN5G(38, 0), CHAN5G(40, 0),
  763. CHAN5G(42, 0), CHAN5G(44, 0),
  764. CHAN5G(46, 0), CHAN5G(48, 0),
  765. CHAN5G(52, 0), CHAN5G(56, 0),
  766. CHAN5G(60, 0), CHAN5G(64, 0),
  767. CHAN5G(100, 0), CHAN5G(104, 0),
  768. CHAN5G(108, 0), CHAN5G(112, 0),
  769. CHAN5G(116, 0), CHAN5G(120, 0),
  770. CHAN5G(124, 0), CHAN5G(128, 0),
  771. CHAN5G(132, 0), CHAN5G(136, 0),
  772. CHAN5G(140, 0), CHAN5G(149, 0),
  773. CHAN5G(153, 0), CHAN5G(157, 0),
  774. CHAN5G(161, 0), CHAN5G(165, 0),
  775. CHAN5G(169, 0), CHAN5G(173, 0),
  776. CHAN5G(184, 0), CHAN5G(188, 0),
  777. CHAN5G(192, 0), CHAN5G(196, 0),
  778. CHAN5G(200, 0), CHAN5G(204, 0),
  779. CHAN5G(208, 0), CHAN5G(212, 0),
  780. CHAN5G(216, 0),
  781. };
  782. /* for cfg80211 - rate table */
  783. static struct ieee80211_rate mtk_rates[] = {
  784. RATETAB_ENT(10, 0x1000, 0),
  785. RATETAB_ENT(20, 0x1001, 0),
  786. RATETAB_ENT(55, 0x1002, 0),
  787. RATETAB_ENT(110, 0x1003, 0), /* 802.11b */
  788. RATETAB_ENT(60, 0x2000, 0),
  789. RATETAB_ENT(90, 0x2001, 0),
  790. RATETAB_ENT(120, 0x2002, 0),
  791. RATETAB_ENT(180, 0x2003, 0),
  792. RATETAB_ENT(240, 0x2004, 0),
  793. RATETAB_ENT(360, 0x2005, 0),
  794. RATETAB_ENT(480, 0x2006, 0),
  795. RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */
  796. };
  797. #define mtk_a_rates (mtk_rates + 4)
  798. #define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
  799. #define mtk_g_rates (mtk_rates + 0)
  800. #define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
  801. #define MT6620_MCS_INFO \
  802. { \
  803. .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
  804. .rx_highest = 0, \
  805. .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
  806. }
  807. #define MT6620_HT_CAP \
  808. { \
  809. .ht_supported = true, \
  810. .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \
  811. | IEEE80211_HT_CAP_SM_PS \
  812. | IEEE80211_HT_CAP_GRN_FLD \
  813. | IEEE80211_HT_CAP_SGI_20 \
  814. | IEEE80211_HT_CAP_SGI_40, \
  815. .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
  816. .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \
  817. .mcs = MT6620_MCS_INFO, \
  818. }
  819. /* public for both Legacy Wi-Fi / P2P access */
  820. struct ieee80211_supported_band mtk_band_2ghz = {
  821. .band = IEEE80211_BAND_2GHZ,
  822. .channels = mtk_2ghz_channels,
  823. .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
  824. .bitrates = mtk_g_rates,
  825. .n_bitrates = mtk_g_rates_size,
  826. .ht_cap = MT6620_HT_CAP,
  827. };
  828. /* public for both Legacy Wi-Fi / P2P access */
  829. struct ieee80211_supported_band mtk_band_5ghz = {
  830. .band = IEEE80211_BAND_5GHZ,
  831. .channels = mtk_5ghz_channels,
  832. .n_channels = ARRAY_SIZE(mtk_5ghz_channels),
  833. .bitrates = mtk_a_rates,
  834. .n_bitrates = mtk_a_rates_size,
  835. .ht_cap = MT6620_HT_CAP,
  836. };
  837. static const UINT_32 mtk_cipher_suites[] = {
  838. /* keep WEP first, it may be removed below */
  839. WLAN_CIPHER_SUITE_WEP40,
  840. WLAN_CIPHER_SUITE_WEP104,
  841. WLAN_CIPHER_SUITE_TKIP,
  842. WLAN_CIPHER_SUITE_CCMP,
  843. /* keep last -- depends on hw flags! */
  844. WLAN_CIPHER_SUITE_AES_CMAC
  845. };
  846. static struct cfg80211_ops mtk_wlan_ops = {
  847. .suspend = mtk_cfg80211_suspend,
  848. .resume = mtk_cfg80211_resume,
  849. .change_virtual_intf = mtk_cfg80211_change_iface,
  850. .add_key = mtk_cfg80211_add_key,
  851. .get_key = mtk_cfg80211_get_key,
  852. .del_key = mtk_cfg80211_del_key,
  853. .set_default_key = mtk_cfg80211_set_default_key,
  854. .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key,
  855. .get_station = mtk_cfg80211_get_station,
  856. .change_station = mtk_cfg80211_change_station,
  857. .add_station = mtk_cfg80211_add_station,
  858. .del_station = mtk_cfg80211_del_station,
  859. .scan = mtk_cfg80211_scan,
  860. .connect = mtk_cfg80211_connect,
  861. .disconnect = mtk_cfg80211_disconnect,
  862. .join_ibss = mtk_cfg80211_join_ibss,
  863. .leave_ibss = mtk_cfg80211_leave_ibss,
  864. .set_power_mgmt = mtk_cfg80211_set_power_mgmt,
  865. .set_pmksa = mtk_cfg80211_set_pmksa,
  866. .del_pmksa = mtk_cfg80211_del_pmksa,
  867. .flush_pmksa = mtk_cfg80211_flush_pmksa,
  868. .assoc = mtk_cfg80211_assoc,
  869. /* Action Frame TX/RX */
  870. .remain_on_channel = mtk_cfg80211_remain_on_channel,
  871. .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel,
  872. .mgmt_tx = mtk_cfg80211_mgmt_tx,
  873. /* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */
  874. .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register,
  875. #ifdef CONFIG_NL80211_TESTMODE
  876. .testmode_cmd = mtk_cfg80211_testmode_cmd,
  877. #endif
  878. #if (CFG_SUPPORT_TDLS == 1)
  879. .tdls_mgmt = TdlsexCfg80211TdlsMgmt,
  880. .tdls_oper = TdlsexCfg80211TdlsOper,
  881. #endif /* CFG_SUPPORT_TDLS */
  882. #if 1 /* Remove schedule_scan because we need more verification for NLO */
  883. .sched_scan_start = mtk_cfg80211_sched_scan_start,
  884. .sched_scan_stop = mtk_cfg80211_sched_scan_stop,
  885. #endif
  886. };
  887. static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = {
  888. {
  889. {
  890. .vendor_id = GOOGLE_OUI,
  891. .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES},
  892. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  893. .doit = mtk_cfg80211_vendor_get_gscan_capabilities},
  894. {
  895. {
  896. .vendor_id = GOOGLE_OUI,
  897. .subcmd = GSCAN_SUBCMD_SET_CONFIG},
  898. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  899. .doit = mtk_cfg80211_vendor_set_config},
  900. {
  901. {
  902. .vendor_id = GOOGLE_OUI,
  903. .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG},
  904. .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
  905. .doit = mtk_cfg80211_vendor_set_scan_config},
  906. {
  907. {
  908. .vendor_id = GOOGLE_OUI,
  909. .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN},
  910. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  911. .doit = mtk_cfg80211_vendor_enable_scan},
  912. {
  913. {
  914. .vendor_id = GOOGLE_OUI,
  915. .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS},
  916. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  917. .doit = mtk_cfg80211_vendor_enable_full_scan_results},
  918. {
  919. {
  920. .vendor_id = GOOGLE_OUI,
  921. .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS},
  922. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  923. .doit = mtk_cfg80211_vendor_get_scan_results},
  924. {
  925. {
  926. .vendor_id = GOOGLE_OUI,
  927. .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST},
  928. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  929. .doit = mtk_cfg80211_vendor_get_channel_list},
  930. {
  931. {
  932. .vendor_id = GOOGLE_OUI,
  933. .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG},
  934. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  935. .doit = mtk_cfg80211_vendor_set_significant_change},
  936. {
  937. {
  938. .vendor_id = GOOGLE_OUI,
  939. .subcmd = GSCAN_SUBCMD_SET_HOTLIST},
  940. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  941. .doit = mtk_cfg80211_vendor_set_hotlist},
  942. /*Link Layer Statistics */
  943. {
  944. {
  945. .vendor_id = GOOGLE_OUI,
  946. .subcmd = LSTATS_SUBCMD_GET_INFO},
  947. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  948. .doit = mtk_cfg80211_vendor_llstats_get_info},
  949. {
  950. {
  951. .vendor_id = GOOGLE_OUI,
  952. .subcmd = RTT_SUBCMD_GETCAPABILITY},
  953. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  954. .doit = mtk_cfg80211_vendor_get_rtt_capabilities},
  955. };
  956. static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = {
  957. {
  958. .vendor_id = GOOGLE_OUI,
  959. .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS},
  960. {
  961. .vendor_id = GOOGLE_OUI,
  962. .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND},
  963. {
  964. .vendor_id = GOOGLE_OUI,
  965. .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE},
  966. {
  967. .vendor_id = GOOGLE_OUI,
  968. .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS},
  969. {
  970. .vendor_id = GOOGLE_OUI,
  971. .subcmd = RTT_EVENT_COMPLETE},
  972. {
  973. .vendor_id = GOOGLE_OUI,
  974. .subcmd = GSCAN_EVENT_COMPLETE_SCAN},
  975. {
  976. .vendor_id = GOOGLE_OUI,
  977. .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST},
  978. };
  979. /* There isn't a lot of sense in it, but you can transmit anything you like */
  980. static const struct ieee80211_txrx_stypes
  981. mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
  982. [NL80211_IFTYPE_ADHOC] = {
  983. .tx = 0xffff,
  984. .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
  985. },
  986. [NL80211_IFTYPE_STATION] = {
  987. .tx = 0xffff,
  988. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  989. },
  990. [NL80211_IFTYPE_AP] = {
  991. .tx = 0xffff,
  992. .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  993. },
  994. [NL80211_IFTYPE_AP_VLAN] = {
  995. /* copy AP */
  996. .tx = 0xffff,
  997. .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  998. BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  999. BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  1000. BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  1001. BIT(IEEE80211_STYPE_AUTH >> 4) |
  1002. BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  1003. },
  1004. [NL80211_IFTYPE_P2P_CLIENT] = {
  1005. .tx = 0xffff,
  1006. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  1007. },
  1008. [NL80211_IFTYPE_P2P_GO] = {
  1009. .tx = 0xffff,
  1010. .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  1011. }
  1012. };
  1013. /*******************************************************************************
  1014. * M A C R O S
  1015. ********************************************************************************
  1016. */
  1017. /*******************************************************************************
  1018. * F U N C T I O N D E C L A R A T I O N S
  1019. ********************************************************************************
  1020. */
  1021. /*******************************************************************************
  1022. * F U N C T I O N S
  1023. ********************************************************************************
  1024. */
  1025. /*----------------------------------------------------------------------------*/
  1026. /*!
  1027. * \brief Override the implementation of select queue
  1028. *
  1029. * \param[in] dev Pointer to struct net_device
  1030. * \param[in] skb Pointer to struct skb_buff
  1031. *
  1032. * \return (none)
  1033. */
  1034. /*----------------------------------------------------------------------------*/
  1035. unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
  1036. {
  1037. unsigned int dscp = 0;
  1038. /* skb->priority values from 256->263 are magic values
  1039. * directly indicate a specific 802.1d priority. This is
  1040. * to allow 802.1d priority to be passed directly in from
  1041. * tags
  1042. */
  1043. if (skb->priority >= 256 && skb->priority <= 263)
  1044. return skb->priority - 256;
  1045. switch (skb->protocol) {
  1046. case htons(ETH_P_IP):
  1047. dscp = ip_hdr(skb)->tos & 0xfc;
  1048. break;
  1049. }
  1050. return dscp >> 5;
  1051. }
  1052. static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
  1053. static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb,
  1054. void *accel_priv, select_queue_fallback_t fallback)
  1055. {
  1056. skb->priority = _cfg80211_classify8021d(skb);
  1057. return au16Wlan1dToQueueIdx[skb->priority];
  1058. }
  1059. /*----------------------------------------------------------------------------*/
  1060. /*!
  1061. * \brief Load NVRAM data and translate it into REG_INFO_T
  1062. *
  1063. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1064. * \param[out] prRegInfo Pointer to struct REG_INFO_T
  1065. *
  1066. * \return (none)
  1067. */
  1068. /*----------------------------------------------------------------------------*/
  1069. static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo)
  1070. {
  1071. UINT_32 i, j;
  1072. UINT_8 aucTmp[2];
  1073. PUINT_8 pucDest;
  1074. ASSERT(prGlueInfo);
  1075. ASSERT(prRegInfo);
  1076. if ((!prGlueInfo) || (!prRegInfo))
  1077. return;
  1078. if (kalCfgDataRead16(prGlueInfo, 0, (PUINT_16) aucTmp) == TRUE) {
  1079. prGlueInfo->fgNvramAvailable = TRUE;
  1080. /* load MAC Address */
  1081. #if !defined(CONFIG_MTK_TC1_FEATURE)
  1082. for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) {
  1083. kalCfgDataRead16(prGlueInfo,
  1084. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
  1085. (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i));
  1086. }
  1087. #else
  1088. TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr);
  1089. #endif
  1090. /* load country code */
  1091. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp);
  1092. /* cast to wide characters */
  1093. prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
  1094. prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
  1095. /* load default normal TX power */
  1096. for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) {
  1097. kalCfgDataRead16(prGlueInfo,
  1098. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
  1099. (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i));
  1100. }
  1101. /* load feature flags */
  1102. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp);
  1103. prRegInfo->ucTxPwrValid = aucTmp[0];
  1104. prRegInfo->ucSupport5GBand = aucTmp[1];
  1105. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp);
  1106. prRegInfo->uc2G4BwFixed20M = aucTmp[0];
  1107. prRegInfo->uc5GBwFixed20M = aucTmp[1];
  1108. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp);
  1109. prRegInfo->ucEnable5GBand = aucTmp[0];
  1110. /* load EFUSE overriding part */
  1111. for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) {
  1112. kalCfgDataRead16(prGlueInfo,
  1113. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
  1114. (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i));
  1115. }
  1116. /* load band edge tx power control */
  1117. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp);
  1118. prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0];
  1119. if (aucTmp[0]) {
  1120. prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1];
  1121. kalCfgDataRead16(prGlueInfo,
  1122. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp);
  1123. prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0];
  1124. prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1];
  1125. }
  1126. /* load regulation subbands */
  1127. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp);
  1128. prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
  1129. prRegInfo->ucRegChannelListIndex = aucTmp[1];
  1130. if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
  1131. for (i = 0; i < MAX_SUBBAND_NUM; i++) {
  1132. pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
  1133. for (j = 0; j < 6; j += sizeof(UINT_16)) {
  1134. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
  1135. + (i * 6 + j), (PUINT_16) aucTmp);
  1136. *pucDest++ = aucTmp[0];
  1137. *pucDest++ = aucTmp[1];
  1138. }
  1139. }
  1140. }
  1141. /* load RSSI compensation */
  1142. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp);
  1143. prRegInfo->uc2GRssiCompensation = aucTmp[0];
  1144. prRegInfo->uc5GRssiCompensation = aucTmp[1];
  1145. kalCfgDataRead16(prGlueInfo,
  1146. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp);
  1147. prRegInfo->fgRssiCompensationValidbit = aucTmp[0];
  1148. prRegInfo->ucRxAntennanumber = aucTmp[1];
  1149. } else {
  1150. prGlueInfo->fgNvramAvailable = FALSE;
  1151. }
  1152. }
  1153. #if CFG_ENABLE_WIFI_DIRECT
  1154. /*----------------------------------------------------------------------------*/
  1155. /*!
  1156. * \brief called by txthread, run sub module init function
  1157. *
  1158. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1159. *
  1160. * \return (none)
  1161. */
  1162. /*----------------------------------------------------------------------------*/
  1163. VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo)
  1164. {
  1165. /*now, we only have p2p module */
  1166. if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
  1167. rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
  1168. rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
  1169. }
  1170. }
  1171. /*----------------------------------------------------------------------------*/
  1172. /*!
  1173. * \brief called by txthread, run sub module exit function
  1174. *
  1175. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1176. *
  1177. * \return (none)
  1178. */
  1179. /*----------------------------------------------------------------------------*/
  1180. VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo)
  1181. {
  1182. /*now, we only have p2p module */
  1183. if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
  1184. rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
  1185. rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
  1186. }
  1187. }
  1188. /*----------------------------------------------------------------------------*/
  1189. /*!
  1190. * \brief set sub module init flag, force TxThread to run sub modle init
  1191. *
  1192. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1193. *
  1194. * \return (none)
  1195. */
  1196. /*----------------------------------------------------------------------------*/
  1197. BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo)
  1198. {
  1199. /* 4 Mark HALT, notify main thread to finish current job */
  1200. prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT;
  1201. /* wake up main thread */
  1202. wake_up_interruptible(&prGlueInfo->waitq);
  1203. /* wait main thread finish sub module INIT */
  1204. wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
  1205. #if 0
  1206. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1207. p2pNetRegister(prGlueInfo);
  1208. #endif
  1209. return TRUE;
  1210. }
  1211. /*----------------------------------------------------------------------------*/
  1212. /*!
  1213. * \brief set sub module exit flag, force TxThread to run sub modle exit
  1214. *
  1215. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1216. *
  1217. * \return (none)
  1218. */
  1219. /*----------------------------------------------------------------------------*/
  1220. BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo)
  1221. {
  1222. #if 0
  1223. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1224. p2pNetUnregister(prGlueInfo);
  1225. #endif
  1226. /* 4 Mark HALT, notify main thread to finish current job */
  1227. prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT;
  1228. /* wake up main thread */
  1229. wake_up_interruptible(&prGlueInfo->waitq);
  1230. /* wait main thread finish sub module EXIT */
  1231. wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
  1232. return TRUE;
  1233. }
  1234. /*----------------------------------------------------------------------------*/
  1235. /*!
  1236. * \brief set by sub module, indicate sub module is already inserted
  1237. *
  1238. * \param[in] rSubModInit, function pointer point to sub module init function
  1239. * \param[in] rSubModExit, function pointer point to sub module exit function
  1240. * \param[in] eSubModIdx, sub module index
  1241. *
  1242. * \return (none)
  1243. */
  1244. /*----------------------------------------------------------------------------*/
  1245. VOID
  1246. wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx)
  1247. {
  1248. rSubModHandler[eSubModIdx].subModInit = rSubModInit;
  1249. rSubModHandler[eSubModIdx].subModExit = rSubModExit;
  1250. rSubModHandler[eSubModIdx].fgIsInited = FALSE;
  1251. }
  1252. #if 0
  1253. /*----------------------------------------------------------------------------*/
  1254. /*!
  1255. * \brief check wlan is launched or not
  1256. *
  1257. * \param[in] (none)
  1258. *
  1259. * \return TRUE, wlan is already started
  1260. * FALSE, wlan is not started yet
  1261. */
  1262. /*----------------------------------------------------------------------------*/
  1263. BOOLEAN wlanIsLaunched(VOID)
  1264. {
  1265. struct net_device *prDev = NULL;
  1266. P_GLUE_INFO_T prGlueInfo = NULL;
  1267. /* 4 <0> Sanity check */
  1268. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  1269. if (0 == u4WlanDevNum)
  1270. return FALSE;
  1271. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  1272. ASSERT(prDev);
  1273. if (NULL == prDev)
  1274. return FALSE;
  1275. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1276. ASSERT(prGlueInfo);
  1277. if (NULL == prGlueInfo)
  1278. return FALSE;
  1279. return prGlueInfo->prAdapter->fgIsWlanLaunched;
  1280. }
  1281. #endif
  1282. /*----------------------------------------------------------------------------*/
  1283. /*!
  1284. * \brief Export wlan GLUE_INFO_T pointer to p2p module
  1285. *
  1286. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1287. *
  1288. * \return TRUE: get GlueInfo pointer successfully
  1289. * FALSE: wlan is not started yet
  1290. */
  1291. /*---------------------------------------------------------------------------*/
  1292. BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr)
  1293. {
  1294. struct net_device *prDev = NULL;
  1295. P_GLUE_INFO_T prGlueInfo = NULL;
  1296. if (0 == u4WlanDevNum)
  1297. return FALSE;
  1298. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  1299. if (NULL == prDev)
  1300. return FALSE;
  1301. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1302. if (NULL == prGlueInfo)
  1303. return FALSE;
  1304. if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched)
  1305. return FALSE;
  1306. *prGlueInfoExpAddr = prGlueInfo;
  1307. return TRUE;
  1308. }
  1309. #endif
  1310. /*----------------------------------------------------------------------------*/
  1311. /*!
  1312. * \brief Release prDev from wlandev_array and free tasklet object related to it.
  1313. *
  1314. * \param[in] prDev Pointer to struct net_device
  1315. *
  1316. * \return (none)
  1317. */
  1318. /*----------------------------------------------------------------------------*/
  1319. static void wlanClearDevIdx(struct net_device *prDev)
  1320. {
  1321. int i;
  1322. ASSERT(prDev);
  1323. for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
  1324. if (arWlanDevInfo[i].prDev == prDev) {
  1325. arWlanDevInfo[i].prDev = NULL;
  1326. u4WlanDevNum--;
  1327. }
  1328. }
  1329. } /* end of wlanClearDevIdx() */
  1330. /*----------------------------------------------------------------------------*/
  1331. /*!
  1332. * \brief Allocate an unique interface index, net_device::ifindex member for this
  1333. * wlan device. Store the net_device in wlandev_array, and initialize
  1334. * tasklet object related to it.
  1335. *
  1336. * \param[in] prDev Pointer to struct net_device
  1337. *
  1338. * \retval >= 0 The device number.
  1339. * \retval -1 Fail to get index.
  1340. */
  1341. /*----------------------------------------------------------------------------*/
  1342. static int wlanGetDevIdx(struct net_device *prDev)
  1343. {
  1344. int i;
  1345. ASSERT(prDev);
  1346. for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
  1347. if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) {
  1348. /* Reserve 2 bytes space to store one digit of
  1349. * device number and NULL terminator.
  1350. */
  1351. arWlanDevInfo[i].prDev = prDev;
  1352. u4WlanDevNum++;
  1353. return i;
  1354. }
  1355. }
  1356. return -1;
  1357. } /* end of wlanGetDevIdx() */
  1358. /*----------------------------------------------------------------------------*/
  1359. /*!
  1360. * \brief A method of struct net_device, a primary SOCKET interface to configure
  1361. * the interface lively. Handle an ioctl call on one of our devices.
  1362. * Everything Linux ioctl specific is done here. Then we pass the contents
  1363. * of the ifr->data to the request message handler.
  1364. *
  1365. * \param[in] prDev Linux kernel netdevice
  1366. *
  1367. * \param[in] prIFReq Our private ioctl request structure, typed for the generic
  1368. * struct ifreq so we can use ptr to function
  1369. *
  1370. * \param[in] cmd Command ID
  1371. *
  1372. * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
  1373. * \retval OTHER The execution of IOCTL command is failed.
  1374. */
  1375. /*----------------------------------------------------------------------------*/
  1376. int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIFReq, int i4Cmd)
  1377. {
  1378. P_GLUE_INFO_T prGlueInfo = NULL;
  1379. int ret = 0;
  1380. /* Verify input parameters for the following functions */
  1381. ASSERT(prDev && prIFReq);
  1382. if (!prDev || !prIFReq) {
  1383. DBGLOG(INIT, WARN, "%s Invalid input data\n", __func__);
  1384. return -EINVAL;
  1385. }
  1386. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1387. ASSERT(prGlueInfo);
  1388. if (!prGlueInfo) {
  1389. DBGLOG(INIT, WARN, "%s No glue info\n", __func__);
  1390. return -EFAULT;
  1391. }
  1392. if (prGlueInfo->u4ReadyFlag == 0)
  1393. return -EINVAL;
  1394. /* printk ("ioctl %x\n", i4Cmd); */
  1395. if (i4Cmd == SIOCGIWPRIV) {
  1396. /* 0x8B0D, get private ioctl table */
  1397. ret = wext_get_priv(prDev, prIFReq);
  1398. } else if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
  1399. /* 0x8B00 ~ 0x8BDF, wireless extension region */
  1400. ret = wext_support_ioctl(prDev, prIFReq, i4Cmd);
  1401. } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
  1402. /* 0x8BE0 ~ 0x8BFF, private ioctl region */
  1403. ret = priv_support_ioctl(prDev, prIFReq, i4Cmd);
  1404. } else if (i4Cmd == SIOCDEVPRIVATE + 1) {
  1405. ret = priv_support_driver_cmd(prDev, prIFReq, i4Cmd);
  1406. } else {
  1407. DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd);
  1408. /* return 0 for safe? */
  1409. }
  1410. return ret;
  1411. } /* end of wlanDoIOCTL() */
  1412. /*----------------------------------------------------------------------------*/
  1413. /*!
  1414. * \brief This function is to set multicast list and set rx mode.
  1415. *
  1416. * \param[in] prDev Pointer to struct net_device
  1417. *
  1418. * \return (none)
  1419. */
  1420. /*----------------------------------------------------------------------------*/
  1421. static struct delayed_work workq;
  1422. static struct net_device *gPrDev;
  1423. static BOOLEAN fgIsWorkMcStart = FALSE;
  1424. static BOOLEAN fgIsWorkMcEverInit = FALSE;
  1425. static struct wireless_dev *gprWdev;
  1426. #ifdef CONFIG_PM
  1427. static const struct wiphy_wowlan_support wlan_wowlan_support = {
  1428. .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY,
  1429. };
  1430. #endif
  1431. static void createWirelessDevice(void)
  1432. {
  1433. struct wiphy *prWiphy = NULL;
  1434. struct wireless_dev *prWdev = NULL;
  1435. #if CFG_SUPPORT_PERSIST_NETDEV
  1436. struct net_device *prNetDev = NULL;
  1437. #endif
  1438. /* <1.1> Create wireless_dev */
  1439. prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
  1440. if (!prWdev) {
  1441. DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
  1442. return;
  1443. }
  1444. /* <1.2> Create wiphy */
  1445. prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
  1446. if (!prWiphy) {
  1447. DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n");
  1448. goto free_wdev;
  1449. }
  1450. /* <1.3> configure wireless_dev & wiphy */
  1451. prWdev->iftype = NL80211_IFTYPE_STATION;
  1452. prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */
  1453. prWiphy->max_scan_ie_len = 512;
  1454. prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM;
  1455. prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM;
  1456. prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN;
  1457. prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
  1458. prWiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
  1459. /* always assign 5Ghz bands here, if the chip is not support 5Ghz,
  1460. bands[IEEE80211_BAND_5GHZ] will be assign to NULL */
  1461. prWiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
  1462. prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
  1463. prWiphy->cipher_suites = (const u32 *)mtk_cipher_suites;
  1464. prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
  1465. prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM
  1466. | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
  1467. | WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
  1468. prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG;
  1469. #if (CFG_SUPPORT_TDLS == 1)
  1470. TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags);
  1471. #endif /* CFG_SUPPORT_TDLS */
  1472. prWiphy->max_remain_on_channel_duration = 5000;
  1473. prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes;
  1474. prWiphy->vendor_commands = mtk_wlan_vendor_ops;
  1475. prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command);
  1476. prWiphy->vendor_events = mtk_wlan_vendor_events;
  1477. prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events);
  1478. /* <1.4> wowlan support */
  1479. #ifdef CONFIG_PM
  1480. prWiphy->wowlan = &wlan_wowlan_support;
  1481. #endif
  1482. #ifdef CONFIG_CFG80211_WEXT
  1483. /* <1.5> Use wireless extension to replace IOCTL */
  1484. prWiphy->wext = &wext_handler_def;
  1485. #endif
  1486. if (wiphy_register(prWiphy) < 0) {
  1487. DBGLOG(INIT, ERROR, "wiphy_register error\n");
  1488. goto free_wiphy;
  1489. }
  1490. prWdev->wiphy = prWiphy;
  1491. #if CFG_SUPPORT_PERSIST_NETDEV
  1492. /* <2> allocate and register net_device */
  1493. #if CFG_TC1_FEATURE
  1494. if (wlan_if_changed)
  1495. prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE,
  1496. ether_setup, CFG_MAX_TXQ_NUM);
  1497. else
  1498. #else
  1499. prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  1500. ether_setup, CFG_MAX_TXQ_NUM);
  1501. #endif
  1502. if (!prNetDev) {
  1503. DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
  1504. goto unregister_wiphy;
  1505. }
  1506. *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy);
  1507. prNetDev->netdev_ops = &wlan_netdev_ops;
  1508. #ifdef CONFIG_WIRELESS_EXT
  1509. prNetDev->wireless_handlers = &wext_handler_def;
  1510. #endif
  1511. netif_carrier_off(prNetDev);
  1512. netif_tx_stop_all_queues(prNetDev);
  1513. /* <2.1> co-relate with wireless_dev bi-directionally */
  1514. prNetDev->ieee80211_ptr = prWdev;
  1515. prWdev->netdev = prNetDev;
  1516. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1517. prNetDev->features = NETIF_F_HW_CSUM;
  1518. #endif
  1519. /* <2.2> co-relate net device & device tree */
  1520. SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy));
  1521. /* <2.3> register net_device */
  1522. if (register_netdev(prWdev->netdev) < 0) {
  1523. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
  1524. goto unregister_wiphy;
  1525. }
  1526. #endif /* CFG_SUPPORT_PERSIST_NETDEV */
  1527. gprWdev = prWdev;
  1528. DBGLOG(INIT, INFO, "create wireless device success\n");
  1529. return;
  1530. #if CFG_SUPPORT_PERSIST_NETDEV
  1531. unregister_wiphy:
  1532. wiphy_unregister(prWiphy);
  1533. #endif
  1534. free_wiphy:
  1535. wiphy_free(prWiphy);
  1536. free_wdev:
  1537. kfree(prWdev);
  1538. }
  1539. static void destroyWirelessDevice(void)
  1540. {
  1541. #if CFG_SUPPORT_PERSIST_NETDEV
  1542. unregister_netdev(gprWdev->netdev);
  1543. free_netdev(gprWdev->netdev);
  1544. #endif
  1545. wiphy_unregister(gprWdev->wiphy);
  1546. wiphy_free(gprWdev->wiphy);
  1547. kfree(gprWdev);
  1548. gprWdev = NULL;
  1549. }
  1550. static void wlanSetMulticastList(struct net_device *prDev)
  1551. {
  1552. gPrDev = prDev;
  1553. schedule_delayed_work(&workq, 0);
  1554. }
  1555. /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
  1556. * another workqueue for sleeping. We don't want to block
  1557. * tx_thread, so we can't let tx_thread to do this */
  1558. static void wlanSetMulticastListWorkQueue(struct work_struct *work)
  1559. {
  1560. P_GLUE_INFO_T prGlueInfo = NULL;
  1561. UINT_32 u4PacketFilter = 0;
  1562. UINT_32 u4SetInfoLen;
  1563. struct net_device *prDev = gPrDev;
  1564. fgIsWorkMcStart = TRUE;
  1565. DBGLOG(INIT, INFO, "wlanSetMulticastListWorkQueue start...\n");
  1566. if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE))
  1567. return;
  1568. if (kalIsHalted()) {
  1569. fgIsWorkMcStart = FALSE;
  1570. kalHaltUnlock();
  1571. return;
  1572. }
  1573. prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
  1574. ASSERT(prDev);
  1575. ASSERT(prGlueInfo);
  1576. if (!prDev || !prGlueInfo) {
  1577. DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
  1578. fgIsWorkMcStart = FALSE;
  1579. kalHaltUnlock();
  1580. return;
  1581. }
  1582. if (prDev->flags & IFF_PROMISC)
  1583. u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
  1584. if (prDev->flags & IFF_BROADCAST)
  1585. u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
  1586. if (prDev->flags & IFF_MULTICAST) {
  1587. if ((prDev->flags & IFF_ALLMULTI) ||
  1588. (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
  1589. u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
  1590. } else {
  1591. u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
  1592. }
  1593. }
  1594. kalHaltUnlock();
  1595. if (kalIoctl(prGlueInfo,
  1596. wlanoidSetCurrentPacketFilter,
  1597. &u4PacketFilter,
  1598. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  1599. fgIsWorkMcStart = FALSE;
  1600. return;
  1601. }
  1602. if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
  1603. /* Prepare multicast address list */
  1604. struct netdev_hw_addr *ha;
  1605. PUINT_8 prMCAddrList = NULL;
  1606. UINT_32 i = 0;
  1607. if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE))
  1608. return;
  1609. if (kalIsHalted()) {
  1610. fgIsWorkMcStart = FALSE;
  1611. kalHaltUnlock();
  1612. /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/
  1613. return;
  1614. }
  1615. prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
  1616. netdev_for_each_mc_addr(ha, prDev) {
  1617. if (i < MAX_NUM_GROUP_ADDR) {
  1618. memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
  1619. i++;
  1620. }
  1621. }
  1622. kalHaltUnlock();
  1623. kalIoctl(prGlueInfo,
  1624. wlanoidSetMulticastList,
  1625. prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  1626. kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
  1627. }
  1628. fgIsWorkMcStart = FALSE;
  1629. DBGLOG(INIT, INFO, "wlanSetMulticastListWorkQueue end\n");
  1630. } /* end of wlanSetMulticastList() */
  1631. /*----------------------------------------------------------------------------*/
  1632. /*!
  1633. * \brief To indicate scheduled scan has been stopped
  1634. *
  1635. * \param[in]
  1636. * prGlueInfo
  1637. *
  1638. * \return
  1639. * None
  1640. */
  1641. /*----------------------------------------------------------------------------*/
  1642. VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work)
  1643. {
  1644. P_GLUE_INFO_T prGlueInfo = NULL;
  1645. struct net_device *prDev = gPrDev;
  1646. prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
  1647. if (!prGlueInfo) {
  1648. DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n");
  1649. return;
  1650. }
  1651. /* 2. indication to cfg80211 */
  1652. /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */
  1653. cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo));
  1654. DBGLOG(SCN, INFO,
  1655. "cfg80211_sched_scan_stopped event send done\n");
  1656. }
  1657. /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
  1658. * another workqueue for sleeping. We don't want to block
  1659. * tx_thread, so we can't let tx_thread to do this */
  1660. void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo)
  1661. {
  1662. ASSERT(prGlueInfo);
  1663. if (!prGlueInfo) {
  1664. DBGLOG(INIT, WARN, "abnormal dev or skb: prGlueInfo(0x%p)\n", prGlueInfo);
  1665. return;
  1666. }
  1667. #if CFG_ENABLE_WIFI_DIRECT
  1668. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1669. mtk_p2p_wext_set_Multicastlist(prGlueInfo);
  1670. #endif
  1671. } /* end of p2pSetMulticastListWorkQueueWrapper() */
  1672. /*----------------------------------------------------------------------------*/
  1673. /*!
  1674. * \brief This function is TX entry point of NET DEVICE.
  1675. *
  1676. * \param[in] prSkb Pointer of the sk_buff to be sent
  1677. * \param[in] prDev Pointer to struct net_device
  1678. *
  1679. * \retval NETDEV_TX_OK - on success.
  1680. * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
  1681. */
  1682. /*----------------------------------------------------------------------------*/
  1683. int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev)
  1684. {
  1685. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1686. P_QUE_ENTRY_T prQueueEntry = NULL;
  1687. P_QUE_T prTxQueue = NULL;
  1688. UINT_16 u2QueueIdx = 0;
  1689. #if (CFG_SUPPORT_TDLS_DBG == 1)
  1690. UINT16 u2Identifier = 0;
  1691. #endif
  1692. #if CFG_BOW_TEST
  1693. UINT_32 i;
  1694. #endif
  1695. GLUE_SPIN_LOCK_DECLARATION();
  1696. ASSERT(prSkb);
  1697. ASSERT(prDev);
  1698. ASSERT(prGlueInfo);
  1699. #if (CFG_SUPPORT_TDLS_DBG == 1)
  1700. {
  1701. UINT8 *pkt = prSkb->data;
  1702. if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
  1703. /* ip */
  1704. u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
  1705. /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */
  1706. DBGLOG(INIT, INFO, "<s> %d\n", u2Identifier);
  1707. }
  1708. }
  1709. #endif
  1710. /* check if WiFi is halt */
  1711. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  1712. DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n");
  1713. dev_kfree_skb(prSkb);
  1714. return NETDEV_TX_OK;
  1715. }
  1716. #if CFG_SUPPORT_HOTSPOT_2_0
  1717. if (prGlueInfo->fgIsDad) {
  1718. /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */
  1719. dev_kfree_skb(prSkb);
  1720. return NETDEV_TX_OK;
  1721. }
  1722. if (prGlueInfo->fgIs6Dad) {
  1723. /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */
  1724. dev_kfree_skb(prSkb);
  1725. return NETDEV_TX_OK;
  1726. }
  1727. #endif
  1728. STATS_TX_TIME_ARRIVE(prSkb);
  1729. prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
  1730. prTxQueue = &prGlueInfo->rTxQueue;
  1731. #if CFG_BOW_TEST
  1732. DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len);
  1733. DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len);
  1734. DBGLOG(BOW, TRACE, "sk_buff->data:\n");
  1735. for (i = 0; i < prSkb->len; i++) {
  1736. DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
  1737. if ((i + 1) % 16 == 0)
  1738. DBGLOG(BOW, TRACE, "\n");
  1739. }
  1740. DBGLOG(BOW, TRACE, "\n");
  1741. #endif
  1742. if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
  1743. /* non-1x packets */
  1744. #if CFG_DBG_GPIO_PINS
  1745. {
  1746. /* TX request from OS */
  1747. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
  1748. kalUdelay(1);
  1749. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
  1750. }
  1751. #endif
  1752. u2QueueIdx = skb_get_queue_mapping(prSkb);
  1753. ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
  1754. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  1755. GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());
  1756. #endif
  1757. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
  1758. if (u2QueueIdx < CFG_MAX_TXQ_NUM)
  1759. GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
  1760. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1761. QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
  1762. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1763. /* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */
  1764. /* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */
  1765. if (u2QueueIdx < CFG_MAX_TXQ_NUM) {
  1766. if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >=
  1767. CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
  1768. netif_stop_subqueue(prDev, u2QueueIdx);
  1769. #if (CONF_HIF_LOOPBACK_AUTO == 1)
  1770. prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01;
  1771. #endif /* CONF_HIF_LOOPBACK_AUTO */
  1772. }
  1773. }
  1774. } else {
  1775. /* printk("is security frame\n"); */
  1776. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  1777. }
  1778. DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len);
  1779. prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
  1780. prGlueInfo->rNetDevStats.tx_packets++;
  1781. if (netif_carrier_ok(prDev))
  1782. kalPerMonStart(prGlueInfo);
  1783. /* set GLUE_FLAG_TXREQ_BIT */
  1784. /* pr->u4Flag |= GLUE_FLAG_TXREQ; */
  1785. /* wake_up_interruptible(&prGlueInfo->waitq); */
  1786. kalSetEvent(prGlueInfo);
  1787. /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
  1788. return NETDEV_TX_OK;
  1789. } /* end of wlanHardStartXmit() */
  1790. /*----------------------------------------------------------------------------*/
  1791. /*!
  1792. * \brief A method of struct net_device, to get the network interface statistical
  1793. * information.
  1794. *
  1795. * Whenever an application needs to get statistics for the interface, this method
  1796. * is called. This happens, for example, when ifconfig or netstat -i is run.
  1797. *
  1798. * \param[in] prDev Pointer to struct net_device.
  1799. *
  1800. * \return net_device_stats buffer pointer.
  1801. */
  1802. /*----------------------------------------------------------------------------*/
  1803. struct net_device_stats *wlanGetStats(IN struct net_device *prDev)
  1804. {
  1805. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1806. #if 0
  1807. WLAN_STATUS rStatus;
  1808. UINT_32 u4XmitError = 0;
  1809. UINT_32 u4XmitOk = 0;
  1810. UINT_32 u4RecvError = 0;
  1811. UINT_32 u4RecvOk = 0;
  1812. UINT_32 u4BufLen;
  1813. ASSERT(prDev);
  1814. /* @FIX ME: need a more clear way to do this */
  1815. rStatus = kalIoctl(prGlueInfo,
  1816. wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1817. rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1818. rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1819. rStatus = kalIoctl(prGlueInfo,
  1820. wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1821. prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
  1822. prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
  1823. prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
  1824. prGlueInfo->rNetDevStats.rx_errors = u4RecvError;
  1825. /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */
  1826. /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */
  1827. /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */
  1828. /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */
  1829. #endif
  1830. /* prGlueInfo->rNetDevStats.rx_packets = 0; */
  1831. /* prGlueInfo->rNetDevStats.tx_packets = 0; */
  1832. prGlueInfo->rNetDevStats.tx_errors = 0;
  1833. prGlueInfo->rNetDevStats.rx_errors = 0;
  1834. /* prGlueInfo->rNetDevStats.rx_bytes = 0; */
  1835. /* prGlueInfo->rNetDevStats.tx_bytes = 0; */
  1836. prGlueInfo->rNetDevStats.rx_errors = 0;
  1837. prGlueInfo->rNetDevStats.multicast = 0;
  1838. return &prGlueInfo->rNetDevStats;
  1839. } /* end of wlanGetStats() */
  1840. /*----------------------------------------------------------------------------*/
  1841. /*!
  1842. * \brief A function for prDev->init
  1843. *
  1844. * \param[in] prDev Pointer to struct net_device.
  1845. *
  1846. * \retval 0 The execution of wlanInit succeeds.
  1847. * \retval -ENXIO No such device.
  1848. */
  1849. /*----------------------------------------------------------------------------*/
  1850. static int wlanInit(struct net_device *prDev)
  1851. {
  1852. P_GLUE_INFO_T prGlueInfo = NULL;
  1853. if (fgIsWorkMcEverInit == FALSE) {
  1854. if (!prDev)
  1855. return -ENXIO;
  1856. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1857. INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
  1858. /* 20150205 work queue for sched_scan */
  1859. INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue);
  1860. fgIsWorkMcEverInit = TRUE;
  1861. }
  1862. return 0; /* success */
  1863. } /* end of wlanInit() */
  1864. /*----------------------------------------------------------------------------*/
  1865. /*!
  1866. * \brief A function for prDev->uninit
  1867. *
  1868. * \param[in] prDev Pointer to struct net_device.
  1869. *
  1870. * \return (none)
  1871. */
  1872. /*----------------------------------------------------------------------------*/
  1873. static void wlanUninit(struct net_device *prDev)
  1874. {
  1875. } /* end of wlanUninit() */
  1876. /*----------------------------------------------------------------------------*/
  1877. /*!
  1878. * \brief A function for prDev->open
  1879. *
  1880. * \param[in] prDev Pointer to struct net_device.
  1881. *
  1882. * \retval 0 The execution of wlanOpen succeeds.
  1883. * \retval < 0 The execution of wlanOpen failed.
  1884. */
  1885. /*----------------------------------------------------------------------------*/
  1886. static int wlanOpen(struct net_device *prDev)
  1887. {
  1888. ASSERT(prDev);
  1889. netif_tx_start_all_queues(prDev);
  1890. return 0; /* success */
  1891. } /* end of wlanOpen() */
  1892. /*----------------------------------------------------------------------------*/
  1893. /*!
  1894. * \brief A function for prDev->stop
  1895. *
  1896. * \param[in] prDev Pointer to struct net_device.
  1897. *
  1898. * \retval 0 The execution of wlanStop succeeds.
  1899. * \retval < 0 The execution of wlanStop failed.
  1900. */
  1901. /*----------------------------------------------------------------------------*/
  1902. static int wlanStop(struct net_device *prDev)
  1903. {
  1904. P_GLUE_INFO_T prGlueInfo = NULL;
  1905. struct cfg80211_scan_request *prScanRequest = NULL;
  1906. GLUE_SPIN_LOCK_DECLARATION();
  1907. ASSERT(prDev);
  1908. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1909. /* CFG80211 down */
  1910. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1911. if (prGlueInfo->prScanRequest != NULL) {
  1912. prScanRequest = prGlueInfo->prScanRequest;
  1913. prGlueInfo->prScanRequest = NULL;
  1914. }
  1915. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1916. if (prScanRequest)
  1917. cfg80211_scan_done(prScanRequest, TRUE);
  1918. netif_tx_stop_all_queues(prDev);
  1919. return 0; /* success */
  1920. } /* end of wlanStop() */
  1921. /*----------------------------------------------------------------------------*/
  1922. /*!
  1923. * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
  1924. *
  1925. * \param[in] prGlueInfo Pointer to glue info
  1926. *
  1927. * \return none
  1928. */
  1929. /*----------------------------------------------------------------------------*/
  1930. VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo)
  1931. {
  1932. UINT_8 i, j;
  1933. UINT_8 ucNumOfChannel;
  1934. RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
  1935. /* 1. Disable all channel */
  1936. for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
  1937. mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
  1938. mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
  1939. }
  1940. for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
  1941. mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
  1942. mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
  1943. }
  1944. /* 2. Get current domain channel list */
  1945. rlmDomainGetChnlList(prGlueInfo->prAdapter,
  1946. BAND_NULL,
  1947. ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
  1948. &ucNumOfChannel, aucChannelList);
  1949. /* 3. Enable specific channel based on domain channel list */
  1950. for (i = 0; i < ucNumOfChannel; i++) {
  1951. switch (aucChannelList[i].eBand) {
  1952. case BAND_2G4:
  1953. for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) {
  1954. if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
  1955. mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
  1956. mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
  1957. break;
  1958. }
  1959. }
  1960. break;
  1961. case BAND_5G:
  1962. for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) {
  1963. if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
  1964. mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
  1965. mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
  1966. break;
  1967. }
  1968. }
  1969. break;
  1970. default:
  1971. break;
  1972. }
  1973. }
  1974. }
  1975. /*----------------------------------------------------------------------------*/
  1976. /*!
  1977. * \brief Register the device to the kernel and return the index.
  1978. *
  1979. * \param[in] prDev Pointer to struct net_device.
  1980. *
  1981. * \retval 0 The execution of wlanNetRegister succeeds.
  1982. * \retval < 0 The execution of wlanNetRegister failed.
  1983. */
  1984. /*----------------------------------------------------------------------------*/
  1985. static INT_32 wlanNetRegister(struct wireless_dev *prWdev)
  1986. {
  1987. P_GLUE_INFO_T prGlueInfo;
  1988. INT_32 i4DevIdx = -1;
  1989. ASSERT(prWdev);
  1990. do {
  1991. if (!prWdev)
  1992. break;
  1993. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  1994. i4DevIdx = wlanGetDevIdx(prWdev->netdev);
  1995. if (i4DevIdx < 0) {
  1996. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n");
  1997. break;
  1998. }
  1999. /* adjust channel support status */
  2000. wlanUpdateChannelTable(prGlueInfo);
  2001. #if !CFG_SUPPORT_PERSIST_NETDEV
  2002. if (register_netdev(prWdev->netdev) < 0) {
  2003. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
  2004. wiphy_unregister(prWdev->wiphy);
  2005. wlanClearDevIdx(prWdev->netdev);
  2006. i4DevIdx = -1;
  2007. }
  2008. #endif
  2009. if (i4DevIdx != -1)
  2010. prGlueInfo->fgIsRegistered = TRUE;
  2011. } while (FALSE);
  2012. return i4DevIdx; /* success */
  2013. } /* end of wlanNetRegister() */
  2014. /*----------------------------------------------------------------------------*/
  2015. /*!
  2016. * \brief Unregister the device from the kernel
  2017. *
  2018. * \param[in] prWdev Pointer to struct net_device.
  2019. *
  2020. * \return (none)
  2021. */
  2022. /*----------------------------------------------------------------------------*/
  2023. static VOID wlanNetUnregister(struct wireless_dev *prWdev)
  2024. {
  2025. P_GLUE_INFO_T prGlueInfo;
  2026. if (!prWdev) {
  2027. DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n");
  2028. return;
  2029. }
  2030. DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev);
  2031. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2032. wlanClearDevIdx(prWdev->netdev);
  2033. #if !CFG_SUPPORT_PERSIST_NETDEV
  2034. unregister_netdev(prWdev->netdev);
  2035. #endif
  2036. prGlueInfo->fgIsRegistered = FALSE;
  2037. DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex);
  2038. } /* end of wlanNetUnregister() */
  2039. static const struct net_device_ops wlan_netdev_ops = {
  2040. .ndo_open = wlanOpen,
  2041. .ndo_stop = wlanStop,
  2042. .ndo_set_rx_mode = wlanSetMulticastList,
  2043. .ndo_get_stats = wlanGetStats,
  2044. .ndo_do_ioctl = wlanDoIOCTL,
  2045. .ndo_start_xmit = wlanHardStartXmit,
  2046. .ndo_init = wlanInit,
  2047. .ndo_uninit = wlanUninit,
  2048. .ndo_select_queue = wlanSelectQueue,
  2049. };
  2050. /*----------------------------------------------------------------------------*/
  2051. /*!
  2052. * \brief A method for creating Linux NET4 struct net_device object and the
  2053. * private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
  2054. * Assign the function pointer to the net_device object
  2055. *
  2056. * \param[in] pvData Memory address for the device
  2057. *
  2058. * \retval Not null The wireless_dev object.
  2059. * \retval NULL Fail to create wireless_dev object
  2060. */
  2061. /*----------------------------------------------------------------------------*/
  2062. static struct lock_class_key rSpinKey[SPIN_LOCK_NUM];
  2063. static struct wireless_dev *wlanNetCreate(PVOID pvData)
  2064. {
  2065. P_GLUE_INFO_T prGlueInfo = NULL;
  2066. struct wireless_dev *prWdev = gprWdev;
  2067. UINT_32 i;
  2068. struct device *prDev;
  2069. if (!prWdev) {
  2070. DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
  2071. return NULL;
  2072. }
  2073. /* 4 <1> co-relate wiphy & prDev */
  2074. #if MTK_WCN_HIF_SDIO
  2075. mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev);
  2076. #else
  2077. /* prDev = &((struct sdio_func *) pvData)->dev; //samp */
  2078. prDev = pvData; /* samp */
  2079. #endif
  2080. if (!prDev)
  2081. DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n");
  2082. /* don't set prDev as parent of wiphy->dev, because we have done device_add
  2083. in driver init. if we set parent here, parent will be not able to know this child,
  2084. and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent
  2085. has been freed. */
  2086. /*set_wiphy_dev(prWdev->wiphy, prDev);*/
  2087. #if !CFG_SUPPORT_PERSIST_NETDEV
  2088. /* 4 <3> Initial Glue structure */
  2089. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2090. kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T));
  2091. /* 4 <3.1> Create net device */
  2092. #if CFG_TC1_FEATURE
  2093. if (wlan_if_changed) {
  2094. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE,
  2095. NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
  2096. } else {
  2097. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  2098. ether_setup, CFG_MAX_TXQ_NUM);
  2099. }
  2100. #else
  2101. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  2102. ether_setup, CFG_MAX_TXQ_NUM);
  2103. #endif
  2104. if (!prGlueInfo->prDevHandler) {
  2105. DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
  2106. return NULL;
  2107. }
  2108. DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n",
  2109. prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex);
  2110. /* 4 <3.1.1> initialize net device varaiables */
  2111. *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
  2112. prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
  2113. #ifdef CONFIG_WIRELESS_EXT
  2114. prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
  2115. #endif
  2116. netif_carrier_off(prGlueInfo->prDevHandler);
  2117. netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
  2118. /* 4 <3.1.2> co-relate with wiphy bi-directionally */
  2119. prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
  2120. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2121. prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM;
  2122. #endif
  2123. prWdev->netdev = prGlueInfo->prDevHandler;
  2124. /* 4 <3.1.3> co-relate net device & prDev */
  2125. /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/
  2126. SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev);
  2127. #else /* CFG_SUPPORT_PERSIST_NETDEV */
  2128. prGlueInfo->prDevHandler = gprWdev->netdev;
  2129. #endif /* CFG_SUPPORT_PERSIST_NETDEV */
  2130. /* 4 <3.2> initiali glue variables */
  2131. prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
  2132. prGlueInfo->ePowerState = ParamDeviceStateD0;
  2133. prGlueInfo->fgIsMacAddrOverride = FALSE;
  2134. prGlueInfo->fgIsRegistered = FALSE;
  2135. prGlueInfo->prScanRequest = NULL;
  2136. #if CFG_SUPPORT_HOTSPOT_2_0
  2137. /* Init DAD */
  2138. prGlueInfo->fgIsDad = FALSE;
  2139. prGlueInfo->fgIs6Dad = FALSE;
  2140. kalMemZero(prGlueInfo->aucDADipv4, 4);
  2141. kalMemZero(prGlueInfo->aucDADipv6, 16);
  2142. #endif
  2143. init_completion(&prGlueInfo->rScanComp);
  2144. init_completion(&prGlueInfo->rHaltComp);
  2145. init_completion(&prGlueInfo->rPendComp);
  2146. #if CFG_ENABLE_WIFI_DIRECT
  2147. init_completion(&prGlueInfo->rSubModComp);
  2148. #endif
  2149. /* initialize timer for OID timeout checker */
  2150. kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
  2151. for (i = 0; i < SPIN_LOCK_NUM; i++) {
  2152. spin_lock_init(&prGlueInfo->rSpinLock[i]);
  2153. lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]);
  2154. }
  2155. /* initialize semaphore for ioctl */
  2156. sema_init(&prGlueInfo->ioctl_sem, 1);
  2157. glSetHifInfo(prGlueInfo, (ULONG) pvData);
  2158. /* 4 <8> Init Queues */
  2159. init_waitqueue_head(&prGlueInfo->waitq);
  2160. QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
  2161. QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
  2162. /* 4 <4> Create Adapter structure */
  2163. prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
  2164. if (!prGlueInfo->prAdapter) {
  2165. DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n");
  2166. return NULL;
  2167. }
  2168. KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR");
  2169. #if CFG_SUPPORT_PERSIST_NETDEV
  2170. dev_open(prGlueInfo->prDevHandler);
  2171. netif_carrier_off(prGlueInfo->prDevHandler);
  2172. netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
  2173. #endif
  2174. return prWdev;
  2175. } /* end of wlanNetCreate() */
  2176. /*----------------------------------------------------------------------------*/
  2177. /*!
  2178. * \brief Destroying the struct net_device object and the private data.
  2179. *
  2180. * \param[in] prWdev Pointer to struct wireless_dev.
  2181. *
  2182. * \return (none)
  2183. */
  2184. /*----------------------------------------------------------------------------*/
  2185. static VOID wlanNetDestroy(struct wireless_dev *prWdev)
  2186. {
  2187. P_GLUE_INFO_T prGlueInfo = NULL;
  2188. ASSERT(prWdev);
  2189. if (!prWdev) {
  2190. DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n");
  2191. return;
  2192. }
  2193. /* prGlueInfo is allocated with net_device */
  2194. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2195. ASSERT(prGlueInfo);
  2196. /* destroy kal OS timer */
  2197. kalCancelTimer(prGlueInfo);
  2198. glClearHifInfo(prGlueInfo);
  2199. wlanAdapterDestroy(prGlueInfo->prAdapter);
  2200. prGlueInfo->prAdapter = NULL;
  2201. #if CFG_SUPPORT_PERSIST_NETDEV
  2202. /* take the net_device to down state */
  2203. dev_close(prGlueInfo->prDevHandler);
  2204. #else
  2205. /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */
  2206. free_netdev(prWdev->netdev);
  2207. #endif
  2208. } /* end of wlanNetDestroy() */
  2209. #ifndef CONFIG_X86
  2210. UINT_8 g_aucBufIpAddr[32] = { 0 };
  2211. static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend)
  2212. {
  2213. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2214. UINT_32 u4SetInfoLen;
  2215. rStatus = kalIoctl(prGlueInfo,
  2216. wlanoidNotifyFwSuspend,
  2217. (PVOID)&fgSuspend,
  2218. sizeof(fgSuspend),
  2219. FALSE,
  2220. FALSE,
  2221. TRUE,
  2222. FALSE,
  2223. &u4SetInfoLen);
  2224. if (rStatus != WLAN_STATUS_SUCCESS)
  2225. DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n");
  2226. }
  2227. void wlanHandleSystemSuspend(void)
  2228. {
  2229. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2230. struct net_device *prDev = NULL;
  2231. P_GLUE_INFO_T prGlueInfo = NULL;
  2232. UINT_8 ip[4] = { 0 };
  2233. UINT_32 u4NumIPv4 = 0;
  2234. #ifdef CONFIG_IPV6
  2235. UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
  2236. UINT_32 u4NumIPv6 = 0;
  2237. #endif
  2238. UINT_32 i;
  2239. P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
  2240. #if CFG_SUPPORT_DROP_MC_PACKET
  2241. UINT_32 u4PacketFilter = 0;
  2242. UINT_32 u4SetInfoLen = 0;
  2243. #endif
  2244. /* <1> Sanity check and acquire the net_device */
  2245. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  2246. if (u4WlanDevNum == 0) {
  2247. DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n");
  2248. return;
  2249. }
  2250. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  2251. fgIsUnderSuspend = true;
  2252. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  2253. ASSERT(prGlueInfo);
  2254. #if CFG_SUPPORT_DROP_MC_PACKET
  2255. /* new filter should not include p2p mask */
  2256. #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
  2257. u4PacketFilter = prGlueInfo->prAdapter->u4OsPacketFilter & (~PARAM_PACKET_FILTER_P2P_MASK);
  2258. #endif
  2259. if (kalIoctl(prGlueInfo,
  2260. wlanoidSetCurrentPacketFilter,
  2261. &u4PacketFilter,
  2262. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  2263. DBGLOG(INIT, ERROR, "set packet filter failed.\n");
  2264. }
  2265. #endif
  2266. if (!prDev || !(prDev->ip_ptr) ||
  2267. !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
  2268. !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
  2269. goto notify_suspend;
  2270. }
  2271. kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
  2272. /* todo: traverse between list to find whole sets of IPv4 addresses */
  2273. if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
  2274. u4NumIPv4++;
  2275. #ifdef CONFIG_IPV6
  2276. if (!prDev || !(prDev->ip6_ptr) ||
  2277. !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
  2278. !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
  2279. goto notify_suspend;
  2280. }
  2281. kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
  2282. DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
  2283. ip6[0], ip6[1], ip6[2], ip6[3],
  2284. ip6[4], ip6[5], ip6[6], ip6[7],
  2285. ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
  2286. );
  2287. /* todo: traverse between list to find whole sets of IPv6 addresses */
  2288. if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) {
  2289. /* Do nothing */
  2290. /* u4NumIPv6++; */
  2291. }
  2292. #endif
  2293. /* <7> set up the ARP filter */
  2294. {
  2295. UINT_32 u4SetInfoLen = 0;
  2296. UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
  2297. P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
  2298. P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
  2299. kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
  2300. prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
  2301. prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2302. for (i = 0; i < u4NumIPv4; i++) {
  2303. prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */
  2304. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2305. prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
  2306. kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
  2307. prParamNetAddr =
  2308. (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
  2309. u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
  2310. }
  2311. #ifdef CONFIG_IPV6
  2312. for (i = 0; i < u4NumIPv6; i++) {
  2313. prParamNetAddr->u2AddressLength = 6;
  2314. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2315. kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
  2316. prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6));
  2317. u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
  2318. }
  2319. #endif
  2320. ASSERT(u4Len <= sizeof(g_aucBufIpAddr));
  2321. rStatus = kalIoctl(prGlueInfo,
  2322. wlanoidSetNetworkAddress,
  2323. (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2324. }
  2325. notify_suspend:
  2326. DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus);
  2327. /* if (rStatus != WLAN_STATUS_SUCCESS) */
  2328. wlanNotifyFwSuspend(prGlueInfo, TRUE);
  2329. }
  2330. void wlanHandleSystemResume(void)
  2331. {
  2332. struct net_device *prDev = NULL;
  2333. P_GLUE_INFO_T prGlueInfo = NULL;
  2334. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2335. UINT_8 ip[4] = { 0 };
  2336. #ifdef CONFIG_IPV6
  2337. UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
  2338. #endif
  2339. EVENT_AIS_BSS_INFO_T rParam;
  2340. UINT_32 u4BufLen = 0;
  2341. #if CFG_SUPPORT_DROP_MC_PACKET
  2342. UINT_32 u4PacketFilter = 0;
  2343. UINT_32 u4SetInfoLen = 0;
  2344. #endif
  2345. /* <1> Sanity check and acquire the net_device */
  2346. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  2347. if (u4WlanDevNum == 0) {
  2348. DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n");
  2349. return;
  2350. }
  2351. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  2352. /* ASSERT(prDev); */
  2353. fgIsUnderSuspend = false;
  2354. if (!prDev) {
  2355. DBGLOG(INIT, INFO, "prDev == NULL!!!\n");
  2356. return;
  2357. }
  2358. /* <3> acquire the prGlueInfo */
  2359. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  2360. ASSERT(prGlueInfo);
  2361. #if CFG_SUPPORT_DROP_MC_PACKET
  2362. /* new filter should not include p2p mask */
  2363. #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
  2364. u4PacketFilter = prGlueInfo->prAdapter->u4OsPacketFilter & (~PARAM_PACKET_FILTER_P2P_MASK);
  2365. #endif
  2366. if (kalIoctl(prGlueInfo,
  2367. wlanoidSetCurrentPacketFilter,
  2368. &u4PacketFilter,
  2369. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  2370. DBGLOG(INIT, ERROR, "set packet filter failed.\n");
  2371. }
  2372. #endif
  2373. /*
  2374. We will receive the event in rx, we will check if the status is the same in driver
  2375. and FW, if not the same, trigger disconnetion procedure.
  2376. */
  2377. kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T));
  2378. rStatus = kalIoctl(prGlueInfo,
  2379. wlanoidQueryBSSInfo,
  2380. &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
  2381. if (rStatus != WLAN_STATUS_SUCCESS) {
  2382. DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus);
  2383. }
  2384. /* <2> get the IPv4 address */
  2385. if (!(prDev->ip_ptr) ||
  2386. !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
  2387. !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
  2388. goto notify_resume;
  2389. }
  2390. /* <4> copy the IPv4 address */
  2391. kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
  2392. #ifdef CONFIG_IPV6
  2393. /* <5> get the IPv6 address */
  2394. if (!prDev || !(prDev->ip6_ptr) ||
  2395. !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
  2396. !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
  2397. goto notify_resume;
  2398. }
  2399. /* <6> copy the IPv6 address */
  2400. kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
  2401. DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
  2402. ip6[0], ip6[1], ip6[2], ip6[3],
  2403. ip6[4], ip6[5], ip6[6], ip6[7],
  2404. ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
  2405. );
  2406. #endif
  2407. /* <7> clear the ARP filter */
  2408. {
  2409. UINT_32 u4SetInfoLen = 0;
  2410. /* UINT_8 aucBuf[32] = {0}; */
  2411. UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
  2412. P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
  2413. /* aucBuf; */
  2414. kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
  2415. prParamNetAddrList->u4AddressCount = 0;
  2416. prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2417. ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
  2418. rStatus = kalIoctl(prGlueInfo,
  2419. wlanoidSetNetworkAddress,
  2420. (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2421. }
  2422. notify_resume:
  2423. DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n",
  2424. rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive,
  2425. ip[0], ip[1], ip[2], ip[3], rStatus);
  2426. /* if (rStatus != WLAN_STATUS_SUCCESS) */
  2427. wlanNotifyFwSuspend(prGlueInfo, FALSE);
  2428. }
  2429. #endif /* ! CONFIG_X86 */
  2430. int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode)
  2431. {
  2432. #if 0
  2433. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
  2434. PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
  2435. WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
  2436. UINT_32 u4BufLen = 0;
  2437. rSetP2P.u4Enable = p2pmode.u4Enable;
  2438. rSetP2P.u4Mode = p2pmode.u4Mode;
  2439. if (!rSetP2P.u4Enable)
  2440. p2pNetUnregister(prGlueInfo, TRUE);
  2441. rWlanStatus = kalIoctl(prGlueInfo,
  2442. wlanoidSetP2pMode,
  2443. (PVOID) &rSetP2P,
  2444. sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  2445. DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus);
  2446. if (rSetP2P.u4Enable)
  2447. p2pNetRegister(prGlueInfo, TRUE);
  2448. return 0;
  2449. #else
  2450. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
  2451. PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
  2452. WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
  2453. BOOLEAN fgIsP2PEnding;
  2454. UINT_32 u4BufLen = 0;
  2455. GLUE_SPIN_LOCK_DECLARATION();
  2456. DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode);
  2457. /* avoid remove & p2p off command simultaneously */
  2458. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2459. fgIsP2PEnding = g_u4P2PEnding;
  2460. g_u4P2POnOffing = 1;
  2461. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2462. if (fgIsP2PEnding == 1) {
  2463. /* skip the command if we are removing */
  2464. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2465. g_u4P2POnOffing = 0;
  2466. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2467. return 0;
  2468. }
  2469. rSetP2P.u4Enable = p2pmode.u4Enable;
  2470. rSetP2P.u4Mode = p2pmode.u4Mode;
  2471. #if !CFG_SUPPORT_PERSIST_NETDEV
  2472. if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE))
  2473. p2pNetUnregister(prGlueInfo, TRUE);
  2474. #endif
  2475. /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */
  2476. /*
  2477. Scenario:
  2478. 1. System enters suspend/resume but not yet enter wlanearlysuspend()
  2479. or wlanlateresume();
  2480. 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl()
  2481. and get g_halt_sem then do glRegisterEarlySuspend() or
  2482. glUnregisterEarlySuspend();
  2483. But system suspend/resume procedure is not yet finished so we
  2484. suspend;
  2485. 3. System switches back to do suspend/resume procedure and execute
  2486. kalIoctl(). But driver does not yet release g_halt_sem so system
  2487. suspend in wlanearlysuspend() or wlanlateresume();
  2488. ==> deadlock occurs.
  2489. */
  2490. rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */
  2491. sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  2492. #if !CFG_SUPPORT_PERSIST_NETDEV
  2493. /* Need to check fgIsP2PRegistered, in case of whole chip reset.
  2494. * in this case, kalIOCTL return success always,
  2495. * and prGlueInfo->prP2pInfo may be NULL */
  2496. if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE))
  2497. p2pNetRegister(prGlueInfo, TRUE);
  2498. #endif
  2499. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2500. g_u4P2POnOffing = 0;
  2501. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2502. return 0;
  2503. #endif
  2504. }
  2505. static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM])
  2506. {
  2507. kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule));
  2508. kalPrint("[wlan] change debug level");
  2509. }
  2510. /*----------------------------------------------------------------------------*/
  2511. /*!
  2512. * \brief Wlan probe function. This function probes and initializes the device.
  2513. *
  2514. * \param[in] pvData data passed by bus driver init function
  2515. * _HIF_EHPI: NULL
  2516. * _HIF_SDIO: sdio bus driver handle
  2517. *
  2518. * \retval 0 Success
  2519. * \retval negative value Failed
  2520. */
  2521. /*----------------------------------------------------------------------------*/
  2522. static INT_32 wlanProbe(PVOID pvData)
  2523. {
  2524. struct wireless_dev *prWdev = NULL;
  2525. enum probe_fail_reason {
  2526. BUS_INIT_FAIL,
  2527. NET_CREATE_FAIL,
  2528. BUS_SET_IRQ_FAIL,
  2529. ADAPTER_START_FAIL,
  2530. NET_REGISTER_FAIL,
  2531. PROC_INIT_FAIL,
  2532. FAIL_REASON_NUM
  2533. } eFailReason;
  2534. P_WLANDEV_INFO_T prWlandevInfo = NULL;
  2535. INT_32 i4DevIdx = 0;
  2536. P_GLUE_INFO_T prGlueInfo = NULL;
  2537. P_ADAPTER_T prAdapter = NULL;
  2538. INT_32 i4Status = 0;
  2539. BOOLEAN bRet = FALSE;
  2540. eFailReason = FAIL_REASON_NUM;
  2541. do {
  2542. /* 4 <1> Initialize the IO port of the interface */
  2543. /* GeorgeKuo: pData has different meaning for _HIF_XXX:
  2544. * _HIF_EHPI: pointer to memory base variable, which will be
  2545. * initialized by glBusInit().
  2546. * _HIF_SDIO: bus driver handle
  2547. */
  2548. bRet = glBusInit(pvData);
  2549. wlanDebugInit();
  2550. /* Cannot get IO address from interface */
  2551. if (FALSE == bRet) {
  2552. DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n");
  2553. i4Status = -EIO;
  2554. eFailReason = BUS_INIT_FAIL;
  2555. break;
  2556. }
  2557. /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */
  2558. prWdev = wlanNetCreate(pvData);
  2559. if (prWdev == NULL) {
  2560. DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n");
  2561. i4Status = -ENOMEM;
  2562. eFailReason = NET_CREATE_FAIL;
  2563. break;
  2564. }
  2565. /* 4 <2.5> Set the ioaddr to HIF Info */
  2566. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2567. gPrDev = prGlueInfo->prDevHandler;
  2568. /* 4 <4> Setup IRQ */
  2569. prWlandevInfo = &arWlanDevInfo[i4DevIdx];
  2570. i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2571. if (i4Status != WLAN_STATUS_SUCCESS) {
  2572. DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n");
  2573. eFailReason = BUS_SET_IRQ_FAIL;
  2574. break;
  2575. }
  2576. prGlueInfo->i4DevIdx = i4DevIdx;
  2577. prAdapter = prGlueInfo->prAdapter;
  2578. prGlueInfo->u4ReadyFlag = 0;
  2579. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2580. prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
  2581. #endif
  2582. #if CFG_SUPPORT_CFG_FILE
  2583. {
  2584. PUINT_8 pucConfigBuf;
  2585. UINT_32 u4ConfigReadLen;
  2586. wlanCfgInit(prAdapter, NULL, 0, 0);
  2587. pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE);
  2588. u4ConfigReadLen = 0;
  2589. DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n");
  2590. if (pucConfigBuf) {
  2591. kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE);
  2592. if (kalReadToFile("/data/misc/wifi.cfg",
  2593. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2594. DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n");
  2595. } else if (kalReadToFile("/data/misc/wifi/wifi.cfg",
  2596. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2597. DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n");
  2598. } else if (kalReadToFile("/etc/firmware/wifi.cfg",
  2599. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2600. DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n");
  2601. }
  2602. if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0)
  2603. wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0);
  2604. kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE);
  2605. } /* pucConfigBuf */
  2606. }
  2607. #endif
  2608. /* 4 <5> Start Device */
  2609. /* */
  2610. #if CFG_ENABLE_FW_DOWNLOAD
  2611. DBGLOG(INIT, TRACE, "start to download firmware...\n");
  2612. /* before start adapter, we need to open and load firmware */
  2613. {
  2614. UINT_32 u4FwSize = 0;
  2615. PVOID prFwBuffer = NULL;
  2616. P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
  2617. /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
  2618. kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
  2619. prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
  2620. prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS;
  2621. /* Load NVRAM content to REG_INFO_T */
  2622. glLoadNvram(prGlueInfo, prRegInfo);
  2623. #if CFG_SUPPORT_CFG_FILE
  2624. wlanCfgApply(prAdapter);
  2625. #endif
  2626. /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */
  2627. prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
  2628. prRegInfo->fgEnArpFilter = TRUE;
  2629. if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
  2630. i4Status = -EIO;
  2631. DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n");
  2632. goto bailout;
  2633. } else {
  2634. if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer,
  2635. u4FwSize) != WLAN_STATUS_SUCCESS) {
  2636. i4Status = -EIO;
  2637. }
  2638. }
  2639. kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
  2640. bailout:
  2641. /* kfree(prRegInfo); */
  2642. DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status);
  2643. if (i4Status < 0) {
  2644. GL_HIF_INFO_T *HifInfo;
  2645. UINT_32 u4FwCnt;
  2646. DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n");
  2647. HifInfo = &prAdapter->prGlueInfo->rHifInfo;
  2648. for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
  2649. DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
  2650. /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */
  2651. /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */
  2652. /* dump HIF register may be hung */
  2653. if (!fgIsBusAccessFailed)
  2654. HifRegDump(prGlueInfo->prAdapter);
  2655. /* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */
  2656. /* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */
  2657. eFailReason = ADAPTER_START_FAIL;
  2658. break;
  2659. }
  2660. }
  2661. #else
  2662. /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
  2663. kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
  2664. P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
  2665. /* Load NVRAM content to REG_INFO_T */
  2666. glLoadNvram(prGlueInfo, prRegInfo);
  2667. prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
  2668. if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
  2669. i4Status = -EIO;
  2670. eFailReason = ADAPTER_START_FAIL;
  2671. break;
  2672. }
  2673. #endif
  2674. if (FALSE == prAdapter->fgEnable5GBand)
  2675. prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
  2676. else
  2677. prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
  2678. prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
  2679. kalSetHalted(FALSE);
  2680. #if CFG_SUPPORT_ROAMING_ENC
  2681. /* adjust roaming threshold */
  2682. {
  2683. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2684. CMD_ROAMING_INFO_T rRoamingInfo;
  2685. UINT_32 u4SetInfoLen = 0;
  2686. prAdapter->fgIsRoamingEncEnabled = TRUE;
  2687. /* suggestion from Tsaiyuan.Hsu */
  2688. kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T));
  2689. rRoamingInfo.fgIsFastRoamingApplied = TRUE;
  2690. DBGLOG(INIT, TRACE, "Enable roaming enhance function\n");
  2691. rStatus = kalIoctl(prGlueInfo,
  2692. wlanoidSetRoamingInfo,
  2693. &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
  2694. if (rStatus != WLAN_STATUS_SUCCESS)
  2695. DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus);
  2696. }
  2697. #endif /* CFG_SUPPORT_ROAMING_ENC */
  2698. #if (CFG_SUPPORT_TXR_ENC == 1)
  2699. /* adjust tx rate switch threshold */
  2700. rlmTxRateEnhanceConfig(prGlueInfo->prAdapter);
  2701. #endif /* CFG_SUPPORT_TXR_ENC */
  2702. /* set MAC address */
  2703. {
  2704. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2705. struct sockaddr MacAddr;
  2706. UINT_32 u4SetInfoLen = 0;
  2707. kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data));
  2708. rStatus = kalIoctl(prGlueInfo,
  2709. wlanoidQueryCurrentAddr,
  2710. &MacAddr.sa_data,
  2711. PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
  2712. if (rStatus != WLAN_STATUS_SUCCESS) {
  2713. DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus);
  2714. prGlueInfo->u4ReadyFlag = 0;
  2715. } else {
  2716. ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data));
  2717. ether_addr_copy(prGlueInfo->prDevHandler->perm_addr,
  2718. prGlueInfo->prDevHandler->dev_addr);
  2719. /* card is ready */
  2720. prGlueInfo->u4ReadyFlag = 1;
  2721. #if CFG_SHOW_MACADDR_SOURCE
  2722. DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data));
  2723. #endif
  2724. }
  2725. }
  2726. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2727. /* set HW checksum offload */
  2728. {
  2729. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2730. UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
  2731. UINT_32 u4SetInfoLen = 0;
  2732. rStatus = kalIoctl(prGlueInfo,
  2733. wlanoidSetCSUMOffload,
  2734. (PVOID) &u4CSUMFlags,
  2735. sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2736. if (rStatus != WLAN_STATUS_SUCCESS)
  2737. DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus);
  2738. }
  2739. #endif
  2740. /* 4 <3> Register the card */
  2741. DBGLOG(INIT, TRACE, "wlanNetRegister...\n");
  2742. i4DevIdx = wlanNetRegister(prWdev);
  2743. if (i4DevIdx < 0) {
  2744. i4Status = -ENXIO;
  2745. DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n");
  2746. eFailReason = NET_REGISTER_FAIL;
  2747. break;
  2748. }
  2749. wlanRegisterNotifier();
  2750. /* 4 <6> Initialize /proc filesystem */
  2751. #ifdef WLAN_INCLUDE_PROC
  2752. DBGLOG(INIT, TRACE, "init procfs...\n");
  2753. i4Status = procCreateFsEntry(prGlueInfo);
  2754. if (i4Status < 0) {
  2755. DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n");
  2756. eFailReason = PROC_INIT_FAIL;
  2757. break;
  2758. }
  2759. #endif /* WLAN_INCLUDE_PROC */
  2760. #if CFG_ENABLE_BT_OVER_WIFI
  2761. prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
  2762. prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
  2763. glRegisterAmpc(prGlueInfo);
  2764. #endif
  2765. #if CFG_ENABLE_WIFI_DIRECT
  2766. DBGLOG(INIT, TRACE, "wlanSubModInit...\n");
  2767. /* wlan is launched */
  2768. prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
  2769. /* if p2p module is inserted, notify tx_thread to init p2p network */
  2770. if (rSubModHandler[P2P_MODULE].subModInit)
  2771. wlanSubModInit(prGlueInfo);
  2772. /* register set_p2p_mode handler to mtk_wmt_wifi */
  2773. register_set_p2p_mode_handler(set_p2p_mode_handler);
  2774. #endif
  2775. #if CFG_SPM_WORKAROUND_FOR_HOTSPOT
  2776. if (glIsChipNeedWakelock(prGlueInfo))
  2777. KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP");
  2778. #endif
  2779. } while (FALSE);
  2780. if (i4Status != WLAN_STATUS_SUCCESS) {
  2781. switch (eFailReason) {
  2782. case PROC_INIT_FAIL:
  2783. wlanNetUnregister(prWdev);
  2784. set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
  2785. /* wake up main thread */
  2786. wake_up_interruptible(&prGlueInfo->waitq);
  2787. /* wait main thread stops */
  2788. wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
  2789. KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
  2790. wlanAdapterStop(prAdapter);
  2791. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2792. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2793. wlanNetDestroy(prWdev);
  2794. break;
  2795. case NET_REGISTER_FAIL:
  2796. set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
  2797. /* wake up main thread */
  2798. wake_up_interruptible(&prGlueInfo->waitq);
  2799. /* wait main thread stops */
  2800. wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
  2801. KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
  2802. wlanAdapterStop(prAdapter);
  2803. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2804. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2805. wlanNetDestroy(prWdev);
  2806. break;
  2807. case ADAPTER_START_FAIL:
  2808. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2809. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2810. wlanNetDestroy(prWdev);
  2811. break;
  2812. case BUS_SET_IRQ_FAIL:
  2813. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2814. wlanNetDestroy(prWdev);
  2815. break;
  2816. case NET_CREATE_FAIL:
  2817. break;
  2818. case BUS_INIT_FAIL:
  2819. break;
  2820. default:
  2821. break;
  2822. }
  2823. }
  2824. #if CFG_ENABLE_WIFI_DIRECT
  2825. {
  2826. GLUE_SPIN_LOCK_DECLARATION();
  2827. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2828. g_u4P2PEnding = 0;
  2829. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2830. }
  2831. #endif
  2832. #if CFG_SUPPORT_AGPS_ASSIST
  2833. if (i4Status == WLAN_STATUS_SUCCESS)
  2834. kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0);
  2835. #endif
  2836. #if (CFG_SUPPORT_MET_PROFILING == 1)
  2837. {
  2838. int iMetInitRet = WLAN_STATUS_FAILURE;
  2839. if (i4Status == WLAN_STATUS_SUCCESS) {
  2840. DBGLOG(INIT, TRACE, "init MET procfs...\n");
  2841. iMetInitRet = kalMetInitProcfs(prGlueInfo);
  2842. if (iMetInitRet < 0)
  2843. DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n");
  2844. }
  2845. }
  2846. #endif
  2847. if (i4Status == WLAN_STATUS_SUCCESS) {
  2848. /*Init performance monitor structure */
  2849. kalPerMonInit(prGlueInfo);
  2850. /* probe ok */
  2851. DBGLOG(INIT, TRACE, "wlanProbe ok\n");
  2852. } else {
  2853. /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag,
  2854. * because even this function returns
  2855. * error, we can also call core dump but only core dump failed. */
  2856. if (g_IsNeedDoChipReset)
  2857. mtk_wcn_set_connsys_power_off_flag(0);
  2858. /* probe failed */
  2859. DBGLOG(INIT, ERROR, "wlanProbe failed\n");
  2860. }
  2861. return i4Status;
  2862. } /* end of wlanProbe() */
  2863. /*----------------------------------------------------------------------------*/
  2864. /*!
  2865. * \brief A method to stop driver operation and release all resources. Following
  2866. * this call, no frame should go up or down through this interface.
  2867. *
  2868. * \return (none)
  2869. */
  2870. /*----------------------------------------------------------------------------*/
  2871. static VOID wlanRemove(VOID)
  2872. {
  2873. #define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000
  2874. struct net_device *prDev = NULL;
  2875. P_WLANDEV_INFO_T prWlandevInfo = NULL;
  2876. P_GLUE_INFO_T prGlueInfo = NULL;
  2877. P_ADAPTER_T prAdapter = NULL;
  2878. DBGLOG(INIT, LOUD, "Remove wlan!\n");
  2879. /* 4 <0> Sanity check */
  2880. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  2881. if (0 == u4WlanDevNum) {
  2882. DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n");
  2883. return;
  2884. }
  2885. /* unregister set_p2p_mode handler to mtk_wmt_wifi */
  2886. register_set_p2p_mode_handler(NULL);
  2887. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  2888. prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1];
  2889. ASSERT(prDev);
  2890. if (NULL == prDev) {
  2891. DBGLOG(INIT, ERROR, "NULL == prDev\n");
  2892. return;
  2893. }
  2894. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  2895. ASSERT(prGlueInfo);
  2896. if (NULL == prGlueInfo) {
  2897. DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n");
  2898. free_netdev(prDev);
  2899. return;
  2900. }
  2901. kalPerMonDestroy(prGlueInfo);
  2902. /* 4 <3> Remove /proc filesystem. */
  2903. #ifdef WLAN_INCLUDE_PROC
  2904. procRemoveProcfs();
  2905. #endif /* WLAN_INCLUDE_PROC */
  2906. #if CFG_ENABLE_WIFI_DIRECT
  2907. /* avoid remove & p2p off command simultaneously */
  2908. {
  2909. BOOLEAN fgIsP2POnOffing;
  2910. GLUE_SPIN_LOCK_DECLARATION();
  2911. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2912. g_u4P2PEnding = 1;
  2913. fgIsP2POnOffing = g_u4P2POnOffing;
  2914. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2915. DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n");
  2916. /* History: cannot use down() here, sometimes we cannot come back here */
  2917. /* waiting for p2p off command finishes, we cannot skip the remove */
  2918. while (1) {
  2919. if (fgIsP2POnOffing == 0)
  2920. break;
  2921. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2922. fgIsP2POnOffing = g_u4P2POnOffing;
  2923. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2924. }
  2925. }
  2926. #endif
  2927. #if CFG_ENABLE_BT_OVER_WIFI
  2928. if (prGlueInfo->rBowInfo.fgIsNetRegistered) {
  2929. bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
  2930. /* wait 300ms for BoW module to send deauth */
  2931. kalMsleep(300);
  2932. }
  2933. #endif
  2934. /* 4 <1> Stopping handling interrupt and free IRQ */
  2935. DBGLOG(INIT, TRACE, "free IRQ...\n");
  2936. glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev)));
  2937. kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
  2938. kalSetHalted(TRUE); /* before flush_delayed_work() */
  2939. if (fgIsWorkMcStart == TRUE) {
  2940. DBGLOG(INIT, TRACE, "flush_delayed_work...\n");
  2941. flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */
  2942. }
  2943. flush_delayed_work(&sched_workq);
  2944. DBGLOG(INIT, INFO, "down g_halt_sem...\n");
  2945. kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC);
  2946. #if CFG_SPM_WORKAROUND_FOR_HOTSPOT
  2947. if (glIsChipNeedWakelock(prGlueInfo))
  2948. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock);
  2949. #endif
  2950. /* flush_delayed_work_sync(&workq); */
  2951. /* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */
  2952. /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */
  2953. /* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */
  2954. set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
  2955. DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n");
  2956. /* wake up main thread */
  2957. wake_up_interruptible(&prGlueInfo->waitq);
  2958. DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n");
  2959. /* wait main thread stops */
  2960. wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
  2961. DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n");
  2962. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock);
  2963. KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2964. /* prGlueInfo->rHifInfo.main_thread = NULL; */
  2965. prGlueInfo->main_thread = NULL;
  2966. #if CFG_ENABLE_BT_OVER_WIFI
  2967. if (prGlueInfo->rBowInfo.fgIsRegistered)
  2968. glUnregisterAmpc(prGlueInfo);
  2969. #endif
  2970. #if (CFG_SUPPORT_MET_PROFILING == 1)
  2971. kalMetRemoveProcfs();
  2972. #endif
  2973. /* Force to do DMA reset */
  2974. DBGLOG(INIT, TRACE, "glResetHif\n");
  2975. glResetHif(prGlueInfo);
  2976. /* 4 <4> wlanAdapterStop */
  2977. prAdapter = prGlueInfo->prAdapter;
  2978. #if CFG_SUPPORT_AGPS_ASSIST
  2979. kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0);
  2980. #endif
  2981. wlanAdapterStop(prAdapter);
  2982. DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum);
  2983. #if CFG_ENABLE_WIFI_DIRECT
  2984. prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
  2985. if (prGlueInfo->prAdapter->fgIsP2PRegistered) {
  2986. DBGLOG(INIT, TRACE, "p2pNetUnregister...\n");
  2987. #if !CFG_SUPPORT_PERSIST_NETDEV
  2988. p2pNetUnregister(prGlueInfo, FALSE);
  2989. #endif
  2990. DBGLOG(INIT, INFO, "p2pRemove...\n");
  2991. p2pRemove(prGlueInfo);
  2992. }
  2993. #endif
  2994. /* 4 <5> Release the Bus */
  2995. glBusRelease(prDev);
  2996. kalHaltUnlock();
  2997. wlanDebugUninit();
  2998. /* 4 <6> Unregister the card */
  2999. wlanNetUnregister(prDev->ieee80211_ptr);
  3000. /* 4 <7> Destroy the device */
  3001. wlanNetDestroy(prDev->ieee80211_ptr);
  3002. prDev = NULL;
  3003. DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n");
  3004. wlanUnregisterNotifier();
  3005. DBGLOG(INIT, INFO, "wlanRemove ok\n");
  3006. } /* end of wlanRemove() */
  3007. /*----------------------------------------------------------------------------*/
  3008. /*!
  3009. * \brief Driver entry point when the driver is configured as a Linux Module, and
  3010. * is called once at module load time, by the user-level modutils
  3011. * application: insmod or modprobe.
  3012. *
  3013. * \retval 0 Success
  3014. */
  3015. /*----------------------------------------------------------------------------*/
  3016. /* 1 Module Entry Point */
  3017. static int initWlan(void)
  3018. {
  3019. int ret = 0, i;
  3020. #if DBG
  3021. for (i = 0; i < DBG_MODULE_NUM; i++)
  3022. aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */
  3023. #else
  3024. /* Initial debug level is D1 */
  3025. for (i = 0; i < DBG_MODULE_NUM; i++)
  3026. aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE;
  3027. #endif /* DBG */
  3028. DBGLOG(INIT, INFO, "initWlan\n");
  3029. spin_lock_init(&g_p2p_lock);
  3030. /* memory pre-allocation */
  3031. kalInitIOBuffer();
  3032. procInitFs();
  3033. createWirelessDevice();
  3034. if (gprWdev)
  3035. glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy));
  3036. ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO);
  3037. if (ret == -EIO) {
  3038. kalUninitIOBuffer();
  3039. return ret;
  3040. }
  3041. #if (CFG_CHIP_RESET_SUPPORT)
  3042. glResetInit();
  3043. #endif
  3044. /* register set_dbg_level handler to mtk_wmt_wifi */
  3045. register_set_dbg_level_handler(set_dbg_level_handler);
  3046. /* Register framebuffer notifier client*/
  3047. kalFbNotifierReg((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy));
  3048. /* Set the initial DEBUG CLASS of each module */
  3049. return ret;
  3050. } /* end of initWlan() */
  3051. /*----------------------------------------------------------------------------*/
  3052. /*!
  3053. * \brief Driver exit point when the driver as a Linux Module is removed. Called
  3054. * at module unload time, by the user level modutils application: rmmod.
  3055. * This is our last chance to clean up after ourselves.
  3056. *
  3057. * \return (none)
  3058. */
  3059. /*----------------------------------------------------------------------------*/
  3060. /* 1 Module Leave Point */
  3061. static VOID exitWlan(void)
  3062. {
  3063. DBGLOG(INIT, INFO, "exitWlan\n");
  3064. /* Unregister framebuffer notifier client*/
  3065. kalFbNotifierUnReg();
  3066. /* unregister set_dbg_level handler to mtk_wmt_wifi */
  3067. register_set_dbg_level_handler(NULL);
  3068. #if CFG_CHIP_RESET_SUPPORT
  3069. glResetUninit();
  3070. #endif
  3071. destroyWirelessDevice();
  3072. glP2pDestroyWirelessDevice();
  3073. glUnregisterBus(wlanRemove);
  3074. /* free pre-allocated memory */
  3075. kalUninitIOBuffer();
  3076. DBGLOG(INIT, INFO, "exitWlan\n");
  3077. procUninitProcFs();
  3078. } /* end of exitWlan() */
  3079. #ifdef MTK_WCN_BUILT_IN_DRIVER
  3080. int mtk_wcn_wlan_gen2_init(void)
  3081. {
  3082. return initWlan();
  3083. }
  3084. EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init);
  3085. void mtk_wcn_wlan_gen2_exit(void)
  3086. {
  3087. return exitWlan();
  3088. }
  3089. EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit);
  3090. #else
  3091. module_init(initWlan);
  3092. module_exit(exitWlan);
  3093. #endif