gl_init.c 112 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496
  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. struct semaphore g_halt_sem;
  684. int g_u4HaltFlag = 1;
  685. #if CFG_ENABLE_WIFI_DIRECT
  686. spinlock_t g_p2p_lock;
  687. int g_u4P2PEnding = 0;
  688. int g_u4P2POnOffing = 0;
  689. #endif
  690. /*******************************************************************************
  691. * D A T A T Y P E S
  692. ********************************************************************************
  693. */
  694. /* Tasklet mechanism is like buttom-half in Linux. We just want to
  695. * send a signal to OS for interrupt defer processing. All resources
  696. * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
  697. */
  698. typedef struct _WLANDEV_INFO_T {
  699. struct net_device *prDev;
  700. } WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
  701. /*******************************************************************************
  702. * P U B L I C D A T A
  703. ********************************************************************************
  704. */
  705. MODULE_AUTHOR(NIC_AUTHOR);
  706. MODULE_DESCRIPTION(NIC_DESC);
  707. MODULE_SUPPORTED_DEVICE(NIC_NAME);
  708. MODULE_LICENSE("GPL");
  709. #define NIC_INF_NAME "wlan%d" /* interface name */
  710. #if CFG_TC1_FEATURE
  711. #define NIC_INF_NAME_IN_AP_MODE "legacy%d"
  712. #endif
  713. /* support to change debug module info dynamically */
  714. UINT_8 aucDebugModule[DBG_MODULE_NUM];
  715. UINT_32 u4DebugModule = 0;
  716. /* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */
  717. static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} };
  718. static UINT_32 u4WlanDevNum; /* How many NICs coexist now */
  719. /**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/
  720. struct delayed_work sched_workq;
  721. /*******************************************************************************
  722. * P R I V A T E D A T A
  723. ********************************************************************************
  724. */
  725. #if CFG_ENABLE_WIFI_DIRECT
  726. static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} };
  727. #endif
  728. #define CHAN2G(_channel, _freq, _flags) \
  729. { \
  730. .band = IEEE80211_BAND_2GHZ, \
  731. .center_freq = (_freq), \
  732. .hw_value = (_channel), \
  733. .flags = (_flags), \
  734. .max_antenna_gain = 0, \
  735. .max_power = 30, \
  736. }
  737. static struct ieee80211_channel mtk_2ghz_channels[] = {
  738. CHAN2G(1, 2412, 0),
  739. CHAN2G(2, 2417, 0),
  740. CHAN2G(3, 2422, 0),
  741. CHAN2G(4, 2427, 0),
  742. CHAN2G(5, 2432, 0),
  743. CHAN2G(6, 2437, 0),
  744. CHAN2G(7, 2442, 0),
  745. CHAN2G(8, 2447, 0),
  746. CHAN2G(9, 2452, 0),
  747. CHAN2G(10, 2457, 0),
  748. CHAN2G(11, 2462, 0),
  749. CHAN2G(12, 2467, 0),
  750. CHAN2G(13, 2472, 0),
  751. CHAN2G(14, 2484, 0),
  752. };
  753. #define CHAN5G(_channel, _flags) \
  754. { \
  755. .band = IEEE80211_BAND_5GHZ, \
  756. .center_freq = 5000 + (5 * (_channel)), \
  757. .hw_value = (_channel), \
  758. .flags = (_flags), \
  759. .max_antenna_gain = 0, \
  760. .max_power = 30, \
  761. }
  762. static struct ieee80211_channel mtk_5ghz_channels[] = {
  763. CHAN5G(34, 0), CHAN5G(36, 0),
  764. CHAN5G(38, 0), CHAN5G(40, 0),
  765. CHAN5G(42, 0), CHAN5G(44, 0),
  766. CHAN5G(46, 0), CHAN5G(48, 0),
  767. CHAN5G(52, 0), CHAN5G(56, 0),
  768. CHAN5G(60, 0), CHAN5G(64, 0),
  769. CHAN5G(100, 0), CHAN5G(104, 0),
  770. CHAN5G(108, 0), CHAN5G(112, 0),
  771. CHAN5G(116, 0), CHAN5G(120, 0),
  772. CHAN5G(124, 0), CHAN5G(128, 0),
  773. CHAN5G(132, 0), CHAN5G(136, 0),
  774. CHAN5G(140, 0), CHAN5G(149, 0),
  775. CHAN5G(153, 0), CHAN5G(157, 0),
  776. CHAN5G(161, 0), CHAN5G(165, 0),
  777. CHAN5G(169, 0), CHAN5G(173, 0),
  778. CHAN5G(184, 0), CHAN5G(188, 0),
  779. CHAN5G(192, 0), CHAN5G(196, 0),
  780. CHAN5G(200, 0), CHAN5G(204, 0),
  781. CHAN5G(208, 0), CHAN5G(212, 0),
  782. CHAN5G(216, 0),
  783. };
  784. /* for cfg80211 - rate table */
  785. static struct ieee80211_rate mtk_rates[] = {
  786. RATETAB_ENT(10, 0x1000, 0),
  787. RATETAB_ENT(20, 0x1001, 0),
  788. RATETAB_ENT(55, 0x1002, 0),
  789. RATETAB_ENT(110, 0x1003, 0), /* 802.11b */
  790. RATETAB_ENT(60, 0x2000, 0),
  791. RATETAB_ENT(90, 0x2001, 0),
  792. RATETAB_ENT(120, 0x2002, 0),
  793. RATETAB_ENT(180, 0x2003, 0),
  794. RATETAB_ENT(240, 0x2004, 0),
  795. RATETAB_ENT(360, 0x2005, 0),
  796. RATETAB_ENT(480, 0x2006, 0),
  797. RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */
  798. };
  799. #define mtk_a_rates (mtk_rates + 4)
  800. #define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
  801. #define mtk_g_rates (mtk_rates + 0)
  802. #define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
  803. #define MT6620_MCS_INFO \
  804. { \
  805. .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
  806. .rx_highest = 0, \
  807. .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
  808. }
  809. #define MT6620_HT_CAP \
  810. { \
  811. .ht_supported = true, \
  812. .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \
  813. | IEEE80211_HT_CAP_SM_PS \
  814. | IEEE80211_HT_CAP_GRN_FLD \
  815. | IEEE80211_HT_CAP_SGI_20 \
  816. | IEEE80211_HT_CAP_SGI_40, \
  817. .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
  818. .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \
  819. .mcs = MT6620_MCS_INFO, \
  820. }
  821. /* public for both Legacy Wi-Fi / P2P access */
  822. struct ieee80211_supported_band mtk_band_2ghz = {
  823. .band = IEEE80211_BAND_2GHZ,
  824. .channels = mtk_2ghz_channels,
  825. .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
  826. .bitrates = mtk_g_rates,
  827. .n_bitrates = mtk_g_rates_size,
  828. .ht_cap = MT6620_HT_CAP,
  829. };
  830. /* public for both Legacy Wi-Fi / P2P access */
  831. struct ieee80211_supported_band mtk_band_5ghz = {
  832. .band = IEEE80211_BAND_5GHZ,
  833. .channels = mtk_5ghz_channels,
  834. .n_channels = ARRAY_SIZE(mtk_5ghz_channels),
  835. .bitrates = mtk_a_rates,
  836. .n_bitrates = mtk_a_rates_size,
  837. .ht_cap = MT6620_HT_CAP,
  838. };
  839. static const UINT_32 mtk_cipher_suites[] = {
  840. /* keep WEP first, it may be removed below */
  841. WLAN_CIPHER_SUITE_WEP40,
  842. WLAN_CIPHER_SUITE_WEP104,
  843. WLAN_CIPHER_SUITE_TKIP,
  844. WLAN_CIPHER_SUITE_CCMP,
  845. /* keep last -- depends on hw flags! */
  846. WLAN_CIPHER_SUITE_AES_CMAC
  847. };
  848. static struct cfg80211_ops mtk_wlan_ops = {
  849. .suspend = mtk_cfg80211_suspend,
  850. .resume = mtk_cfg80211_resume,
  851. .change_virtual_intf = mtk_cfg80211_change_iface,
  852. .add_key = mtk_cfg80211_add_key,
  853. .get_key = mtk_cfg80211_get_key,
  854. .del_key = mtk_cfg80211_del_key,
  855. .set_default_key = mtk_cfg80211_set_default_key,
  856. .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key,
  857. .get_station = mtk_cfg80211_get_station,
  858. .change_station = mtk_cfg80211_change_station,
  859. .add_station = mtk_cfg80211_add_station,
  860. .del_station = mtk_cfg80211_del_station,
  861. .scan = mtk_cfg80211_scan,
  862. .connect = mtk_cfg80211_connect,
  863. .disconnect = mtk_cfg80211_disconnect,
  864. .join_ibss = mtk_cfg80211_join_ibss,
  865. .leave_ibss = mtk_cfg80211_leave_ibss,
  866. .set_power_mgmt = mtk_cfg80211_set_power_mgmt,
  867. .set_pmksa = mtk_cfg80211_set_pmksa,
  868. .del_pmksa = mtk_cfg80211_del_pmksa,
  869. .flush_pmksa = mtk_cfg80211_flush_pmksa,
  870. .assoc = mtk_cfg80211_assoc,
  871. /* Action Frame TX/RX */
  872. .remain_on_channel = mtk_cfg80211_remain_on_channel,
  873. .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel,
  874. .mgmt_tx = mtk_cfg80211_mgmt_tx,
  875. /* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */
  876. .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register,
  877. #ifdef CONFIG_NL80211_TESTMODE
  878. .testmode_cmd = mtk_cfg80211_testmode_cmd,
  879. #endif
  880. #if (CFG_SUPPORT_TDLS == 1)
  881. .tdls_mgmt = TdlsexCfg80211TdlsMgmt,
  882. .tdls_oper = TdlsexCfg80211TdlsOper,
  883. #endif /* CFG_SUPPORT_TDLS */
  884. #if 1 /* Remove schedule_scan because we need more verification for NLO */
  885. .sched_scan_start = mtk_cfg80211_sched_scan_start,
  886. .sched_scan_stop = mtk_cfg80211_sched_scan_stop,
  887. #endif
  888. };
  889. static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = {
  890. {
  891. {
  892. .vendor_id = GOOGLE_OUI,
  893. .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES},
  894. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  895. .doit = mtk_cfg80211_vendor_get_gscan_capabilities},
  896. {
  897. {
  898. .vendor_id = GOOGLE_OUI,
  899. .subcmd = GSCAN_SUBCMD_SET_CONFIG},
  900. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  901. .doit = mtk_cfg80211_vendor_set_config},
  902. {
  903. {
  904. .vendor_id = GOOGLE_OUI,
  905. .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG},
  906. .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
  907. .doit = mtk_cfg80211_vendor_set_scan_config},
  908. {
  909. {
  910. .vendor_id = GOOGLE_OUI,
  911. .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN},
  912. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  913. .doit = mtk_cfg80211_vendor_enable_scan},
  914. {
  915. {
  916. .vendor_id = GOOGLE_OUI,
  917. .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS},
  918. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  919. .doit = mtk_cfg80211_vendor_enable_full_scan_results},
  920. {
  921. {
  922. .vendor_id = GOOGLE_OUI,
  923. .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS},
  924. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  925. .doit = mtk_cfg80211_vendor_get_scan_results},
  926. {
  927. {
  928. .vendor_id = GOOGLE_OUI,
  929. .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST},
  930. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  931. .doit = mtk_cfg80211_vendor_get_channel_list},
  932. {
  933. {
  934. .vendor_id = GOOGLE_OUI,
  935. .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG},
  936. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  937. .doit = mtk_cfg80211_vendor_set_significant_change},
  938. {
  939. {
  940. .vendor_id = GOOGLE_OUI,
  941. .subcmd = GSCAN_SUBCMD_SET_HOTLIST},
  942. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  943. .doit = mtk_cfg80211_vendor_set_hotlist},
  944. /*Link Layer Statistics */
  945. {
  946. {
  947. .vendor_id = GOOGLE_OUI,
  948. .subcmd = LSTATS_SUBCMD_GET_INFO},
  949. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  950. .doit = mtk_cfg80211_vendor_llstats_get_info},
  951. {
  952. {
  953. .vendor_id = GOOGLE_OUI,
  954. .subcmd = RTT_SUBCMD_GETCAPABILITY},
  955. .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
  956. .doit = mtk_cfg80211_vendor_get_rtt_capabilities},
  957. };
  958. static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = {
  959. {
  960. .vendor_id = GOOGLE_OUI,
  961. .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS},
  962. {
  963. .vendor_id = GOOGLE_OUI,
  964. .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND},
  965. {
  966. .vendor_id = GOOGLE_OUI,
  967. .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE},
  968. {
  969. .vendor_id = GOOGLE_OUI,
  970. .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS},
  971. {
  972. .vendor_id = GOOGLE_OUI,
  973. .subcmd = RTT_EVENT_COMPLETE},
  974. {
  975. .vendor_id = GOOGLE_OUI,
  976. .subcmd = GSCAN_EVENT_COMPLETE_SCAN},
  977. {
  978. .vendor_id = GOOGLE_OUI,
  979. .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST},
  980. };
  981. /* There isn't a lot of sense in it, but you can transmit anything you like */
  982. static const struct ieee80211_txrx_stypes
  983. mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
  984. [NL80211_IFTYPE_ADHOC] = {
  985. .tx = 0xffff,
  986. .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
  987. },
  988. [NL80211_IFTYPE_STATION] = {
  989. .tx = 0xffff,
  990. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  991. },
  992. [NL80211_IFTYPE_AP] = {
  993. .tx = 0xffff,
  994. .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  995. },
  996. [NL80211_IFTYPE_AP_VLAN] = {
  997. /* copy AP */
  998. .tx = 0xffff,
  999. .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  1000. BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  1001. BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  1002. BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  1003. BIT(IEEE80211_STYPE_AUTH >> 4) |
  1004. BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  1005. },
  1006. [NL80211_IFTYPE_P2P_CLIENT] = {
  1007. .tx = 0xffff,
  1008. .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  1009. },
  1010. [NL80211_IFTYPE_P2P_GO] = {
  1011. .tx = 0xffff,
  1012. .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4)
  1013. }
  1014. };
  1015. /*******************************************************************************
  1016. * M A C R O S
  1017. ********************************************************************************
  1018. */
  1019. /*******************************************************************************
  1020. * F U N C T I O N D E C L A R A T I O N S
  1021. ********************************************************************************
  1022. */
  1023. /*******************************************************************************
  1024. * F U N C T I O N S
  1025. ********************************************************************************
  1026. */
  1027. /*----------------------------------------------------------------------------*/
  1028. /*!
  1029. * \brief Override the implementation of select queue
  1030. *
  1031. * \param[in] dev Pointer to struct net_device
  1032. * \param[in] skb Pointer to struct skb_buff
  1033. *
  1034. * \return (none)
  1035. */
  1036. /*----------------------------------------------------------------------------*/
  1037. unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
  1038. {
  1039. unsigned int dscp = 0;
  1040. /* skb->priority values from 256->263 are magic values
  1041. * directly indicate a specific 802.1d priority. This is
  1042. * to allow 802.1d priority to be passed directly in from
  1043. * tags
  1044. */
  1045. if (skb->priority >= 256 && skb->priority <= 263)
  1046. return skb->priority - 256;
  1047. switch (skb->protocol) {
  1048. case htons(ETH_P_IP):
  1049. dscp = ip_hdr(skb)->tos & 0xfc;
  1050. break;
  1051. }
  1052. return dscp >> 5;
  1053. }
  1054. static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
  1055. static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb,
  1056. void *accel_priv, select_queue_fallback_t fallback)
  1057. {
  1058. skb->priority = _cfg80211_classify8021d(skb);
  1059. return au16Wlan1dToQueueIdx[skb->priority];
  1060. }
  1061. /*----------------------------------------------------------------------------*/
  1062. /*!
  1063. * \brief Load NVRAM data and translate it into REG_INFO_T
  1064. *
  1065. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1066. * \param[out] prRegInfo Pointer to struct REG_INFO_T
  1067. *
  1068. * \return (none)
  1069. */
  1070. /*----------------------------------------------------------------------------*/
  1071. static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo)
  1072. {
  1073. UINT_32 i, j;
  1074. UINT_8 aucTmp[2];
  1075. PUINT_8 pucDest;
  1076. ASSERT(prGlueInfo);
  1077. ASSERT(prRegInfo);
  1078. if ((!prGlueInfo) || (!prRegInfo))
  1079. return;
  1080. if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) {
  1081. prGlueInfo->fgNvramAvailable = TRUE;
  1082. /* load MAC Address */
  1083. #if !defined(CONFIG_MTK_TC1_FEATURE)
  1084. for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) {
  1085. kalCfgDataRead16(prGlueInfo,
  1086. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
  1087. (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i));
  1088. }
  1089. #else
  1090. TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr);
  1091. #endif
  1092. /* load country code */
  1093. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp);
  1094. /* cast to wide characters */
  1095. prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
  1096. prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
  1097. /* load default normal TX power */
  1098. for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) {
  1099. kalCfgDataRead16(prGlueInfo,
  1100. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
  1101. (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i));
  1102. }
  1103. /* load feature flags */
  1104. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp);
  1105. prRegInfo->ucTxPwrValid = aucTmp[0];
  1106. prRegInfo->ucSupport5GBand = aucTmp[1];
  1107. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp);
  1108. prRegInfo->uc2G4BwFixed20M = aucTmp[0];
  1109. prRegInfo->uc5GBwFixed20M = aucTmp[1];
  1110. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp);
  1111. prRegInfo->ucEnable5GBand = aucTmp[0];
  1112. /* load EFUSE overriding part */
  1113. for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) {
  1114. kalCfgDataRead16(prGlueInfo,
  1115. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
  1116. (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i));
  1117. }
  1118. /* load band edge tx power control */
  1119. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp);
  1120. prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0];
  1121. if (aucTmp[0]) {
  1122. prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1];
  1123. kalCfgDataRead16(prGlueInfo,
  1124. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp);
  1125. prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0];
  1126. prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1];
  1127. }
  1128. /* load regulation subbands */
  1129. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp);
  1130. prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
  1131. prRegInfo->ucRegChannelListIndex = aucTmp[1];
  1132. if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
  1133. for (i = 0; i < MAX_SUBBAND_NUM; i++) {
  1134. pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
  1135. for (j = 0; j < 6; j += sizeof(UINT_16)) {
  1136. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
  1137. + (i * 6 + j), (PUINT_16) aucTmp);
  1138. *pucDest++ = aucTmp[0];
  1139. *pucDest++ = aucTmp[1];
  1140. }
  1141. }
  1142. }
  1143. /* load RSSI compensation */
  1144. kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp);
  1145. prRegInfo->uc2GRssiCompensation = aucTmp[0];
  1146. prRegInfo->uc5GRssiCompensation = aucTmp[1];
  1147. kalCfgDataRead16(prGlueInfo,
  1148. OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp);
  1149. prRegInfo->fgRssiCompensationValidbit = aucTmp[0];
  1150. prRegInfo->ucRxAntennanumber = aucTmp[1];
  1151. } else {
  1152. prGlueInfo->fgNvramAvailable = FALSE;
  1153. }
  1154. }
  1155. #if CFG_ENABLE_WIFI_DIRECT
  1156. /*----------------------------------------------------------------------------*/
  1157. /*!
  1158. * \brief called by txthread, run sub module init function
  1159. *
  1160. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1161. *
  1162. * \return (none)
  1163. */
  1164. /*----------------------------------------------------------------------------*/
  1165. VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo)
  1166. {
  1167. /*now, we only have p2p module */
  1168. if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
  1169. rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
  1170. rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
  1171. }
  1172. }
  1173. /*----------------------------------------------------------------------------*/
  1174. /*!
  1175. * \brief called by txthread, run sub module exit function
  1176. *
  1177. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1178. *
  1179. * \return (none)
  1180. */
  1181. /*----------------------------------------------------------------------------*/
  1182. VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo)
  1183. {
  1184. /*now, we only have p2p module */
  1185. if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
  1186. rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
  1187. rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
  1188. }
  1189. }
  1190. /*----------------------------------------------------------------------------*/
  1191. /*!
  1192. * \brief set sub module init flag, force TxThread to run sub modle init
  1193. *
  1194. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1195. *
  1196. * \return (none)
  1197. */
  1198. /*----------------------------------------------------------------------------*/
  1199. BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo)
  1200. {
  1201. /* 4 Mark HALT, notify main thread to finish current job */
  1202. prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT;
  1203. /* wake up main thread */
  1204. wake_up_interruptible(&prGlueInfo->waitq);
  1205. /* wait main thread finish sub module INIT */
  1206. wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
  1207. #if 0
  1208. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1209. p2pNetRegister(prGlueInfo);
  1210. #endif
  1211. return TRUE;
  1212. }
  1213. /*----------------------------------------------------------------------------*/
  1214. /*!
  1215. * \brief set sub module exit flag, force TxThread to run sub modle exit
  1216. *
  1217. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1218. *
  1219. * \return (none)
  1220. */
  1221. /*----------------------------------------------------------------------------*/
  1222. BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo)
  1223. {
  1224. #if 0
  1225. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1226. p2pNetUnregister(prGlueInfo);
  1227. #endif
  1228. /* 4 Mark HALT, notify main thread to finish current job */
  1229. prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT;
  1230. /* wake up main thread */
  1231. wake_up_interruptible(&prGlueInfo->waitq);
  1232. /* wait main thread finish sub module EXIT */
  1233. wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
  1234. return TRUE;
  1235. }
  1236. /*----------------------------------------------------------------------------*/
  1237. /*!
  1238. * \brief set by sub module, indicate sub module is already inserted
  1239. *
  1240. * \param[in] rSubModInit, function pointer point to sub module init function
  1241. * \param[in] rSubModExit, function pointer point to sub module exit function
  1242. * \param[in] eSubModIdx, sub module index
  1243. *
  1244. * \return (none)
  1245. */
  1246. /*----------------------------------------------------------------------------*/
  1247. VOID
  1248. wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx)
  1249. {
  1250. rSubModHandler[eSubModIdx].subModInit = rSubModInit;
  1251. rSubModHandler[eSubModIdx].subModExit = rSubModExit;
  1252. rSubModHandler[eSubModIdx].fgIsInited = FALSE;
  1253. }
  1254. #if 0
  1255. /*----------------------------------------------------------------------------*/
  1256. /*!
  1257. * \brief check wlan is launched or not
  1258. *
  1259. * \param[in] (none)
  1260. *
  1261. * \return TRUE, wlan is already started
  1262. * FALSE, wlan is not started yet
  1263. */
  1264. /*----------------------------------------------------------------------------*/
  1265. BOOLEAN wlanIsLaunched(VOID)
  1266. {
  1267. struct net_device *prDev = NULL;
  1268. P_GLUE_INFO_T prGlueInfo = NULL;
  1269. /* 4 <0> Sanity check */
  1270. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  1271. if (0 == u4WlanDevNum)
  1272. return FALSE;
  1273. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  1274. ASSERT(prDev);
  1275. if (NULL == prDev)
  1276. return FALSE;
  1277. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1278. ASSERT(prGlueInfo);
  1279. if (NULL == prGlueInfo)
  1280. return FALSE;
  1281. return prGlueInfo->prAdapter->fgIsWlanLaunched;
  1282. }
  1283. #endif
  1284. /*----------------------------------------------------------------------------*/
  1285. /*!
  1286. * \brief Export wlan GLUE_INFO_T pointer to p2p module
  1287. *
  1288. * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
  1289. *
  1290. * \return TRUE: get GlueInfo pointer successfully
  1291. * FALSE: wlan is not started yet
  1292. */
  1293. /*---------------------------------------------------------------------------*/
  1294. BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr)
  1295. {
  1296. struct net_device *prDev = NULL;
  1297. P_GLUE_INFO_T prGlueInfo = NULL;
  1298. if (0 == u4WlanDevNum)
  1299. return FALSE;
  1300. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  1301. if (NULL == prDev)
  1302. return FALSE;
  1303. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1304. if (NULL == prGlueInfo)
  1305. return FALSE;
  1306. if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched)
  1307. return FALSE;
  1308. *prGlueInfoExpAddr = prGlueInfo;
  1309. return TRUE;
  1310. }
  1311. #endif
  1312. /*----------------------------------------------------------------------------*/
  1313. /*!
  1314. * \brief Release prDev from wlandev_array and free tasklet object related to it.
  1315. *
  1316. * \param[in] prDev Pointer to struct net_device
  1317. *
  1318. * \return (none)
  1319. */
  1320. /*----------------------------------------------------------------------------*/
  1321. static void wlanClearDevIdx(struct net_device *prDev)
  1322. {
  1323. int i;
  1324. ASSERT(prDev);
  1325. for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
  1326. if (arWlanDevInfo[i].prDev == prDev) {
  1327. arWlanDevInfo[i].prDev = NULL;
  1328. u4WlanDevNum--;
  1329. }
  1330. }
  1331. } /* end of wlanClearDevIdx() */
  1332. /*----------------------------------------------------------------------------*/
  1333. /*!
  1334. * \brief Allocate an unique interface index, net_device::ifindex member for this
  1335. * wlan device. Store the net_device in wlandev_array, and initialize
  1336. * tasklet object related to it.
  1337. *
  1338. * \param[in] prDev Pointer to struct net_device
  1339. *
  1340. * \retval >= 0 The device number.
  1341. * \retval -1 Fail to get index.
  1342. */
  1343. /*----------------------------------------------------------------------------*/
  1344. static int wlanGetDevIdx(struct net_device *prDev)
  1345. {
  1346. int i;
  1347. ASSERT(prDev);
  1348. for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
  1349. if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) {
  1350. /* Reserve 2 bytes space to store one digit of
  1351. * device number and NULL terminator.
  1352. */
  1353. arWlanDevInfo[i].prDev = prDev;
  1354. u4WlanDevNum++;
  1355. return i;
  1356. }
  1357. }
  1358. return -1;
  1359. } /* end of wlanGetDevIdx() */
  1360. /*----------------------------------------------------------------------------*/
  1361. /*!
  1362. * \brief A method of struct net_device, a primary SOCKET interface to configure
  1363. * the interface lively. Handle an ioctl call on one of our devices.
  1364. * Everything Linux ioctl specific is done here. Then we pass the contents
  1365. * of the ifr->data to the request message handler.
  1366. *
  1367. * \param[in] prDev Linux kernel netdevice
  1368. *
  1369. * \param[in] prIFReq Our private ioctl request structure, typed for the generic
  1370. * struct ifreq so we can use ptr to function
  1371. *
  1372. * \param[in] cmd Command ID
  1373. *
  1374. * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
  1375. * \retval OTHER The execution of IOCTL command is failed.
  1376. */
  1377. /*----------------------------------------------------------------------------*/
  1378. int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIFReq, int i4Cmd)
  1379. {
  1380. P_GLUE_INFO_T prGlueInfo = NULL;
  1381. int ret = 0;
  1382. /* Verify input parameters for the following functions */
  1383. ASSERT(prDev && prIFReq);
  1384. if (!prDev || !prIFReq) {
  1385. DBGLOG(INIT, WARN, "%s Invalid input data\n", __func__);
  1386. return -EINVAL;
  1387. }
  1388. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1389. ASSERT(prGlueInfo);
  1390. if (!prGlueInfo) {
  1391. DBGLOG(INIT, WARN, "%s No glue info\n", __func__);
  1392. return -EFAULT;
  1393. }
  1394. if (prGlueInfo->u4ReadyFlag == 0)
  1395. return -EINVAL;
  1396. /* printk ("ioctl %x\n", i4Cmd); */
  1397. if (i4Cmd == SIOCGIWPRIV) {
  1398. /* 0x8B0D, get private ioctl table */
  1399. ret = wext_get_priv(prDev, prIFReq);
  1400. } else if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
  1401. /* 0x8B00 ~ 0x8BDF, wireless extension region */
  1402. ret = wext_support_ioctl(prDev, prIFReq, i4Cmd);
  1403. } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
  1404. /* 0x8BE0 ~ 0x8BFF, private ioctl region */
  1405. ret = priv_support_ioctl(prDev, prIFReq, i4Cmd);
  1406. } else if (i4Cmd == SIOCDEVPRIVATE + 1) {
  1407. ret = priv_support_driver_cmd(prDev, prIFReq, i4Cmd);
  1408. } else {
  1409. DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd);
  1410. /* return 0 for safe? */
  1411. }
  1412. return ret;
  1413. } /* end of wlanDoIOCTL() */
  1414. /*----------------------------------------------------------------------------*/
  1415. /*!
  1416. * \brief This function is to set multicast list and set rx mode.
  1417. *
  1418. * \param[in] prDev Pointer to struct net_device
  1419. *
  1420. * \return (none)
  1421. */
  1422. /*----------------------------------------------------------------------------*/
  1423. static struct delayed_work workq;
  1424. static struct net_device *gPrDev;
  1425. static BOOLEAN fgIsWorkMcStart = FALSE;
  1426. static BOOLEAN fgIsWorkMcEverInit = FALSE;
  1427. static struct wireless_dev *gprWdev;
  1428. #ifdef CONFIG_PM
  1429. static const struct wiphy_wowlan_support wlan_wowlan_support = {
  1430. .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY,
  1431. };
  1432. #endif
  1433. static void createWirelessDevice(void)
  1434. {
  1435. struct wiphy *prWiphy = NULL;
  1436. struct wireless_dev *prWdev = NULL;
  1437. #if CFG_SUPPORT_PERSIST_NETDEV
  1438. struct net_device *prNetDev = NULL;
  1439. #endif
  1440. /* <1.1> Create wireless_dev */
  1441. prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
  1442. if (!prWdev) {
  1443. DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
  1444. return;
  1445. }
  1446. /* initialize semaphore for ioctl */
  1447. sema_init(&g_halt_sem, 1);
  1448. g_u4HaltFlag = 1;
  1449. /* <1.2> Create wiphy */
  1450. prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
  1451. if (!prWiphy) {
  1452. DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n");
  1453. goto free_wdev;
  1454. }
  1455. /* <1.3> configure wireless_dev & wiphy */
  1456. prWdev->iftype = NL80211_IFTYPE_STATION;
  1457. prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */
  1458. prWiphy->max_scan_ie_len = 512;
  1459. prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM;
  1460. prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM;
  1461. prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN;
  1462. prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
  1463. prWiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
  1464. /* always assign 5Ghz bands here, if the chip is not support 5Ghz,
  1465. bands[IEEE80211_BAND_5GHZ] will be assign to NULL */
  1466. prWiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
  1467. prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
  1468. prWiphy->cipher_suites = (const u32 *)mtk_cipher_suites;
  1469. prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
  1470. prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM
  1471. | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
  1472. | WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
  1473. prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG;
  1474. #if (CFG_SUPPORT_TDLS == 1)
  1475. TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags);
  1476. #endif /* CFG_SUPPORT_TDLS */
  1477. prWiphy->max_remain_on_channel_duration = 5000;
  1478. prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes;
  1479. prWiphy->vendor_commands = mtk_wlan_vendor_ops;
  1480. prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command);
  1481. prWiphy->vendor_events = mtk_wlan_vendor_events;
  1482. prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events);
  1483. /* <1.4> wowlan support */
  1484. #ifdef CONFIG_PM
  1485. prWiphy->wowlan = &wlan_wowlan_support;
  1486. #endif
  1487. #ifdef CONFIG_CFG80211_WEXT
  1488. /* <1.5> Use wireless extension to replace IOCTL */
  1489. prWiphy->wext = &wext_handler_def;
  1490. #endif
  1491. if (wiphy_register(prWiphy) < 0) {
  1492. DBGLOG(INIT, ERROR, "wiphy_register error\n");
  1493. goto free_wiphy;
  1494. }
  1495. prWdev->wiphy = prWiphy;
  1496. #if CFG_SUPPORT_PERSIST_NETDEV
  1497. /* <2> allocate and register net_device */
  1498. #if CFG_TC1_FEATURE
  1499. if (wlan_if_changed)
  1500. prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE,
  1501. ether_setup, CFG_MAX_TXQ_NUM);
  1502. else
  1503. #else
  1504. prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  1505. ether_setup, CFG_MAX_TXQ_NUM);
  1506. #endif
  1507. if (!prNetDev) {
  1508. DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
  1509. goto unregister_wiphy;
  1510. }
  1511. *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy);
  1512. prNetDev->netdev_ops = &wlan_netdev_ops;
  1513. #ifdef CONFIG_WIRELESS_EXT
  1514. prNetDev->wireless_handlers = &wext_handler_def;
  1515. #endif
  1516. netif_carrier_off(prNetDev);
  1517. netif_tx_stop_all_queues(prNetDev);
  1518. /* <2.1> co-relate with wireless_dev bi-directionally */
  1519. prNetDev->ieee80211_ptr = prWdev;
  1520. prWdev->netdev = prNetDev;
  1521. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1522. prNetDev->features = NETIF_F_HW_CSUM;
  1523. #endif
  1524. /* <2.2> co-relate net device & device tree */
  1525. SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy));
  1526. /* <2.3> register net_device */
  1527. if (register_netdev(prWdev->netdev) < 0) {
  1528. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
  1529. goto unregister_wiphy;
  1530. }
  1531. #endif /* CFG_SUPPORT_PERSIST_NETDEV */
  1532. gprWdev = prWdev;
  1533. DBGLOG(INIT, INFO, "create wireless device success\n");
  1534. return;
  1535. #if CFG_SUPPORT_PERSIST_NETDEV
  1536. unregister_wiphy:
  1537. wiphy_unregister(prWiphy);
  1538. #endif
  1539. free_wiphy:
  1540. wiphy_free(prWiphy);
  1541. free_wdev:
  1542. kfree(prWdev);
  1543. }
  1544. static void destroyWirelessDevice(void)
  1545. {
  1546. #if CFG_SUPPORT_PERSIST_NETDEV
  1547. unregister_netdev(gprWdev->netdev);
  1548. free_netdev(gprWdev->netdev);
  1549. #endif
  1550. wiphy_unregister(gprWdev->wiphy);
  1551. wiphy_free(gprWdev->wiphy);
  1552. kfree(gprWdev);
  1553. gprWdev = NULL;
  1554. }
  1555. static void wlanSetMulticastList(struct net_device *prDev)
  1556. {
  1557. gPrDev = prDev;
  1558. schedule_delayed_work(&workq, 0);
  1559. }
  1560. /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
  1561. * another workqueue for sleeping. We don't want to block
  1562. * tx_thread, so we can't let tx_thread to do this */
  1563. static void wlanSetMulticastListWorkQueue(struct work_struct *work)
  1564. {
  1565. P_GLUE_INFO_T prGlueInfo = NULL;
  1566. UINT_32 u4PacketFilter = 0;
  1567. UINT_32 u4SetInfoLen;
  1568. struct net_device *prDev = gPrDev;
  1569. fgIsWorkMcStart = TRUE;
  1570. DBGLOG(INIT, INFO, "wlanSetMulticastListWorkQueue start...\n");
  1571. down(&g_halt_sem);
  1572. if (g_u4HaltFlag) {
  1573. fgIsWorkMcStart = FALSE;
  1574. up(&g_halt_sem);
  1575. return;
  1576. }
  1577. prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
  1578. ASSERT(prDev);
  1579. ASSERT(prGlueInfo);
  1580. if (!prDev || !prGlueInfo) {
  1581. DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
  1582. fgIsWorkMcStart = FALSE;
  1583. up(&g_halt_sem);
  1584. return;
  1585. }
  1586. if (prDev->flags & IFF_PROMISC)
  1587. u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
  1588. if (prDev->flags & IFF_BROADCAST)
  1589. u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
  1590. if (prDev->flags & IFF_MULTICAST) {
  1591. if ((prDev->flags & IFF_ALLMULTI) ||
  1592. (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
  1593. u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
  1594. } else {
  1595. u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
  1596. }
  1597. }
  1598. up(&g_halt_sem);
  1599. if (kalIoctl(prGlueInfo,
  1600. wlanoidSetCurrentPacketFilter,
  1601. &u4PacketFilter,
  1602. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  1603. fgIsWorkMcStart = FALSE;
  1604. return;
  1605. }
  1606. if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
  1607. /* Prepare multicast address list */
  1608. struct netdev_hw_addr *ha;
  1609. PUINT_8 prMCAddrList = NULL;
  1610. UINT_32 i = 0;
  1611. down(&g_halt_sem);
  1612. if (g_u4HaltFlag) {
  1613. fgIsWorkMcStart = FALSE;
  1614. up(&g_halt_sem);
  1615. return;
  1616. }
  1617. prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
  1618. netdev_for_each_mc_addr(ha, prDev) {
  1619. if (i < MAX_NUM_GROUP_ADDR) {
  1620. memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
  1621. i++;
  1622. }
  1623. }
  1624. up(&g_halt_sem);
  1625. kalIoctl(prGlueInfo,
  1626. wlanoidSetMulticastList,
  1627. prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  1628. kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
  1629. }
  1630. fgIsWorkMcStart = FALSE;
  1631. DBGLOG(INIT, INFO, "wlanSetMulticastListWorkQueue end\n");
  1632. } /* end of wlanSetMulticastList() */
  1633. /*----------------------------------------------------------------------------*/
  1634. /*!
  1635. * \brief To indicate scheduled scan has been stopped
  1636. *
  1637. * \param[in]
  1638. * prGlueInfo
  1639. *
  1640. * \return
  1641. * None
  1642. */
  1643. /*----------------------------------------------------------------------------*/
  1644. VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work)
  1645. {
  1646. P_GLUE_INFO_T prGlueInfo = NULL;
  1647. struct net_device *prDev = gPrDev;
  1648. prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
  1649. if (!prGlueInfo) {
  1650. DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n");
  1651. return;
  1652. }
  1653. /* 2. indication to cfg80211 */
  1654. /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */
  1655. cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo));
  1656. DBGLOG(SCN, INFO,
  1657. "cfg80211_sched_scan_stopped event send done\n");
  1658. }
  1659. /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
  1660. * another workqueue for sleeping. We don't want to block
  1661. * tx_thread, so we can't let tx_thread to do this */
  1662. void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo)
  1663. {
  1664. ASSERT(prGlueInfo);
  1665. if (!prGlueInfo) {
  1666. DBGLOG(INIT, WARN, "abnormal dev or skb: prGlueInfo(0x%p)\n", prGlueInfo);
  1667. return;
  1668. }
  1669. #if CFG_ENABLE_WIFI_DIRECT
  1670. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  1671. mtk_p2p_wext_set_Multicastlist(prGlueInfo);
  1672. #endif
  1673. } /* end of p2pSetMulticastListWorkQueueWrapper() */
  1674. /*----------------------------------------------------------------------------*/
  1675. /*!
  1676. * \brief This function is TX entry point of NET DEVICE.
  1677. *
  1678. * \param[in] prSkb Pointer of the sk_buff to be sent
  1679. * \param[in] prDev Pointer to struct net_device
  1680. *
  1681. * \retval NETDEV_TX_OK - on success.
  1682. * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
  1683. */
  1684. /*----------------------------------------------------------------------------*/
  1685. int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev)
  1686. {
  1687. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1688. P_QUE_ENTRY_T prQueueEntry = NULL;
  1689. P_QUE_T prTxQueue = NULL;
  1690. UINT_16 u2QueueIdx = 0;
  1691. #if (CFG_SUPPORT_TDLS_DBG == 1)
  1692. UINT16 u2Identifier = 0;
  1693. #endif
  1694. #if CFG_BOW_TEST
  1695. UINT_32 i;
  1696. #endif
  1697. GLUE_SPIN_LOCK_DECLARATION();
  1698. ASSERT(prSkb);
  1699. ASSERT(prDev);
  1700. ASSERT(prGlueInfo);
  1701. #if (CFG_SUPPORT_TDLS_DBG == 1)
  1702. {
  1703. UINT8 *pkt = prSkb->data;
  1704. if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
  1705. /* ip */
  1706. u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
  1707. /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */
  1708. DBGLOG(INIT, INFO, "<s> %d\n", u2Identifier);
  1709. }
  1710. }
  1711. #endif
  1712. /* check if WiFi is halt */
  1713. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  1714. DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n");
  1715. dev_kfree_skb(prSkb);
  1716. return NETDEV_TX_OK;
  1717. }
  1718. #if CFG_SUPPORT_HOTSPOT_2_0
  1719. if (prGlueInfo->fgIsDad) {
  1720. /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */
  1721. dev_kfree_skb(prSkb);
  1722. return NETDEV_TX_OK;
  1723. }
  1724. if (prGlueInfo->fgIs6Dad) {
  1725. /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */
  1726. dev_kfree_skb(prSkb);
  1727. return NETDEV_TX_OK;
  1728. }
  1729. #endif
  1730. STATS_TX_TIME_ARRIVE(prSkb);
  1731. prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
  1732. prTxQueue = &prGlueInfo->rTxQueue;
  1733. #if CFG_BOW_TEST
  1734. DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len);
  1735. DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len);
  1736. DBGLOG(BOW, TRACE, "sk_buff->data:\n");
  1737. for (i = 0; i < prSkb->len; i++) {
  1738. DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
  1739. if ((i + 1) % 16 == 0)
  1740. DBGLOG(BOW, TRACE, "\n");
  1741. }
  1742. DBGLOG(BOW, TRACE, "\n");
  1743. #endif
  1744. if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
  1745. /* non-1x packets */
  1746. #if CFG_DBG_GPIO_PINS
  1747. {
  1748. /* TX request from OS */
  1749. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
  1750. kalUdelay(1);
  1751. mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
  1752. }
  1753. #endif
  1754. u2QueueIdx = skb_get_queue_mapping(prSkb);
  1755. ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
  1756. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  1757. GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());
  1758. #endif
  1759. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
  1760. if (u2QueueIdx < CFG_MAX_TXQ_NUM)
  1761. GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
  1762. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1763. QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
  1764. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  1765. /* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */
  1766. /* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */
  1767. if (u2QueueIdx < CFG_MAX_TXQ_NUM) {
  1768. if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >=
  1769. CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
  1770. netif_stop_subqueue(prDev, u2QueueIdx);
  1771. #if (CONF_HIF_LOOPBACK_AUTO == 1)
  1772. prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01;
  1773. #endif /* CONF_HIF_LOOPBACK_AUTO */
  1774. }
  1775. }
  1776. } else {
  1777. /* printk("is security frame\n"); */
  1778. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  1779. }
  1780. DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len);
  1781. prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
  1782. prGlueInfo->rNetDevStats.tx_packets++;
  1783. if (netif_carrier_ok(prDev))
  1784. kalPerMonStart(prGlueInfo);
  1785. /* set GLUE_FLAG_TXREQ_BIT */
  1786. /* pr->u4Flag |= GLUE_FLAG_TXREQ; */
  1787. /* wake_up_interruptible(&prGlueInfo->waitq); */
  1788. kalSetEvent(prGlueInfo);
  1789. /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
  1790. return NETDEV_TX_OK;
  1791. } /* end of wlanHardStartXmit() */
  1792. /*----------------------------------------------------------------------------*/
  1793. /*!
  1794. * \brief A method of struct net_device, to get the network interface statistical
  1795. * information.
  1796. *
  1797. * Whenever an application needs to get statistics for the interface, this method
  1798. * is called. This happens, for example, when ifconfig or netstat -i is run.
  1799. *
  1800. * \param[in] prDev Pointer to struct net_device.
  1801. *
  1802. * \return net_device_stats buffer pointer.
  1803. */
  1804. /*----------------------------------------------------------------------------*/
  1805. struct net_device_stats *wlanGetStats(IN struct net_device *prDev)
  1806. {
  1807. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1808. #if 0
  1809. WLAN_STATUS rStatus;
  1810. UINT_32 u4XmitError = 0;
  1811. UINT_32 u4XmitOk = 0;
  1812. UINT_32 u4RecvError = 0;
  1813. UINT_32 u4RecvOk = 0;
  1814. UINT_32 u4BufLen;
  1815. ASSERT(prDev);
  1816. /* @FIX ME: need a more clear way to do this */
  1817. rStatus = kalIoctl(prGlueInfo,
  1818. wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1819. rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1820. rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1821. rStatus = kalIoctl(prGlueInfo,
  1822. wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen);
  1823. prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
  1824. prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
  1825. prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
  1826. prGlueInfo->rNetDevStats.rx_errors = u4RecvError;
  1827. /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */
  1828. /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */
  1829. /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */
  1830. /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */
  1831. #endif
  1832. /* prGlueInfo->rNetDevStats.rx_packets = 0; */
  1833. /* prGlueInfo->rNetDevStats.tx_packets = 0; */
  1834. prGlueInfo->rNetDevStats.tx_errors = 0;
  1835. prGlueInfo->rNetDevStats.rx_errors = 0;
  1836. /* prGlueInfo->rNetDevStats.rx_bytes = 0; */
  1837. /* prGlueInfo->rNetDevStats.tx_bytes = 0; */
  1838. prGlueInfo->rNetDevStats.rx_errors = 0;
  1839. prGlueInfo->rNetDevStats.multicast = 0;
  1840. return &prGlueInfo->rNetDevStats;
  1841. } /* end of wlanGetStats() */
  1842. /*----------------------------------------------------------------------------*/
  1843. /*!
  1844. * \brief A function for prDev->init
  1845. *
  1846. * \param[in] prDev Pointer to struct net_device.
  1847. *
  1848. * \retval 0 The execution of wlanInit succeeds.
  1849. * \retval -ENXIO No such device.
  1850. */
  1851. /*----------------------------------------------------------------------------*/
  1852. static int wlanInit(struct net_device *prDev)
  1853. {
  1854. P_GLUE_INFO_T prGlueInfo = NULL;
  1855. if (fgIsWorkMcEverInit == FALSE) {
  1856. if (!prDev)
  1857. return -ENXIO;
  1858. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1859. INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
  1860. /* 20150205 work queue for sched_scan */
  1861. INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue);
  1862. fgIsWorkMcEverInit = TRUE;
  1863. }
  1864. return 0; /* success */
  1865. } /* end of wlanInit() */
  1866. /*----------------------------------------------------------------------------*/
  1867. /*!
  1868. * \brief A function for prDev->uninit
  1869. *
  1870. * \param[in] prDev Pointer to struct net_device.
  1871. *
  1872. * \return (none)
  1873. */
  1874. /*----------------------------------------------------------------------------*/
  1875. static void wlanUninit(struct net_device *prDev)
  1876. {
  1877. } /* end of wlanUninit() */
  1878. /*----------------------------------------------------------------------------*/
  1879. /*!
  1880. * \brief A function for prDev->open
  1881. *
  1882. * \param[in] prDev Pointer to struct net_device.
  1883. *
  1884. * \retval 0 The execution of wlanOpen succeeds.
  1885. * \retval < 0 The execution of wlanOpen failed.
  1886. */
  1887. /*----------------------------------------------------------------------------*/
  1888. static int wlanOpen(struct net_device *prDev)
  1889. {
  1890. ASSERT(prDev);
  1891. netif_tx_start_all_queues(prDev);
  1892. return 0; /* success */
  1893. } /* end of wlanOpen() */
  1894. /*----------------------------------------------------------------------------*/
  1895. /*!
  1896. * \brief A function for prDev->stop
  1897. *
  1898. * \param[in] prDev Pointer to struct net_device.
  1899. *
  1900. * \retval 0 The execution of wlanStop succeeds.
  1901. * \retval < 0 The execution of wlanStop failed.
  1902. */
  1903. /*----------------------------------------------------------------------------*/
  1904. static int wlanStop(struct net_device *prDev)
  1905. {
  1906. P_GLUE_INFO_T prGlueInfo = NULL;
  1907. struct cfg80211_scan_request *prScanRequest = NULL;
  1908. GLUE_SPIN_LOCK_DECLARATION();
  1909. ASSERT(prDev);
  1910. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  1911. /* CFG80211 down */
  1912. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1913. if (prGlueInfo->prScanRequest != NULL) {
  1914. prScanRequest = prGlueInfo->prScanRequest;
  1915. prGlueInfo->prScanRequest = NULL;
  1916. }
  1917. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
  1918. if (prScanRequest)
  1919. cfg80211_scan_done(prScanRequest, TRUE);
  1920. netif_tx_stop_all_queues(prDev);
  1921. return 0; /* success */
  1922. } /* end of wlanStop() */
  1923. /*----------------------------------------------------------------------------*/
  1924. /*!
  1925. * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
  1926. *
  1927. * \param[in] prGlueInfo Pointer to glue info
  1928. *
  1929. * \return none
  1930. */
  1931. /*----------------------------------------------------------------------------*/
  1932. VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo)
  1933. {
  1934. UINT_8 i, j;
  1935. UINT_8 ucNumOfChannel;
  1936. RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
  1937. /* 1. Disable all channel */
  1938. for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
  1939. mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
  1940. mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
  1941. }
  1942. for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
  1943. mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
  1944. mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED;
  1945. }
  1946. /* 2. Get current domain channel list */
  1947. rlmDomainGetChnlList(prGlueInfo->prAdapter,
  1948. BAND_NULL,
  1949. ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
  1950. &ucNumOfChannel, aucChannelList);
  1951. /* 3. Enable specific channel based on domain channel list */
  1952. for (i = 0; i < ucNumOfChannel; i++) {
  1953. switch (aucChannelList[i].eBand) {
  1954. case BAND_2G4:
  1955. for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) {
  1956. if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
  1957. mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
  1958. mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
  1959. break;
  1960. }
  1961. }
  1962. break;
  1963. case BAND_5G:
  1964. for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) {
  1965. if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
  1966. mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
  1967. mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED;
  1968. break;
  1969. }
  1970. }
  1971. break;
  1972. default:
  1973. break;
  1974. }
  1975. }
  1976. }
  1977. /*----------------------------------------------------------------------------*/
  1978. /*!
  1979. * \brief Register the device to the kernel and return the index.
  1980. *
  1981. * \param[in] prDev Pointer to struct net_device.
  1982. *
  1983. * \retval 0 The execution of wlanNetRegister succeeds.
  1984. * \retval < 0 The execution of wlanNetRegister failed.
  1985. */
  1986. /*----------------------------------------------------------------------------*/
  1987. static INT_32 wlanNetRegister(struct wireless_dev *prWdev)
  1988. {
  1989. P_GLUE_INFO_T prGlueInfo;
  1990. INT_32 i4DevIdx = -1;
  1991. ASSERT(prWdev);
  1992. do {
  1993. if (!prWdev)
  1994. break;
  1995. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  1996. i4DevIdx = wlanGetDevIdx(prWdev->netdev);
  1997. if (i4DevIdx < 0) {
  1998. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n");
  1999. break;
  2000. }
  2001. /* adjust channel support status */
  2002. wlanUpdateChannelTable(prGlueInfo);
  2003. #if !CFG_SUPPORT_PERSIST_NETDEV
  2004. if (register_netdev(prWdev->netdev) < 0) {
  2005. DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n");
  2006. wiphy_unregister(prWdev->wiphy);
  2007. wlanClearDevIdx(prWdev->netdev);
  2008. i4DevIdx = -1;
  2009. }
  2010. #endif
  2011. if (i4DevIdx != -1)
  2012. prGlueInfo->fgIsRegistered = TRUE;
  2013. } while (FALSE);
  2014. return i4DevIdx; /* success */
  2015. } /* end of wlanNetRegister() */
  2016. /*----------------------------------------------------------------------------*/
  2017. /*!
  2018. * \brief Unregister the device from the kernel
  2019. *
  2020. * \param[in] prWdev Pointer to struct net_device.
  2021. *
  2022. * \return (none)
  2023. */
  2024. /*----------------------------------------------------------------------------*/
  2025. static VOID wlanNetUnregister(struct wireless_dev *prWdev)
  2026. {
  2027. P_GLUE_INFO_T prGlueInfo;
  2028. if (!prWdev) {
  2029. DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n");
  2030. return;
  2031. }
  2032. DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev);
  2033. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2034. wlanClearDevIdx(prWdev->netdev);
  2035. #if !CFG_SUPPORT_PERSIST_NETDEV
  2036. unregister_netdev(prWdev->netdev);
  2037. #endif
  2038. prGlueInfo->fgIsRegistered = FALSE;
  2039. DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex);
  2040. } /* end of wlanNetUnregister() */
  2041. static const struct net_device_ops wlan_netdev_ops = {
  2042. .ndo_open = wlanOpen,
  2043. .ndo_stop = wlanStop,
  2044. .ndo_set_rx_mode = wlanSetMulticastList,
  2045. .ndo_get_stats = wlanGetStats,
  2046. .ndo_do_ioctl = wlanDoIOCTL,
  2047. .ndo_start_xmit = wlanHardStartXmit,
  2048. .ndo_init = wlanInit,
  2049. .ndo_uninit = wlanUninit,
  2050. .ndo_select_queue = wlanSelectQueue,
  2051. };
  2052. /*----------------------------------------------------------------------------*/
  2053. /*!
  2054. * \brief A method for creating Linux NET4 struct net_device object and the
  2055. * private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
  2056. * Assign the function pointer to the net_device object
  2057. *
  2058. * \param[in] pvData Memory address for the device
  2059. *
  2060. * \retval Not null The wireless_dev object.
  2061. * \retval NULL Fail to create wireless_dev object
  2062. */
  2063. /*----------------------------------------------------------------------------*/
  2064. static struct lock_class_key rSpinKey[SPIN_LOCK_NUM];
  2065. static struct wireless_dev *wlanNetCreate(PVOID pvData)
  2066. {
  2067. P_GLUE_INFO_T prGlueInfo = NULL;
  2068. struct wireless_dev *prWdev = gprWdev;
  2069. UINT_32 i;
  2070. struct device *prDev;
  2071. if (!prWdev) {
  2072. DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n");
  2073. return NULL;
  2074. }
  2075. /* 4 <1> co-relate wiphy & prDev */
  2076. #if MTK_WCN_HIF_SDIO
  2077. mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev);
  2078. #else
  2079. /* prDev = &((struct sdio_func *) pvData)->dev; //samp */
  2080. prDev = pvData; /* samp */
  2081. #endif
  2082. if (!prDev)
  2083. DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n");
  2084. /* don't set prDev as parent of wiphy->dev, because we have done device_add
  2085. in driver init. if we set parent here, parent will be not able to know this child,
  2086. and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent
  2087. has been freed. */
  2088. /*set_wiphy_dev(prWdev->wiphy, prDev);*/
  2089. #if !CFG_SUPPORT_PERSIST_NETDEV
  2090. /* 4 <3> Initial Glue structure */
  2091. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2092. kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T));
  2093. /* 4 <3.1> Create net device */
  2094. #if CFG_TC1_FEATURE
  2095. if (wlan_if_changed) {
  2096. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE,
  2097. NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
  2098. } else {
  2099. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  2100. ether_setup, CFG_MAX_TXQ_NUM);
  2101. }
  2102. #else
  2103. prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE,
  2104. ether_setup, CFG_MAX_TXQ_NUM);
  2105. #endif
  2106. if (!prGlueInfo->prDevHandler) {
  2107. DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n");
  2108. return NULL;
  2109. }
  2110. DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n",
  2111. prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex);
  2112. /* 4 <3.1.1> initialize net device varaiables */
  2113. *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
  2114. prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
  2115. #ifdef CONFIG_WIRELESS_EXT
  2116. prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
  2117. #endif
  2118. netif_carrier_off(prGlueInfo->prDevHandler);
  2119. netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
  2120. /* 4 <3.1.2> co-relate with wiphy bi-directionally */
  2121. prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
  2122. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2123. prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM;
  2124. #endif
  2125. prWdev->netdev = prGlueInfo->prDevHandler;
  2126. /* 4 <3.1.3> co-relate net device & prDev */
  2127. /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/
  2128. SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev);
  2129. #else /* CFG_SUPPORT_PERSIST_NETDEV */
  2130. prGlueInfo->prDevHandler = gprWdev->netdev;
  2131. #endif /* CFG_SUPPORT_PERSIST_NETDEV */
  2132. /* 4 <3.2> initiali glue variables */
  2133. prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
  2134. prGlueInfo->ePowerState = ParamDeviceStateD0;
  2135. prGlueInfo->fgIsMacAddrOverride = FALSE;
  2136. prGlueInfo->fgIsRegistered = FALSE;
  2137. prGlueInfo->prScanRequest = NULL;
  2138. #if CFG_SUPPORT_HOTSPOT_2_0
  2139. /* Init DAD */
  2140. prGlueInfo->fgIsDad = FALSE;
  2141. prGlueInfo->fgIs6Dad = FALSE;
  2142. kalMemZero(prGlueInfo->aucDADipv4, 4);
  2143. kalMemZero(prGlueInfo->aucDADipv6, 16);
  2144. #endif
  2145. init_completion(&prGlueInfo->rScanComp);
  2146. init_completion(&prGlueInfo->rHaltComp);
  2147. init_completion(&prGlueInfo->rPendComp);
  2148. #if CFG_ENABLE_WIFI_DIRECT
  2149. init_completion(&prGlueInfo->rSubModComp);
  2150. #endif
  2151. /* initialize timer for OID timeout checker */
  2152. kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
  2153. for (i = 0; i < SPIN_LOCK_NUM; i++) {
  2154. spin_lock_init(&prGlueInfo->rSpinLock[i]);
  2155. lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]);
  2156. }
  2157. /* initialize semaphore for ioctl */
  2158. sema_init(&prGlueInfo->ioctl_sem, 1);
  2159. glSetHifInfo(prGlueInfo, (ULONG) pvData);
  2160. /* 4 <8> Init Queues */
  2161. init_waitqueue_head(&prGlueInfo->waitq);
  2162. QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
  2163. QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
  2164. /* 4 <4> Create Adapter structure */
  2165. prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
  2166. if (!prGlueInfo->prAdapter) {
  2167. DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n");
  2168. return NULL;
  2169. }
  2170. KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR");
  2171. #if CFG_SUPPORT_PERSIST_NETDEV
  2172. dev_open(prGlueInfo->prDevHandler);
  2173. netif_carrier_off(prGlueInfo->prDevHandler);
  2174. netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
  2175. #endif
  2176. return prWdev;
  2177. } /* end of wlanNetCreate() */
  2178. /*----------------------------------------------------------------------------*/
  2179. /*!
  2180. * \brief Destroying the struct net_device object and the private data.
  2181. *
  2182. * \param[in] prWdev Pointer to struct wireless_dev.
  2183. *
  2184. * \return (none)
  2185. */
  2186. /*----------------------------------------------------------------------------*/
  2187. static VOID wlanNetDestroy(struct wireless_dev *prWdev)
  2188. {
  2189. P_GLUE_INFO_T prGlueInfo = NULL;
  2190. ASSERT(prWdev);
  2191. if (!prWdev) {
  2192. DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n");
  2193. return;
  2194. }
  2195. /* prGlueInfo is allocated with net_device */
  2196. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2197. ASSERT(prGlueInfo);
  2198. /* destroy kal OS timer */
  2199. kalCancelTimer(prGlueInfo);
  2200. glClearHifInfo(prGlueInfo);
  2201. wlanAdapterDestroy(prGlueInfo->prAdapter);
  2202. prGlueInfo->prAdapter = NULL;
  2203. #if CFG_SUPPORT_PERSIST_NETDEV
  2204. /* take the net_device to down state */
  2205. dev_close(prGlueInfo->prDevHandler);
  2206. #else
  2207. /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */
  2208. free_netdev(prWdev->netdev);
  2209. #endif
  2210. } /* end of wlanNetDestroy() */
  2211. #ifndef CONFIG_X86
  2212. UINT_8 g_aucBufIpAddr[32] = { 0 };
  2213. static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend)
  2214. {
  2215. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2216. UINT_32 u4SetInfoLen;
  2217. rStatus = kalIoctl(prGlueInfo,
  2218. wlanoidNotifyFwSuspend,
  2219. (PVOID)&fgSuspend,
  2220. sizeof(fgSuspend),
  2221. FALSE,
  2222. FALSE,
  2223. TRUE,
  2224. FALSE,
  2225. &u4SetInfoLen);
  2226. if (rStatus != WLAN_STATUS_SUCCESS)
  2227. DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n");
  2228. }
  2229. void wlanHandleSystemSuspend(void)
  2230. {
  2231. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2232. struct net_device *prDev = NULL;
  2233. P_GLUE_INFO_T prGlueInfo = NULL;
  2234. UINT_8 ip[4] = { 0 };
  2235. UINT_32 u4NumIPv4 = 0;
  2236. #ifdef CONFIG_IPV6
  2237. UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
  2238. UINT_32 u4NumIPv6 = 0;
  2239. #endif
  2240. UINT_32 i;
  2241. P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
  2242. #if CFG_SUPPORT_DROP_MC_PACKET
  2243. UINT_32 u4PacketFilter = 0;
  2244. UINT_32 u4SetInfoLen = 0;
  2245. #endif
  2246. /* <1> Sanity check and acquire the net_device */
  2247. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  2248. if (u4WlanDevNum == 0) {
  2249. DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n");
  2250. return;
  2251. }
  2252. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  2253. fgIsUnderSuspend = true;
  2254. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  2255. ASSERT(prGlueInfo);
  2256. #if CFG_SUPPORT_DROP_MC_PACKET
  2257. /* new filter should not include p2p mask */
  2258. #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
  2259. u4PacketFilter = prGlueInfo->prAdapter->u4OsPacketFilter & (~PARAM_PACKET_FILTER_P2P_MASK);
  2260. #endif
  2261. if (kalIoctl(prGlueInfo,
  2262. wlanoidSetCurrentPacketFilter,
  2263. &u4PacketFilter,
  2264. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  2265. DBGLOG(INIT, ERROR, "set packet filter failed.\n");
  2266. }
  2267. #endif
  2268. if (!prDev || !(prDev->ip_ptr) ||
  2269. !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
  2270. !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
  2271. goto notify_suspend;
  2272. }
  2273. kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
  2274. /* todo: traverse between list to find whole sets of IPv4 addresses */
  2275. if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
  2276. u4NumIPv4++;
  2277. #ifdef CONFIG_IPV6
  2278. if (!prDev || !(prDev->ip6_ptr) ||
  2279. !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
  2280. !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
  2281. goto notify_suspend;
  2282. }
  2283. kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
  2284. DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
  2285. ip6[0], ip6[1], ip6[2], ip6[3],
  2286. ip6[4], ip6[5], ip6[6], ip6[7],
  2287. ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
  2288. );
  2289. /* todo: traverse between list to find whole sets of IPv6 addresses */
  2290. if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) {
  2291. /* Do nothing */
  2292. /* u4NumIPv6++; */
  2293. }
  2294. #endif
  2295. /* <7> set up the ARP filter */
  2296. {
  2297. UINT_32 u4SetInfoLen = 0;
  2298. UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
  2299. P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
  2300. P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
  2301. kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
  2302. prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
  2303. prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2304. for (i = 0; i < u4NumIPv4; i++) {
  2305. prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */
  2306. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2307. prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
  2308. kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
  2309. prParamNetAddr =
  2310. (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
  2311. u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
  2312. }
  2313. #ifdef CONFIG_IPV6
  2314. for (i = 0; i < u4NumIPv6; i++) {
  2315. prParamNetAddr->u2AddressLength = 6;
  2316. prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2317. kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
  2318. prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6));
  2319. u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
  2320. }
  2321. #endif
  2322. ASSERT(u4Len <= sizeof(g_aucBufIpAddr));
  2323. rStatus = kalIoctl(prGlueInfo,
  2324. wlanoidSetNetworkAddress,
  2325. (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2326. }
  2327. notify_suspend:
  2328. DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus);
  2329. if (rStatus != WLAN_STATUS_SUCCESS)
  2330. wlanNotifyFwSuspend(prGlueInfo, TRUE);
  2331. }
  2332. void wlanHandleSystemResume(void)
  2333. {
  2334. struct net_device *prDev = NULL;
  2335. P_GLUE_INFO_T prGlueInfo = NULL;
  2336. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2337. UINT_8 ip[4] = { 0 };
  2338. #ifdef CONFIG_IPV6
  2339. UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
  2340. #endif
  2341. EVENT_AIS_BSS_INFO_T rParam;
  2342. UINT_32 u4BufLen = 0;
  2343. #if CFG_SUPPORT_DROP_MC_PACKET
  2344. UINT_32 u4PacketFilter = 0;
  2345. UINT_32 u4SetInfoLen = 0;
  2346. #endif
  2347. /* <1> Sanity check and acquire the net_device */
  2348. ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
  2349. if (u4WlanDevNum == 0) {
  2350. DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n");
  2351. return;
  2352. }
  2353. prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev;
  2354. /* ASSERT(prDev); */
  2355. fgIsUnderSuspend = false;
  2356. if (!prDev) {
  2357. DBGLOG(INIT, INFO, "prDev == NULL!!!\n");
  2358. return;
  2359. }
  2360. /* <3> acquire the prGlueInfo */
  2361. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  2362. ASSERT(prGlueInfo);
  2363. #if CFG_SUPPORT_DROP_MC_PACKET
  2364. /* new filter should not include p2p mask */
  2365. #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
  2366. u4PacketFilter = prGlueInfo->prAdapter->u4OsPacketFilter & (~PARAM_PACKET_FILTER_P2P_MASK);
  2367. #endif
  2368. if (kalIoctl(prGlueInfo,
  2369. wlanoidSetCurrentPacketFilter,
  2370. &u4PacketFilter,
  2371. sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
  2372. DBGLOG(INIT, ERROR, "set packet filter failed.\n");
  2373. }
  2374. #endif
  2375. /*
  2376. We will receive the event in rx, we will check if the status is the same in driver
  2377. and FW, if not the same, trigger disconnetion procedure.
  2378. */
  2379. kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T));
  2380. rStatus = kalIoctl(prGlueInfo,
  2381. wlanoidQueryBSSInfo,
  2382. &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
  2383. if (rStatus != WLAN_STATUS_SUCCESS) {
  2384. DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus);
  2385. }
  2386. /* <2> get the IPv4 address */
  2387. if (!(prDev->ip_ptr) ||
  2388. !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
  2389. !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
  2390. goto notify_resume;
  2391. }
  2392. /* <4> copy the IPv4 address */
  2393. kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
  2394. #ifdef CONFIG_IPV6
  2395. /* <5> get the IPv6 address */
  2396. if (!prDev || !(prDev->ip6_ptr) ||
  2397. !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
  2398. !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
  2399. goto notify_resume;
  2400. }
  2401. /* <6> copy the IPv6 address */
  2402. kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
  2403. DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
  2404. ip6[0], ip6[1], ip6[2], ip6[3],
  2405. ip6[4], ip6[5], ip6[6], ip6[7],
  2406. ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]
  2407. );
  2408. #endif
  2409. /* <7> clear the ARP filter */
  2410. {
  2411. UINT_32 u4SetInfoLen = 0;
  2412. /* UINT_8 aucBuf[32] = {0}; */
  2413. UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
  2414. P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr;
  2415. /* aucBuf; */
  2416. kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
  2417. prParamNetAddrList->u4AddressCount = 0;
  2418. prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
  2419. ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
  2420. rStatus = kalIoctl(prGlueInfo,
  2421. wlanoidSetNetworkAddress,
  2422. (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2423. }
  2424. notify_resume:
  2425. DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n",
  2426. rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive,
  2427. ip[0], ip[1], ip[2], ip[3], rStatus);
  2428. if (rStatus != WLAN_STATUS_SUCCESS) {
  2429. wlanNotifyFwSuspend(prGlueInfo, FALSE);
  2430. }
  2431. }
  2432. #endif /* ! CONFIG_X86 */
  2433. int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode)
  2434. {
  2435. #if 0
  2436. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
  2437. PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
  2438. WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
  2439. UINT_32 u4BufLen = 0;
  2440. rSetP2P.u4Enable = p2pmode.u4Enable;
  2441. rSetP2P.u4Mode = p2pmode.u4Mode;
  2442. if (!rSetP2P.u4Enable)
  2443. p2pNetUnregister(prGlueInfo, TRUE);
  2444. rWlanStatus = kalIoctl(prGlueInfo,
  2445. wlanoidSetP2pMode,
  2446. (PVOID) &rSetP2P,
  2447. sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  2448. DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus);
  2449. if (rSetP2P.u4Enable)
  2450. p2pNetRegister(prGlueInfo, TRUE);
  2451. return 0;
  2452. #else
  2453. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev));
  2454. PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P;
  2455. WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
  2456. BOOLEAN fgIsP2PEnding;
  2457. UINT_32 u4BufLen = 0;
  2458. GLUE_SPIN_LOCK_DECLARATION();
  2459. DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode);
  2460. /* avoid remove & p2p off command simultaneously */
  2461. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2462. fgIsP2PEnding = g_u4P2PEnding;
  2463. g_u4P2POnOffing = 1;
  2464. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2465. if (fgIsP2PEnding == 1) {
  2466. /* skip the command if we are removing */
  2467. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2468. g_u4P2POnOffing = 0;
  2469. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2470. return 0;
  2471. }
  2472. rSetP2P.u4Enable = p2pmode.u4Enable;
  2473. rSetP2P.u4Mode = p2pmode.u4Mode;
  2474. #if !CFG_SUPPORT_PERSIST_NETDEV
  2475. if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE))
  2476. p2pNetUnregister(prGlueInfo, TRUE);
  2477. #endif
  2478. /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */
  2479. /*
  2480. Scenario:
  2481. 1. System enters suspend/resume but not yet enter wlanearlysuspend()
  2482. or wlanlateresume();
  2483. 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl()
  2484. and get g_halt_sem then do glRegisterEarlySuspend() or
  2485. glUnregisterEarlySuspend();
  2486. But system suspend/resume procedure is not yet finished so we
  2487. suspend;
  2488. 3. System switches back to do suspend/resume procedure and execute
  2489. kalIoctl(). But driver does not yet release g_halt_sem so system
  2490. suspend in wlanearlysuspend() or wlanlateresume();
  2491. ==> deadlock occurs.
  2492. */
  2493. rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */
  2494. sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  2495. #if !CFG_SUPPORT_PERSIST_NETDEV
  2496. /* Need to check fgIsP2PRegistered, in case of whole chip reset.
  2497. * in this case, kalIOCTL return success always,
  2498. * and prGlueInfo->prP2pInfo may be NULL */
  2499. if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE))
  2500. p2pNetRegister(prGlueInfo, TRUE);
  2501. #endif
  2502. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2503. g_u4P2POnOffing = 0;
  2504. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2505. return 0;
  2506. #endif
  2507. }
  2508. static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM])
  2509. {
  2510. kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule));
  2511. kalPrint("[wlan] change debug level");
  2512. }
  2513. /*----------------------------------------------------------------------------*/
  2514. /*!
  2515. * \brief Wlan probe function. This function probes and initializes the device.
  2516. *
  2517. * \param[in] pvData data passed by bus driver init function
  2518. * _HIF_EHPI: NULL
  2519. * _HIF_SDIO: sdio bus driver handle
  2520. *
  2521. * \retval 0 Success
  2522. * \retval negative value Failed
  2523. */
  2524. /*----------------------------------------------------------------------------*/
  2525. static INT_32 wlanProbe(PVOID pvData)
  2526. {
  2527. struct wireless_dev *prWdev = NULL;
  2528. enum probe_fail_reason {
  2529. BUS_INIT_FAIL,
  2530. NET_CREATE_FAIL,
  2531. BUS_SET_IRQ_FAIL,
  2532. ADAPTER_START_FAIL,
  2533. NET_REGISTER_FAIL,
  2534. PROC_INIT_FAIL,
  2535. FAIL_REASON_NUM
  2536. } eFailReason;
  2537. P_WLANDEV_INFO_T prWlandevInfo = NULL;
  2538. INT_32 i4DevIdx = 0;
  2539. P_GLUE_INFO_T prGlueInfo = NULL;
  2540. P_ADAPTER_T prAdapter = NULL;
  2541. INT_32 i4Status = 0;
  2542. BOOLEAN bRet = FALSE;
  2543. eFailReason = FAIL_REASON_NUM;
  2544. do {
  2545. /* 4 <1> Initialize the IO port of the interface */
  2546. /* GeorgeKuo: pData has different meaning for _HIF_XXX:
  2547. * _HIF_EHPI: pointer to memory base variable, which will be
  2548. * initialized by glBusInit().
  2549. * _HIF_SDIO: bus driver handle
  2550. */
  2551. bRet = glBusInit(pvData);
  2552. wlanDebugInit();
  2553. /* Cannot get IO address from interface */
  2554. if (FALSE == bRet) {
  2555. DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n");
  2556. i4Status = -EIO;
  2557. eFailReason = BUS_INIT_FAIL;
  2558. break;
  2559. }
  2560. /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */
  2561. prWdev = wlanNetCreate(pvData);
  2562. if (prWdev == NULL) {
  2563. DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n");
  2564. i4Status = -ENOMEM;
  2565. eFailReason = NET_CREATE_FAIL;
  2566. break;
  2567. }
  2568. /* 4 <2.5> Set the ioaddr to HIF Info */
  2569. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
  2570. gPrDev = prGlueInfo->prDevHandler;
  2571. /* 4 <4> Setup IRQ */
  2572. prWlandevInfo = &arWlanDevInfo[i4DevIdx];
  2573. i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2574. if (i4Status != WLAN_STATUS_SUCCESS) {
  2575. DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n");
  2576. eFailReason = BUS_SET_IRQ_FAIL;
  2577. break;
  2578. }
  2579. prGlueInfo->i4DevIdx = i4DevIdx;
  2580. prAdapter = prGlueInfo->prAdapter;
  2581. prGlueInfo->u4ReadyFlag = 0;
  2582. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2583. prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
  2584. #endif
  2585. #if CFG_SUPPORT_CFG_FILE
  2586. {
  2587. PUINT_8 pucConfigBuf;
  2588. UINT_32 u4ConfigReadLen;
  2589. wlanCfgInit(prAdapter, NULL, 0, 0);
  2590. pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE);
  2591. u4ConfigReadLen = 0;
  2592. DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n");
  2593. if (pucConfigBuf) {
  2594. kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE);
  2595. if (kalReadToFile("/data/misc/wifi.cfg",
  2596. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2597. DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n");
  2598. } else if (kalReadToFile("/data/misc/wifi/wifi.cfg",
  2599. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2600. DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n");
  2601. } else if (kalReadToFile("/etc/firmware/wifi.cfg",
  2602. pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) {
  2603. DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n");
  2604. }
  2605. if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0)
  2606. wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0);
  2607. kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE);
  2608. } /* pucConfigBuf */
  2609. }
  2610. #endif
  2611. /* 4 <5> Start Device */
  2612. /* */
  2613. #if CFG_ENABLE_FW_DOWNLOAD
  2614. DBGLOG(INIT, TRACE, "start to download firmware...\n");
  2615. /* before start adapter, we need to open and load firmware */
  2616. {
  2617. UINT_32 u4FwSize = 0;
  2618. PVOID prFwBuffer = NULL;
  2619. P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
  2620. /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
  2621. kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
  2622. prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
  2623. prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS;
  2624. /* Load NVRAM content to REG_INFO_T */
  2625. glLoadNvram(prGlueInfo, prRegInfo);
  2626. #if CFG_SUPPORT_CFG_FILE
  2627. wlanCfgApply(prAdapter);
  2628. #endif
  2629. /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */
  2630. prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
  2631. prRegInfo->fgEnArpFilter = TRUE;
  2632. if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
  2633. i4Status = -EIO;
  2634. DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n");
  2635. goto bailout;
  2636. } else {
  2637. if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer,
  2638. u4FwSize) != WLAN_STATUS_SUCCESS) {
  2639. i4Status = -EIO;
  2640. }
  2641. }
  2642. kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
  2643. bailout:
  2644. /* kfree(prRegInfo); */
  2645. DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status);
  2646. if (i4Status < 0) {
  2647. GL_HIF_INFO_T *HifInfo;
  2648. UINT_32 u4FwCnt;
  2649. DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n");
  2650. HifInfo = &prAdapter->prGlueInfo->rHifInfo;
  2651. for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++)
  2652. DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR));
  2653. /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */
  2654. /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */
  2655. /* dump HIF register may be hung */
  2656. if (!fgIsBusAccessFailed)
  2657. HifRegDump(prGlueInfo->prAdapter);
  2658. /* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */
  2659. /* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */
  2660. eFailReason = ADAPTER_START_FAIL;
  2661. break;
  2662. }
  2663. }
  2664. #else
  2665. /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */
  2666. kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
  2667. P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
  2668. /* Load NVRAM content to REG_INFO_T */
  2669. glLoadNvram(prGlueInfo, prRegInfo);
  2670. prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
  2671. if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
  2672. i4Status = -EIO;
  2673. eFailReason = ADAPTER_START_FAIL;
  2674. break;
  2675. }
  2676. #endif
  2677. if (FALSE == prAdapter->fgEnable5GBand)
  2678. prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
  2679. prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
  2680. g_u4HaltFlag = 0;
  2681. #if CFG_SUPPORT_ROAMING_ENC
  2682. /* adjust roaming threshold */
  2683. {
  2684. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2685. CMD_ROAMING_INFO_T rRoamingInfo;
  2686. UINT_32 u4SetInfoLen = 0;
  2687. prAdapter->fgIsRoamingEncEnabled = TRUE;
  2688. /* suggestion from Tsaiyuan.Hsu */
  2689. kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T));
  2690. rRoamingInfo.fgIsFastRoamingApplied = TRUE;
  2691. DBGLOG(INIT, TRACE, "Enable roaming enhance function\n");
  2692. rStatus = kalIoctl(prGlueInfo,
  2693. wlanoidSetRoamingInfo,
  2694. &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
  2695. if (rStatus != WLAN_STATUS_SUCCESS)
  2696. DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus);
  2697. }
  2698. #endif /* CFG_SUPPORT_ROAMING_ENC */
  2699. #if (CFG_SUPPORT_TXR_ENC == 1)
  2700. /* adjust tx rate switch threshold */
  2701. rlmTxRateEnhanceConfig(prGlueInfo->prAdapter);
  2702. #endif /* CFG_SUPPORT_TXR_ENC */
  2703. /* set MAC address */
  2704. {
  2705. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2706. struct sockaddr MacAddr;
  2707. UINT_32 u4SetInfoLen = 0;
  2708. kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data));
  2709. rStatus = kalIoctl(prGlueInfo,
  2710. wlanoidQueryCurrentAddr,
  2711. &MacAddr.sa_data,
  2712. PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen);
  2713. if (rStatus != WLAN_STATUS_SUCCESS) {
  2714. DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus);
  2715. prGlueInfo->u4ReadyFlag = 0;
  2716. } else {
  2717. ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data));
  2718. ether_addr_copy(prGlueInfo->prDevHandler->perm_addr,
  2719. prGlueInfo->prDevHandler->dev_addr);
  2720. /* card is ready */
  2721. prGlueInfo->u4ReadyFlag = 1;
  2722. #if CFG_SHOW_MACADDR_SOURCE
  2723. DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data));
  2724. #endif
  2725. }
  2726. }
  2727. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  2728. /* set HW checksum offload */
  2729. {
  2730. WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
  2731. UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
  2732. UINT_32 u4SetInfoLen = 0;
  2733. rStatus = kalIoctl(prGlueInfo,
  2734. wlanoidSetCSUMOffload,
  2735. (PVOID) &u4CSUMFlags,
  2736. sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  2737. if (rStatus != WLAN_STATUS_SUCCESS)
  2738. DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus);
  2739. }
  2740. #endif
  2741. /* 4 <3> Register the card */
  2742. DBGLOG(INIT, TRACE, "wlanNetRegister...\n");
  2743. i4DevIdx = wlanNetRegister(prWdev);
  2744. if (i4DevIdx < 0) {
  2745. i4Status = -ENXIO;
  2746. DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n");
  2747. eFailReason = NET_REGISTER_FAIL;
  2748. break;
  2749. }
  2750. wlanRegisterNotifier();
  2751. /* 4 <6> Initialize /proc filesystem */
  2752. #ifdef WLAN_INCLUDE_PROC
  2753. DBGLOG(INIT, TRACE, "init procfs...\n");
  2754. i4Status = procCreateFsEntry(prGlueInfo);
  2755. if (i4Status < 0) {
  2756. DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n");
  2757. eFailReason = PROC_INIT_FAIL;
  2758. break;
  2759. }
  2760. #endif /* WLAN_INCLUDE_PROC */
  2761. #if CFG_ENABLE_BT_OVER_WIFI
  2762. prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
  2763. prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
  2764. glRegisterAmpc(prGlueInfo);
  2765. #endif
  2766. #if CFG_ENABLE_WIFI_DIRECT
  2767. DBGLOG(INIT, TRACE, "wlanSubModInit...\n");
  2768. /* wlan is launched */
  2769. prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
  2770. /* if p2p module is inserted, notify tx_thread to init p2p network */
  2771. if (rSubModHandler[P2P_MODULE].subModInit)
  2772. wlanSubModInit(prGlueInfo);
  2773. /* register set_p2p_mode handler to mtk_wmt_wifi */
  2774. register_set_p2p_mode_handler(set_p2p_mode_handler);
  2775. #endif
  2776. #if CFG_SPM_WORKAROUND_FOR_HOTSPOT
  2777. if (glIsChipNeedWakelock(prGlueInfo))
  2778. KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP");
  2779. #endif
  2780. } while (FALSE);
  2781. if (i4Status != WLAN_STATUS_SUCCESS) {
  2782. switch (eFailReason) {
  2783. case PROC_INIT_FAIL:
  2784. wlanNetUnregister(prWdev);
  2785. set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
  2786. /* wake up main thread */
  2787. wake_up_interruptible(&prGlueInfo->waitq);
  2788. /* wait main thread stops */
  2789. wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
  2790. KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
  2791. wlanAdapterStop(prAdapter);
  2792. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2793. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2794. wlanNetDestroy(prWdev);
  2795. break;
  2796. case NET_REGISTER_FAIL:
  2797. set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag);
  2798. /* wake up main thread */
  2799. wake_up_interruptible(&prGlueInfo->waitq);
  2800. /* wait main thread stops */
  2801. wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
  2802. KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock);
  2803. wlanAdapterStop(prAdapter);
  2804. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2805. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2806. wlanNetDestroy(prWdev);
  2807. break;
  2808. case ADAPTER_START_FAIL:
  2809. glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
  2810. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2811. wlanNetDestroy(prWdev);
  2812. break;
  2813. case BUS_SET_IRQ_FAIL:
  2814. KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock);
  2815. wlanNetDestroy(prWdev);
  2816. break;
  2817. case NET_CREATE_FAIL:
  2818. break;
  2819. case BUS_INIT_FAIL:
  2820. break;
  2821. default:
  2822. break;
  2823. }
  2824. }
  2825. #if CFG_ENABLE_WIFI_DIRECT
  2826. {
  2827. GLUE_SPIN_LOCK_DECLARATION();
  2828. GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock);
  2829. g_u4P2PEnding = 0;
  2830. GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock);
  2831. }
  2832. #endif
  2833. #if CFG_SUPPORT_AGPS_ASSIST
  2834. if (i4Status == WLAN_STATUS_SUCCESS)
  2835. kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0);
  2836. #endif
  2837. #if (CFG_SUPPORT_MET_PROFILING == 1)
  2838. {
  2839. int iMetInitRet = WLAN_STATUS_FAILURE;
  2840. if (i4Status == WLAN_STATUS_SUCCESS) {
  2841. DBGLOG(INIT, TRACE, "init MET procfs...\n");
  2842. iMetInitRet = kalMetInitProcfs(prGlueInfo);
  2843. if (iMetInitRet < 0)
  2844. DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n");
  2845. }
  2846. }
  2847. #endif
  2848. if (i4Status == WLAN_STATUS_SUCCESS) {
  2849. /*Init performance monitor structure */
  2850. kalPerMonInit(prGlueInfo);
  2851. /* probe ok */
  2852. DBGLOG(INIT, TRACE, "wlanProbe ok\n");
  2853. } else {
  2854. /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag,
  2855. * because even this function returns
  2856. * error, we can also call core dump but only core dump failed. */
  2857. if (g_IsNeedDoChipReset)
  2858. mtk_wcn_set_connsys_power_off_flag(0);
  2859. /* probe failed */
  2860. DBGLOG(INIT, ERROR, "wlanProbe failed\n");
  2861. }
  2862. return i4Status;
  2863. } /* end of wlanProbe() */
  2864. /*----------------------------------------------------------------------------*/
  2865. /*!
  2866. * \brief A method to stop driver operation and release all resources. Following
  2867. * this call, no frame should go up or down through this interface.
  2868. *
  2869. * \return (none)
  2870. */
  2871. /*----------------------------------------------------------------------------*/
  2872. static VOID wlanRemove(VOID)
  2873. {
  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. g_u4HaltFlag = 1; /* 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. down(&g_halt_sem);
  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. up(&g_halt_sem);
  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