gl_init.c 113 KB

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