nic_tx.c 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2
  3. */
  4. /*! \file nic_tx.c
  5. \brief Functions that provide TX operation in NIC Layer.
  6. This file provides TX functions which are responsible for both Hardware and
  7. Software Resource Management and keep their Synchronization.
  8. */
  9. /*
  10. ** Log: nic_tx.c
  11. **
  12. ** 09 16 2014 eason.tsai
  13. ** [ALPS01728937] [Need Patch] [Volunteer Patch] MET support
  14. ** support MET
  15. **
  16. ** 09 16 2014 eason.tsai
  17. ** [ALPS01728937] [Need Patch] [Volunteer Patch] MET support
  18. ** MET support
  19. **
  20. ** 08 23 2013 terry.wu
  21. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  22. ** 1. Reset MSDU_INFO for data packet to avoid unexpected Tx status
  23. ** 2. Drop Tx packet to non-associated STA in driver
  24. **
  25. ** 08 23 2013 yuche.tsai
  26. ** [BORA00002761] [MT6630][Wi-Fi Direct][Driver] Group Interface formation
  27. ** Bug fix for possible KE.
  28. **
  29. ** 08 20 2013 terry.wu
  30. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  31. ** 1. Reset MSDU_INFO PID field in MSDU set function
  32. **
  33. ** 08 19 2013 terry.wu
  34. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  35. ** 1. Enable TC resource adjust feature
  36. ** 2. Set Non-QoS data frame to TC5
  37. **
  38. ** 08 13 2013 terry.wu
  39. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  40. ** 1. Assign TXD.PID by wlan index
  41. ** 2. Some bug fix
  42. **
  43. ** 08 06 2013 terry.wu
  44. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  45. ** Set BMC packet retry limit to unlimit
  46. **
  47. ** 08 05 2013 terry.wu
  48. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  49. ** 1. Add SW rate definition
  50. ** 2. Add HW default rate selection logic from FW
  51. **
  52. ** 08 02 2013 terry.wu
  53. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  54. ** 1. Set VI/VO Tx life time to no limitation
  55. ** 2. Set VI/VO Tx retry limit to 7
  56. **
  57. ** 07 31 2013 terry.wu
  58. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  59. ** 1. Fix NetDev binding issue
  60. **
  61. ** 07 26 2013 terry.wu
  62. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  63. ** 1. Set NoACK to BMC packet
  64. ** 2. Add kalGetEthAddr function for Tx frame
  65. ** 3. Update RxIndicatePackets
  66. **
  67. ** 07 26 2013 terry.wu
  68. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  69. ** 1. Reduce extra Tx frame header parsing
  70. ** 2. Add TX port control
  71. ** 3. Add net interface to BSS binding
  72. **
  73. ** 07 19 2013 wh.su
  74. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  75. ** wapi 1x frame don't need encrypt
  76. **
  77. ** 07 18 2013 terry.wu
  78. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  79. ** .
  80. **
  81. ** 07 18 2013 terry.wu
  82. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  83. ** 1. Update TxDesc PF bit setting rule
  84. ** 2. Remove unnecessary QM function
  85. **
  86. ** 07 18 2013 wh.su
  87. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  88. ** At nicTxComposeDesc (Mgmt and Data) function, use security setting
  89. ** to decide frame protect or not.
  90. **
  91. ** 07 15 2013 terry.wu
  92. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  93. ** Fix KE at aisFsm when turning off wifi
  94. **
  95. ** 07 12 2013 terry.wu
  96. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  97. ** 1. Update VHT IE composing function
  98. ** 2. disable bow
  99. ** 3. Exchange bss/sta rec update sequence for temp solution
  100. **
  101. ** 07 10 2013 terry.wu
  102. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  103. ** Disable IP/TCP/UDP checksum temporally for 1st connection
  104. **
  105. ** 07 10 2013 terry.wu
  106. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  107. ** 1. Fix KE at qmEnqueueTxPackets while turning off
  108. ** 2. Temp solution for Tx protected data packet
  109. **
  110. ** 07 05 2013 wh.su
  111. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  112. ** To let the 1x no PF at tx desc, data with PF, for WPA2-PSK test purpose!!!!!
  113. **
  114. ** 07 04 2013 terry.wu
  115. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  116. ** Update Tx path for 1x packet
  117. **
  118. ** 07 04 2013 terry.wu
  119. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  120. ** Update for 1st Connection.
  121. **
  122. ** 07 02 2013 wh.su
  123. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  124. ** Refine security BMC wlan index assign
  125. ** Fix some compiling warning
  126. **
  127. ** 06 27 2013 terry.wu
  128. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  129. ** Refine management frame Tx function
  130. **
  131. ** 06 26 2013 terry.wu
  132. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  133. ** Update VHT rate definition
  134. **
  135. ** 06 26 2013 terry.wu
  136. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  137. ** Update Tx DESC definition to lateset version
  138. **
  139. ** 06 25 2013 terry.wu
  140. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  141. ** Update for 1st connection
  142. **
  143. ** 06 18 2013 terry.wu
  144. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  145. ** Update for 1st connection
  146. **
  147. ** 03 29 2013 cp.wu
  148. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  149. ** 1. remove unused HIF definitions
  150. ** 2. enable NDIS 5.1 build success
  151. **
  152. ** 03 22 2013 terry.wu
  153. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  154. ** Update MCU queue index from Q0 to Q1
  155. **
  156. ** 03 19 2013 terry.wu
  157. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  158. ** .
  159. **
  160. ** 03 14 2013 terry.wu
  161. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  162. ** Update packet remaining Tx time
  163. **
  164. ** 03 12 2013 terry.wu
  165. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  166. ** Update Tx utility function for management frame
  167. **
  168. ** 03 05 2013 terry.wu
  169. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  170. ** .
  171. **
  172. ** 03 04 2013 terry.wu
  173. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  174. ** .
  175. **
  176. ** 02 01 2013 cp.wu
  177. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  178. ** 1. eliminate MT5931/MT6620/MT6628 logic
  179. ** 2. add firmware download control sequence
  180. **
  181. ** 01 22 2013 cp.wu
  182. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  183. ** modification for ucBssIndex migration
  184. **
  185. ** 01 21 2013 terry.wu
  186. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  187. ** Update TX path based on new ucBssIndex modifications.
  188. **
  189. ** 01 15 2013 terry.wu
  190. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  191. ** Update Tx done resource release mechanism.
  192. **
  193. ** 12 27 2012 terry.wu
  194. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  195. ** Update MQM index mapping mechanism
  196. ** 1. TID to ACI
  197. ** 2. ACI to SW TxQ
  198. ** 3. ACI to network TC resource
  199. **
  200. ** 12 27 2012 cp.wu
  201. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  202. ** 1. remove unused definitions
  203. ** 2. correct page count and surpress compiler warning
  204. **
  205. ** 12 26 2012 terry.wu
  206. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  207. ** Update TXD format based on latest release.
  208. **
  209. ** 12 21 2012 terry.wu
  210. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  211. ** Update TxD template feature.
  212. **
  213. ** 12 19 2012 terry.wu
  214. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  215. ** Add Tx desc composing function
  216. **
  217. ** 12 18 2012 terry.wu
  218. ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
  219. ** Page count resource management.
  220. **
  221. ** 11 01 2012 cp.wu
  222. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  223. ** update to MT6630 CMD/EVENT definitions.
  224. **
  225. ** 10 25 2012 cp.wu
  226. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  227. ** sync with MT6630 HIFSYS update.
  228. **
  229. ** 09 17 2012 cm.chang
  230. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  231. ** Duplicate source from MT6620 v2.3 driver branch
  232. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  233. **
  234. ** 08 28 2012 cp.wu
  235. ** [WCXRP00001270] [MT6620 Wi-Fi][Driver] Fix non-aggregated TX path for experimental purpose
  236. ** fix: pucTxCoalescingBufPtr is also used by non-aggregated TX path
  237. *
  238. * 06 13 2012 yuche.tsai
  239. * NULL
  240. * Update maintrunk driver.
  241. * Add support for driver compose assoc request frame.
  242. *
  243. * 11 18 2011 eddie.chen
  244. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  245. * Add log counter for tx
  246. *
  247. * 11 09 2011 eddie.chen
  248. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  249. * Add xlog for beacon timeout and sta aging timeout.
  250. *
  251. * 11 08 2011 eddie.chen
  252. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  253. * Add xlog function.
  254. *
  255. * 05 17 2011 cp.wu
  256. * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss
  257. * disconnection
  258. * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state.
  259. *
  260. * 04 12 2011 eddie.chen
  261. * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
  262. * Fix the sta index in processing security frame
  263. * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
  264. * Add debug message.
  265. *
  266. * 04 12 2011 cp.wu
  267. * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
  268. * dropping cases for TC4 path
  269. * remove unused variables.
  270. *
  271. * 04 12 2011 cp.wu
  272. * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
  273. * dropping cases for TC4 path
  274. * 1. add nicTxGetResource() API for QM to make decisions.
  275. * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case.
  276. *
  277. * 03 17 2011 cp.wu
  278. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  279. * after system running for a long period
  280. * use pre-allocated buffer for storing enhanced interrupt response as well
  281. *
  282. * 03 15 2011 cp.wu
  283. * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
  284. * memory consumption
  285. * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
  286. * 2. Use common coalescing buffer for both TX/RX directions
  287. *
  288. *
  289. * 02 16 2011 cp.wu
  290. * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count
  291. * and modify behavior
  292. * 1. add new API: nicTxGetFreeCmdCount()
  293. * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly
  294. *
  295. * 01 24 2011 cp.wu
  296. * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
  297. * 1. add an extra counter for tracking pending forward frames.
  298. * 2. notify TX service thread as well when there is pending forward frame
  299. * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
  300. *
  301. * 01 12 2011 cp.wu
  302. * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
  303. * needs such information
  304. * fill mac header length information for 802.1x frames.
  305. *
  306. * 12 31 2010 cp.wu
  307. * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
  308. * scheduling
  309. * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
  310. * loaded
  311. *
  312. * 11 01 2010 yarco.yang
  313. * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
  314. * Add GPIO debug function
  315. *
  316. * 10 18 2010 cp.wu
  317. * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
  318. * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
  319. * 2. shorten polling count for shorter response time
  320. * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
  321. *
  322. * 10 06 2010 cp.wu
  323. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  324. * code reorganization to improve isolation between GLUE and CORE layers.
  325. *
  326. * 09 29 2010 wh.su
  327. * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
  328. * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
  329. *
  330. * 09 27 2010 wh.su
  331. * NULL
  332. * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error
  333. *
  334. * 09 24 2010 wh.su
  335. * NULL
  336. * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra
  337. * bytes padding.
  338. *
  339. * 09 01 2010 cp.wu
  340. * NULL
  341. * HIFSYS Clock Source Workaround
  342. *
  343. * 08 30 2010 cp.wu
  344. * NULL
  345. * API added: nicTxPendingPackets(), for simplifying porting layer
  346. *
  347. * 08 30 2010 cp.wu
  348. * NULL
  349. * eliminate klockwork errors
  350. *
  351. * 08 20 2010 wh.su
  352. * NULL
  353. * adding the eapol callback setting.
  354. *
  355. * 08 18 2010 yarco.yang
  356. * NULL
  357. * 1. Fixed HW checksum offload function not work under Linux issue.
  358. * 2. Add debug message.
  359. *
  360. * 08 05 2010 yuche.tsai
  361. * NULL
  362. * .
  363. *
  364. * 08 03 2010 cp.wu
  365. * NULL
  366. * surpress compilation warning.
  367. *
  368. * 08 02 2010 jeffrey.chang
  369. * NULL
  370. * 1) modify tx service thread to avoid busy looping
  371. * 2) add spin lock declartion for linux build
  372. *
  373. * 07 29 2010 cp.wu
  374. * NULL
  375. * simplify post-handling after TX_DONE interrupt is handled.
  376. *
  377. * 07 19 2010 jeffrey.chang
  378. *
  379. * Linux port modification
  380. *
  381. * 07 13 2010 cp.wu
  382. *
  383. * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
  384. * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
  385. * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network
  386. * operation
  387. *
  388. * 07 08 2010 cp.wu
  389. *
  390. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  391. *
  392. * 06 29 2010 yarco.yang
  393. * [WPD00003837][MT6620]Data Path Refine
  394. * replace g_rQM with Adpater->rQM
  395. *
  396. * 06 25 2010 cp.wu
  397. * [WPD00003833][MT6620 and MT5931] Driver migration
  398. * add API in que_mgt to retrieve sta-rec index for security frames.
  399. *
  400. * 06 24 2010 cp.wu
  401. * [WPD00003833][MT6620 and MT5931] Driver migration
  402. * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
  403. *
  404. * 06 23 2010 yarco.yang
  405. * [WPD00003837][MT6620]Data Path Refine
  406. * Merge g_arStaRec[] into adapter->arStaRec[]
  407. *
  408. * 06 22 2010 cp.wu
  409. * [WPD00003833][MT6620 and MT5931] Driver migration
  410. * 1) add command warpper for STA-REC/BSS-INFO sync.
  411. * 2) enhance command packet sending procedure for non-oid part
  412. * 3) add command packet definitions for STA-REC/BSS-INFO sync.
  413. *
  414. * 06 21 2010 cp.wu
  415. * [WPD00003833][MT6620 and MT5931] Driver migration
  416. * add checking for TX descriptor poll.
  417. *
  418. * 06 21 2010 cp.wu
  419. * [WPD00003833][MT6620 and MT5931] Driver migration
  420. * TX descriptors are now allocated once for reducing allocation overhead
  421. *
  422. * 06 18 2010 cm.chang
  423. * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
  424. * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
  425. *
  426. * 06 15 2010 cp.wu
  427. * [WPD00003833][MT6620 and MT5931] Driver migration
  428. * change zero-padding for TX port access to HAL.
  429. *
  430. * 06 15 2010 cp.wu
  431. * [WPD00003833][MT6620 and MT5931] Driver migration
  432. * .
  433. *
  434. * 06 15 2010 cp.wu
  435. * [WPD00003833][MT6620 and MT5931] Driver migration
  436. * .
  437. *
  438. * 06 14 2010 cp.wu
  439. * [WPD00003833][MT6620 and MT5931] Driver migration
  440. * fill extra information for revised HIF_TX_HEADER.
  441. *
  442. * 06 11 2010 cp.wu
  443. * [WPD00003833][MT6620 and MT5931] Driver migration
  444. * 1) migrate assoc.c.
  445. * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
  446. * 3) add configuration options for CNM_MEM and RSN modules
  447. * 4) add data path for management frames
  448. * 5) eliminate rPacketInfo of MSDU_INFO_T
  449. *
  450. * 06 10 2010 cp.wu
  451. * [WPD00003833][MT6620 and MT5931] Driver migration
  452. * change to enqueue TX frame infinitely.
  453. *
  454. * 06 09 2010 cp.wu
  455. * [WPD00003833][MT6620 and MT5931] Driver migration
  456. * add TX_PACKET_MGMT to indicate the frame is coming from management modules
  457. *
  458. * 06 06 2010 kevin.huang
  459. * [WPD00003832][MT6620 5931] Create driver base
  460. * [MT6620 5931] Create driver base
  461. *
  462. * 05 10 2010 cp.wu
  463. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  464. * fill network type field while doing frame identification.
  465. *
  466. * 04 23 2010 cp.wu
  467. * [WPD00001943]Create WiFi test driver framework on WinXP
  468. * surpress compiler warning
  469. *
  470. * 04 06 2010 jeffrey.chang
  471. * [WPD00003826]Initial import for Linux port
  472. * Tag the packet for QoS on Tx path
  473. *
  474. * 03 30 2010 cp.wu
  475. * [WPD00001943]Create WiFi test driver framework on WinXP
  476. * remove driver-land statistics.
  477. *
  478. * 03 29 2010 jeffrey.chang
  479. * [WPD00003826]Initial import for Linux port
  480. * improve none-glue code portability
  481. *
  482. * 03 24 2010 jeffrey.chang
  483. * [WPD00003826]Initial import for Linux port
  484. * initial import for Linux port
  485. *
  486. * 03 24 2010 cp.wu
  487. * [WPD00001943]Create WiFi test driver framework on WinXP
  488. * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
  489. * * * * *
  490. *
  491. * 03 10 2010 cp.wu
  492. * [WPD00001943]Create WiFi test driver framework on WinXP
  493. * code clean: removing unused variables and structure definitions
  494. *
  495. * 03 08 2010 cp.wu
  496. * [WPD00001943]Create WiFi test driver framework on WinXP
  497. * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
  498. * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
  499. *
  500. * 03 02 2010 cp.wu
  501. * [WPD00001943]Create WiFi test driver framework on WinXP
  502. * add mutex to avoid multiple access to qmTxQueue simultaneously.
  503. *
  504. * 02 26 2010 cp.wu
  505. * [WPD00001943]Create WiFi test driver framework on WinXP
  506. * avoid referring to NDIS-specific data structure directly from non-glue layer.
  507. *
  508. * 02 24 2010 cp.wu
  509. * [WPD00001943]Create WiFi test driver framework on WinXP
  510. * add Ethernet destination address information in packet info for TX
  511. *
  512. * 02 10 2010 cp.wu
  513. * [WPD00001943]Create WiFi test driver framework on WinXP
  514. * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
  515. * * * * * * 2) firmware image length is now retrieved via NdisFileOpen
  516. * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
  517. * * * * * * 4) nicRxWaitResponse() revised
  518. * * * * * * 5) another set of TQ counter default value is added for fw-download state
  519. * * * * * * 6) Wi-Fi load address is now retrieved from registry too
  520. *
  521. * 02 09 2010 cp.wu
  522. * [WPD00001943]Create WiFi test driver framework on WinXP
  523. * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
  524. * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP
  525. * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes
  526. *
  527. * 02 08 2010 cp.wu
  528. * [WPD00001943]Create WiFi test driver framework on WinXP
  529. * prepare for implementing fw download logic
  530. *
  531. * 01 27 2010 cp.wu
  532. * [WPD00001943]Create WiFi test driver framework on WinXP
  533. * 1. eliminate improper variable in rHifInfo
  534. * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged
  535. * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode
  536. * * * * * * * * * 4. correct some HAL implementation
  537. *
  538. * 01 13 2010 tehuang.liu
  539. * [WPD00001943]Create WiFi test driver framework on WinXP
  540. * Enabled the Burst_End Indication mechanism
  541. *
  542. * 01 13 2010 cp.wu
  543. * [WPD00001943]Create WiFi test driver framework on WinXP
  544. * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo
  545. *
  546. * 12 30 2009 cp.wu
  547. * [WPD00001943]Create WiFi test driver framework on WinXP
  548. * 1) According to CMD/EVENT documentation v0.8,
  549. * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
  550. * * * * * * * * * * and result is retrieved by get ATInfo instead
  551. * * * * * * * * * * 2) add 4 counter for recording aggregation statistics
  552. ** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752
  553. ** remove unused API
  554. ** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752
  555. ** correct assertion criterion
  556. ** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752
  557. ** correct trivial mistake
  558. ** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752
  559. ** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data
  560. ** + add more assertion for packet size check
  561. ** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752
  562. ** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort
  563. ** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752
  564. ** add 2 assertion for size check
  565. ** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461
  566. ** Add debug message
  567. ** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752
  568. ** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T
  569. ** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752
  570. ** use TC4 instead of TC5 for command packet
  571. ** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752
  572. ** add flush for reset
  573. ** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752
  574. ** fill prMsduInfo->ucUserPriority
  575. ** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752
  576. ** fill u2SeqNo
  577. ** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752
  578. ** integration with SD1's data path API
  579. ** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752
  580. ** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList
  581. ** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752
  582. ** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum,
  583. ** WIFI_CMD_T will be created inside oid handler
  584. ** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752
  585. ** use TxAccquireResource instead of accessing TCQ directly.
  586. ** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084
  587. ** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752
  588. ** add nicTxMsduInfoList () implementation
  589. ** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752
  590. ** add nicTxAdjustTcq() implementation
  591. ** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752
  592. ** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure
  593. ** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752
  594. ** add SD1_SD3_DATAPATH_INTEGRATION data path handling
  595. ** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084
  596. ** modify TX hdr format, fix tx retransmission issue
  597. ** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084
  598. ** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084
  599. ** modify TX SW data structure
  600. ** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084
  601. ** modify HAL part
  602. ** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084
  603. ** update for new HW design
  604. ** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725
  605. ** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461
  606. ** Assign SeqNum to CMD Packet
  607. ** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461
  608. ** Add debug message
  609. ** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461
  610. ** Fix Query Command need resp issue
  611. ** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461
  612. ** Move OS dependent code to kalQueryTxOOBData()
  613. ** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461
  614. ** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port
  615. ** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461
  616. ** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand()
  617. ** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461
  618. ** Move the CMD_INFO_T related function to cmd_buf.c
  619. ** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426
  620. ** Update OOB query for TX packet
  621. ** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426
  622. ** Support PKGUIO
  623. ** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461
  624. ** Add virtual OOB for HIF LOOPBACK SW PRETEST
  625. ** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461
  626. ** Add function for SDIO_TX_ENHANCE
  627. ** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461
  628. ** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test.
  629. ** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461
  630. ** Add code for TX Data & Cmd Packet
  631. ** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461
  632. ** Fix LINT warning
  633. ** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461
  634. ** Update TX PATH API
  635. ** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426
  636. ** Init for develop
  637. **
  638. */
  639. /*******************************************************************************
  640. * C O M P I L E R F L A G S
  641. ********************************************************************************
  642. */
  643. /*******************************************************************************
  644. * E X T E R N A L R E F E R E N C E S
  645. ********************************************************************************
  646. */
  647. #include "precomp.h"
  648. #include "que_mgt.h"
  649. #ifdef UDP_SKT_WIFI
  650. #include <linux/ftrace_event.h>
  651. #endif
  652. /*******************************************************************************
  653. * C O N S T A N T S
  654. ********************************************************************************
  655. */
  656. /*******************************************************************************
  657. * D A T A T Y P E S
  658. ********************************************************************************
  659. */
  660. /*******************************************************************************
  661. * P U B L I C D A T A
  662. ********************************************************************************
  663. */
  664. static const TX_RESOURCE_CONTROL_T arTcResourceControl[TC_NUM] = {
  665. /* dest port index, dest queue index, HIF TX queue index */
  666. /* First HW queue */
  667. {PORT_INDEX_LMAC, MAC_TXQ_AC0_INDEX, HIF_TX_AC0_INDEX},
  668. {PORT_INDEX_LMAC, MAC_TXQ_AC1_INDEX, HIF_TX_AC1_INDEX},
  669. {PORT_INDEX_LMAC, MAC_TXQ_AC2_INDEX, HIF_TX_AC2_INDEX},
  670. {PORT_INDEX_LMAC, MAC_TXQ_AC3_INDEX, HIF_TX_AC3_INDEX},
  671. {PORT_INDEX_MCU, MCU_Q1_INDEX, HIF_TX_CPU_INDEX},
  672. {PORT_INDEX_LMAC, MAC_TXQ_AC4_INDEX, HIF_TX_AC4_INDEX},
  673. /* Second HW queue */
  674. #if NIC_TX_ENABLE_SECOND_HW_QUEUE
  675. {PORT_INDEX_LMAC, MAC_TXQ_AC10_INDEX, HIF_TX_AC10_INDEX},
  676. {PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX},
  677. {PORT_INDEX_LMAC, MAC_TXQ_AC12_INDEX, HIF_TX_AC12_INDEX},
  678. {PORT_INDEX_LMAC, MAC_TXQ_AC13_INDEX, HIF_TX_AC13_INDEX},
  679. {PORT_INDEX_LMAC, MAC_TXQ_AC14_INDEX, HIF_TX_AC14_INDEX},
  680. #endif
  681. };
  682. /* Traffic settings per TC */
  683. static const TX_TC_TRAFFIC_SETTING_T arTcTrafficSettings[NET_TC_NUM] = {
  684. /* Tx desc template format, Remaining Tx time, Retry count */
  685. /* For Data frame with StaRec, set Long Format to enable the following settings */
  686. {NIC_TX_DESC_SHORT_FORMAT_LENGTH, NIC_TX_AC_BE_REMAINING_TX_TIME,
  687. NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
  688. {NIC_TX_DESC_SHORT_FORMAT_LENGTH, NIC_TX_AC_BK_REMAINING_TX_TIME,
  689. NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
  690. {NIC_TX_DESC_SHORT_FORMAT_LENGTH, NIC_TX_AC_VI_REMAINING_TX_TIME,
  691. NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
  692. {NIC_TX_DESC_SHORT_FORMAT_LENGTH, NIC_TX_AC_VO_REMAINING_TX_TIME,
  693. NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
  694. /* MGMT frame */
  695. {NIC_TX_DESC_LONG_FORMAT_LENGTH, TX_DESC_TX_TIME_NO_LIMIT,
  696. NIC_TX_MGMT_DEFAULT_RETRY_COUNT_LIMIT},
  697. /* non-StaRec frame (BMC, etc...) */
  698. {NIC_TX_DESC_LONG_FORMAT_LENGTH, TX_DESC_TX_TIME_NO_LIMIT,
  699. NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
  700. };
  701. /*******************************************************************************
  702. * P R I V A T E D A T A
  703. ********************************************************************************
  704. */
  705. /*******************************************************************************
  706. * M A C R O S
  707. ********************************************************************************
  708. */
  709. /*******************************************************************************
  710. * F U N C T I O N D E C L A R A T I O N S
  711. ********************************************************************************
  712. */
  713. /*******************************************************************************
  714. * F U N C T I O N S
  715. ********************************************************************************
  716. */
  717. /*----------------------------------------------------------------------------*/
  718. /*!
  719. * @brief This function will initial all variables in regard to SW TX Queues and
  720. * all free lists of MSDU_INFO_T and SW_TFCB_T.
  721. *
  722. * @param prAdapter Pointer to the Adapter structure.
  723. *
  724. * @return (none)
  725. */
  726. /*----------------------------------------------------------------------------*/
  727. VOID nicTxInitialize(IN P_ADAPTER_T prAdapter)
  728. {
  729. P_TX_CTRL_T prTxCtrl;
  730. PUINT_8 pucMemHandle;
  731. P_MSDU_INFO_T prMsduInfo;
  732. UINT_32 i;
  733. KAL_SPIN_LOCK_DECLARATION();
  734. DEBUGFUNC("nicTxInitialize");
  735. ASSERT(prAdapter);
  736. prTxCtrl = &prAdapter->rTxCtrl;
  737. /* 4 <1> Initialization of Traffic Class Queue Parameters */
  738. nicTxResetResource(prAdapter);
  739. prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;
  740. /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */
  741. QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList);
  742. pucMemHandle = prTxCtrl->pucTxCached;
  743. for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) {
  744. prMsduInfo = (P_MSDU_INFO_T) pucMemHandle;
  745. kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
  746. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  747. QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
  748. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  749. pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T));
  750. }
  751. ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM);
  752. /* Check if the memory allocation consist with this initialization function */
  753. ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize);
  754. QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue);
  755. prTxCtrl->i4TxMgmtPendingNum = 0;
  756. #if CFG_HIF_STATISTICS
  757. prTxCtrl->u4TotalTxAccessNum = 0;
  758. prTxCtrl->u4TotalTxPacketNum = 0;
  759. #endif
  760. prTxCtrl->i4PendingFwdFrameCount = 0;
  761. /* Assign init value */
  762. /* Tx sequence number */
  763. prAdapter->ucTxSeqNum = 0;
  764. /* PID pool */
  765. for (i = 0; i < WTBL_SIZE; i++)
  766. prAdapter->aucPidPool[i] = NIC_TX_DESC_DRIVER_PID_MIN;
  767. prTxCtrl->u4PageSize = NIC_TX_PAGE_SIZE;
  768. qmInit(prAdapter);
  769. TX_RESET_ALL_CNTS(prTxCtrl);
  770. } /* end of nicTxInitialize() */
  771. BOOLEAN nicTxSanityCheckResource(IN P_ADAPTER_T prAdapter)
  772. {
  773. P_TX_CTRL_T prTxCtrl;
  774. UINT_8 ucTC;
  775. UINT_32 ucTotalMaxResource = 0;
  776. UINT_32 ucTotalFreeResource = 0;
  777. BOOLEAN fgError = FALSE;
  778. if (prAdapter->rWifiVar.ucTxDbg & BIT(0)) {
  779. prTxCtrl = &prAdapter->rTxCtrl;
  780. prTxCtrl->u4TotalPageNum = 546;
  781. for (ucTC = TC0_INDEX; ucTC < TC_NUM; ucTC++) {
  782. ucTotalMaxResource += prTxCtrl->rTc.au2MaxNumOfPage[ucTC];
  783. ucTotalFreeResource += prTxCtrl->rTc.au2FreePageCount[ucTC];
  784. if (prTxCtrl->rTc.au2FreePageCount[ucTC] > prTxCtrl->u4TotalPageNum) {
  785. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  786. fgError = TRUE;
  787. }
  788. if (prTxCtrl->rTc.au2MaxNumOfPage[ucTC] > prTxCtrl->u4TotalPageNum) {
  789. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  790. fgError = TRUE;
  791. }
  792. if (prTxCtrl->rTc.au2FreePageCount[ucTC] > prTxCtrl->rTc.au2MaxNumOfPage[ucTC]) {
  793. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  794. fgError = TRUE;
  795. }
  796. }
  797. if (ucTotalMaxResource != prTxCtrl->u4TotalPageNum) {
  798. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  799. fgError = TRUE;
  800. }
  801. if (ucTotalMaxResource < ucTotalFreeResource) {
  802. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  803. fgError = TRUE;
  804. }
  805. if (ucTotalFreeResource > prTxCtrl->u4TotalPageNum) {
  806. DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
  807. fgError = TRUE;
  808. }
  809. if (fgError) {
  810. DBGLOG(TX, ERROR, "Total resource[%u]\n", prTxCtrl->u4TotalPageNum);
  811. qmDumpQueueStatus(prAdapter);
  812. }
  813. }
  814. return !fgError;
  815. }
  816. /*----------------------------------------------------------------------------*/
  817. /*!
  818. * \brief Driver maintain a variable that is synchronous with the usage of individual
  819. * TC Buffer Count. This function will check if has enough TC Buffer for incoming
  820. * packet and then update the value after promise to provide the resources.
  821. *
  822. * \param[in] prAdapter Pointer to the Adapter structure.
  823. * \param[in] ucTC Specify the resource of TC
  824. *
  825. * \retval WLAN_STATUS_SUCCESS Resource is available and been assigned.
  826. * \retval WLAN_STATUS_RESOURCES Resource is not available.
  827. */
  828. /*----------------------------------------------------------------------------*/
  829. WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN UINT_8 ucPageCount)
  830. {
  831. P_TX_CTRL_T prTxCtrl;
  832. WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES;
  833. KAL_SPIN_LOCK_DECLARATION();
  834. ASSERT(prAdapter);
  835. prTxCtrl = &prAdapter->rTxCtrl;
  836. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  837. if (prTxCtrl->rTc.au2FreePageCount[ucTC] >= ucPageCount) {
  838. prTxCtrl->rTc.au2FreePageCount[ucTC] -= ucPageCount;
  839. prTxCtrl->rTc.au2FreeBufferCount[ucTC] =
  840. (prTxCtrl->rTc.au2FreePageCount[ucTC] / NIC_TX_MAX_PAGE_PER_FRAME);
  841. DBGLOG(TX, TRACE,
  842. "Acquire: TC%d AcquirePageCnt[%u] FreeBufferCnt[%u] FreePageCnt[%u]\n",
  843. ucTC, ucPageCount, prTxCtrl->rTc.au2FreeBufferCount[ucTC],
  844. prTxCtrl->rTc.au2FreePageCount[ucTC]);
  845. u4Status = WLAN_STATUS_SUCCESS;
  846. }
  847. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  848. return u4Status;
  849. } /* end of nicTxAcquireResourceAndTFCBs() */
  850. /*----------------------------------------------------------------------------*/
  851. /*!
  852. * @brief Driver maintain a variable that is synchronous with the usage of individual
  853. * TC Buffer Count. This function will do polling if FW has return the resource.
  854. * Used when driver start up before enable interrupt.
  855. *
  856. * @param prAdapter Pointer to the Adapter structure.
  857. * @param ucTC Specify the resource of TC
  858. *
  859. * @retval WLAN_STATUS_SUCCESS Resource is available.
  860. * @retval WLAN_STATUS_FAILURE Resource is not available.
  861. */
  862. /*----------------------------------------------------------------------------*/
  863. WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
  864. {
  865. P_TX_CTRL_T prTxCtrl;
  866. WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
  867. INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT;
  868. UINT_32 au4WTSR[8];
  869. ASSERT(prAdapter);
  870. prTxCtrl = &prAdapter->rTxCtrl;
  871. if (ucTC >= TC_NUM)
  872. return WLAN_STATUS_FAILURE;
  873. if (prTxCtrl->rTc.au2FreeBufferCount[ucTC] > 0)
  874. return WLAN_STATUS_SUCCESS;
  875. while (i-- > 0) {
  876. HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR);
  877. if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
  878. u4Status = WLAN_STATUS_FAILURE;
  879. break;
  880. } else if (nicTxReleaseResource(prAdapter, (PUINT_16) au4WTSR)) {
  881. if (prTxCtrl->rTc.au2FreeBufferCount[ucTC] > 0) {
  882. u4Status = WLAN_STATUS_SUCCESS;
  883. break;
  884. }
  885. kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
  886. } else {
  887. kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
  888. }
  889. }
  890. #if DBG
  891. {
  892. INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1);
  893. if (i4Times) {
  894. DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %ld times, %ld msec\n",
  895. i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC));
  896. }
  897. }
  898. #endif /* DBG */
  899. return u4Status;
  900. } /* end of nicTxPollingResource() */
  901. /*----------------------------------------------------------------------------*/
  902. /*!
  903. * \brief Driver maintain a variable that is synchronous with the usage of individual
  904. * TC Buffer Count. This function will calculate TC page count according to
  905. * the given TX_STATUS COUNTER after TX Done.
  906. *
  907. * \param[in] prAdapter Pointer to the Adapter structure.
  908. * \param[in] au2TxRlsCnt array of TX STATUS
  909. * \param[in] au2FreeTcResource array of free & available resource count
  910. *
  911. * @return TRUE there are available resource to release
  912. * @return FALSE no available resource to release
  913. */
  914. /*----------------------------------------------------------------------------*/
  915. BOOLEAN nicTxCalculateResource(IN P_ADAPTER_T prAdapter, IN UINT_16 *au2TxRlsCnt, OUT UINT_16 *au2FreeTcResource)
  916. {
  917. P_TX_TCQ_STATUS_T prTcqStatus;
  918. BOOLEAN bStatus = FALSE;
  919. UINT_8 ucTcIdx;
  920. UINT_16 u2TotalTxDoneCnt = 0;
  921. UINT_16 u2TotalExtraTxDone = 0;
  922. UINT_16 au2UsedCnt[TC_NUM];
  923. UINT_16 au2ExtraTxDone[TC_NUM];
  924. PUINT_16 au2TxDoneCnt;
  925. PUINT_16 au2PreUsedCnt;
  926. UINT_16 u2AvaliableCnt;
  927. BOOLEAN fgEnExtraTxDone;
  928. KAL_SPIN_LOCK_DECLARATION();
  929. ASSERT(prAdapter);
  930. prTcqStatus = &prAdapter->rTxCtrl.rTc;
  931. au2TxDoneCnt = prTcqStatus->au2TxDonePageCount;
  932. au2PreUsedCnt = prTcqStatus->au2PreUsedPageCount;
  933. u2AvaliableCnt = prTcqStatus->u2AvaliablePageCount;
  934. fgEnExtraTxDone = prAdapter->rWifiVar.ucExtraTxDone;
  935. /* Get used page count */
  936. if (fgEnExtraTxDone) {
  937. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  938. for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
  939. au2UsedCnt[ucTcIdx] = prTcqStatus->au2MaxNumOfPage[ucTcIdx] -
  940. prTcqStatus->au2FreePageCount[ucTcIdx];
  941. }
  942. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  943. }
  944. /* Get Tx done & available page count */
  945. u2AvaliableCnt += au2TxRlsCnt[HIF_TX_FFA_INDEX];
  946. for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
  947. /* Get Tx done count from Tx interrupt status */
  948. au2TxDoneCnt[ucTcIdx] += au2TxRlsCnt[arTcResourceControl[ucTcIdx].ucHifTxQIndex];
  949. /* Get Available EXTRA Tx done */
  950. if (fgEnExtraTxDone) {
  951. /* Release Tx done if there are pre-used resource */
  952. if (au2TxDoneCnt[ucTcIdx] >= au2PreUsedCnt[ucTcIdx]) {
  953. au2TxDoneCnt[ucTcIdx] -= au2PreUsedCnt[ucTcIdx];
  954. au2PreUsedCnt[ucTcIdx] = 0;
  955. } else {
  956. au2PreUsedCnt[ucTcIdx] -= au2TxDoneCnt[ucTcIdx];
  957. au2TxDoneCnt[ucTcIdx] = 0;
  958. }
  959. /* Calculate extra Tx done to share rest FFA resource */
  960. if (au2TxDoneCnt[ucTcIdx] >= au2UsedCnt[ucTcIdx]) {
  961. au2TxDoneCnt[ucTcIdx] = au2UsedCnt[ucTcIdx];
  962. au2ExtraTxDone[ucTcIdx] = 0;
  963. } else {
  964. au2ExtraTxDone[ucTcIdx] = au2UsedCnt[ucTcIdx] - au2TxDoneCnt[ucTcIdx];
  965. }
  966. u2TotalExtraTxDone += au2ExtraTxDone[ucTcIdx];
  967. }
  968. u2TotalTxDoneCnt += au2TxDoneCnt[ucTcIdx];
  969. }
  970. DBGLOG(TX, TRACE, "TxDone result, FFA[%u] AC[%u:%u:%u:%u:%u] CPU[%u]\n",
  971. au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX],
  972. au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX],
  973. au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_AC4_INDEX],
  974. au2TxRlsCnt[HIF_TX_CPU_INDEX]);
  975. #if 0
  976. DBGLOG(TX, TRACE, "Tx Done INT result, AC5/6[%u:%u] BMC/BCN[%u:%u] AC10~14[%u:%u:%u:%u:%u]\n",
  977. au2TxRlsCnt[HIF_TX_AC5_INDEX], au2TxRlsCnt[HIF_TX_AC6_INDEX],
  978. au2TxRlsCnt[HIF_TX_BMC_INDEX], au2TxRlsCnt[HIF_TX_BCN_INDEX],
  979. au2TxRlsCnt[HIF_TX_AC10_INDEX], au2TxRlsCnt[HIF_TX_AC11_INDEX],
  980. au2TxRlsCnt[HIF_TX_AC12_INDEX], au2TxRlsCnt[HIF_TX_AC13_INDEX],
  981. au2TxRlsCnt[HIF_TX_AC14_INDEX]);
  982. #endif
  983. DBGLOG(TX, TRACE, "TxDone Page count, TC[%u:%u:%u:%u:%u:%u]\n",
  984. au2TxDoneCnt[TC0_INDEX], au2TxDoneCnt[TC1_INDEX],
  985. au2TxDoneCnt[TC2_INDEX], au2TxDoneCnt[TC3_INDEX],
  986. au2TxDoneCnt[TC4_INDEX], au2TxDoneCnt[TC5_INDEX]);
  987. /* Calculate free Tc page count */
  988. if (u2AvaliableCnt && u2TotalTxDoneCnt) {
  989. /* Distribute resource by Tx done counter */
  990. if (u2AvaliableCnt >= u2TotalTxDoneCnt) {
  991. /* Fulfill all TC resource */
  992. kalMemCopy(au2FreeTcResource, prTcqStatus->au2TxDonePageCount,
  993. sizeof(prTcqStatus->au2TxDonePageCount));
  994. kalMemZero(prTcqStatus->au2TxDonePageCount, sizeof(prTcqStatus->au2TxDonePageCount));
  995. u2AvaliableCnt -= u2TotalTxDoneCnt;
  996. } else {
  997. /* Round-robin distribute resource */
  998. ucTcIdx = prTcqStatus->ucNextTcIdx;
  999. while (u2AvaliableCnt) {
  1000. /* Enough resource, fulfill this TC */
  1001. if (u2AvaliableCnt >= au2TxDoneCnt[ucTcIdx]) {
  1002. au2FreeTcResource[ucTcIdx] = au2TxDoneCnt[ucTcIdx];
  1003. u2AvaliableCnt -= au2TxDoneCnt[ucTcIdx];
  1004. au2TxDoneCnt[ucTcIdx] = 0;
  1005. /* Round-robin get next TC */
  1006. ucTcIdx++;
  1007. ucTcIdx %= TC_NUM;
  1008. }
  1009. /* no more resource, distribute rest of resource to this TC */
  1010. else {
  1011. au2FreeTcResource[ucTcIdx] = u2AvaliableCnt;
  1012. au2TxDoneCnt[ucTcIdx] -= u2AvaliableCnt;
  1013. u2AvaliableCnt = 0;
  1014. }
  1015. }
  1016. prTcqStatus->ucNextTcIdx = ucTcIdx;
  1017. }
  1018. bStatus = TRUE;
  1019. }
  1020. if (u2AvaliableCnt && u2TotalExtraTxDone && fgEnExtraTxDone) {
  1021. /* Distribute resource by EXTRA Tx done counter */
  1022. if (u2AvaliableCnt >= u2TotalExtraTxDone) {
  1023. for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
  1024. au2FreeTcResource[ucTcIdx] += au2ExtraTxDone[ucTcIdx];
  1025. au2PreUsedCnt[ucTcIdx] += au2ExtraTxDone[ucTcIdx];
  1026. au2ExtraTxDone[ucTcIdx] = 0;
  1027. }
  1028. u2AvaliableCnt -= u2TotalExtraTxDone;
  1029. } else {
  1030. /* Round-robin distribute resource */
  1031. ucTcIdx = prTcqStatus->ucNextTcIdx;
  1032. while (u2AvaliableCnt) {
  1033. /* Enough resource, fulfill this TC */
  1034. if (u2AvaliableCnt >= au2ExtraTxDone[ucTcIdx]) {
  1035. au2FreeTcResource[ucTcIdx] += au2ExtraTxDone[ucTcIdx];
  1036. au2PreUsedCnt[ucTcIdx] += au2ExtraTxDone[ucTcIdx];
  1037. u2AvaliableCnt -= au2ExtraTxDone[ucTcIdx];
  1038. au2ExtraTxDone[ucTcIdx] = 0;
  1039. /* Round-robin get next TC */
  1040. ucTcIdx++;
  1041. ucTcIdx %= TC_NUM;
  1042. }
  1043. /* no more resource, distribute rest of resource to this TC */
  1044. else {
  1045. au2FreeTcResource[ucTcIdx] += u2AvaliableCnt;
  1046. au2PreUsedCnt[ucTcIdx] += u2AvaliableCnt;
  1047. au2ExtraTxDone[ucTcIdx] -= u2AvaliableCnt;
  1048. u2AvaliableCnt = 0;
  1049. }
  1050. }
  1051. prTcqStatus->ucNextTcIdx = ucTcIdx;
  1052. }
  1053. bStatus = TRUE;
  1054. }
  1055. prTcqStatus->u2AvaliablePageCount = u2AvaliableCnt;
  1056. return bStatus;
  1057. }
  1058. /*----------------------------------------------------------------------------*/
  1059. /*!
  1060. * \brief Driver maintain a variable that is synchronous with the usage of individual
  1061. * TC Buffer Count. This function will release TC Buffer count according to
  1062. * the given TX_STATUS COUNTER after TX Done.
  1063. *
  1064. * \param[in] prAdapter Pointer to the Adapter structure.
  1065. * \param[in] u4TxStatusCnt Value of TX STATUS
  1066. *
  1067. * @return (none)
  1068. */
  1069. /*----------------------------------------------------------------------------*/
  1070. BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_16 *au2TxRlsCnt)
  1071. {
  1072. P_TX_TCQ_STATUS_T prTcqStatus;
  1073. BOOLEAN bStatus = FALSE;
  1074. UINT_32 i, u4BufferCountToBeFreed;
  1075. UINT_16 au2FreeTcResource[TC_NUM] = { 0 };
  1076. KAL_SPIN_LOCK_DECLARATION();
  1077. ASSERT(prAdapter);
  1078. prTcqStatus = &prAdapter->rTxCtrl.rTc;
  1079. /* Calculate free page count */
  1080. if (nicTxCalculateResource(prAdapter, au2TxRlsCnt, au2FreeTcResource)) {
  1081. /* Return free Tc page count */
  1082. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1083. for (i = TC0_INDEX; i < TC_NUM; i++) {
  1084. /* Real page counter */
  1085. prTcqStatus->au2FreePageCount[i] += au2FreeTcResource[i];
  1086. /* Buffer counter. For development only */
  1087. /* Convert page count to buffer count */
  1088. u4BufferCountToBeFreed = (prTcqStatus->au2FreePageCount[i] / NIC_TX_MAX_PAGE_PER_FRAME);
  1089. prTcqStatus->au2FreeBufferCount[i] = u4BufferCountToBeFreed;
  1090. if (au2FreeTcResource[i]) {
  1091. DBGLOG(TX, TRACE,
  1092. "Release: TC%lu ReturnPageCnt[%u] FreePageCnt[%u] FreeBufferCnt[%u]\n",
  1093. i, au2FreeTcResource[i], prTcqStatus->au2FreePageCount[i],
  1094. prTcqStatus->au2FreeBufferCount[i]);
  1095. }
  1096. }
  1097. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1098. bStatus = TRUE;
  1099. }
  1100. if (!nicTxSanityCheckResource(prAdapter))
  1101. DBGLOG(TX, ERROR, "Tx Done INT result, FFA[%u] AC[%u:%u:%u:%u:%u] CPU[%u]\n",
  1102. au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX],
  1103. au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX],
  1104. au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_AC4_INDEX],
  1105. au2TxRlsCnt[HIF_TX_CPU_INDEX]);
  1106. DBGLOG(TX, LOUD,
  1107. "TCQ Status Free Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n",
  1108. prTcqStatus->au2FreePageCount[TC0_INDEX],
  1109. prTcqStatus->au2FreeBufferCount[TC0_INDEX],
  1110. prTcqStatus->au2FreePageCount[TC1_INDEX],
  1111. prTcqStatus->au2FreeBufferCount[TC1_INDEX],
  1112. prTcqStatus->au2FreePageCount[TC2_INDEX],
  1113. prTcqStatus->au2FreeBufferCount[TC2_INDEX],
  1114. prTcqStatus->au2FreePageCount[TC3_INDEX],
  1115. prTcqStatus->au2FreeBufferCount[TC3_INDEX],
  1116. prTcqStatus->au2FreePageCount[TC4_INDEX],
  1117. prTcqStatus->au2FreeBufferCount[TC4_INDEX],
  1118. prTcqStatus->au2FreePageCount[TC5_INDEX], prTcqStatus->au2FreeBufferCount[TC5_INDEX]);
  1119. return bStatus;
  1120. } /* end of nicTxReleaseResource() */
  1121. /*----------------------------------------------------------------------------*/
  1122. /*!
  1123. * \brief Reset TC Buffer Count to initialized value
  1124. *
  1125. * \param[in] prAdapter Pointer to the Adapter structure.
  1126. *
  1127. * @return WLAN_STATUS_SUCCESS
  1128. */
  1129. /*----------------------------------------------------------------------------*/
  1130. WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter)
  1131. {
  1132. P_TX_CTRL_T prTxCtrl;
  1133. UINT_8 ucIdx;
  1134. KAL_SPIN_LOCK_DECLARATION();
  1135. DEBUGFUNC("nicTxResetResource");
  1136. ASSERT(prAdapter);
  1137. prTxCtrl = &prAdapter->rTxCtrl;
  1138. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1139. /* Delta page count */
  1140. kalMemZero(prTxCtrl->rTc.au2TxDonePageCount, sizeof(prTxCtrl->rTc.au2TxDonePageCount));
  1141. kalMemZero(prTxCtrl->rTc.au2PreUsedPageCount, sizeof(prTxCtrl->rTc.au2PreUsedPageCount));
  1142. prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX;
  1143. prTxCtrl->rTc.u2AvaliablePageCount = 0;
  1144. DBGLOG(TX, LOUD, "Default TCQ free resource [%u %u %u %u %u %u]\n",
  1145. prAdapter->rWifiVar.au4TcPageCount[TC0_INDEX],
  1146. prAdapter->rWifiVar.au4TcPageCount[TC1_INDEX],
  1147. prAdapter->rWifiVar.au4TcPageCount[TC2_INDEX],
  1148. prAdapter->rWifiVar.au4TcPageCount[TC3_INDEX],
  1149. prAdapter->rWifiVar.au4TcPageCount[TC4_INDEX],
  1150. prAdapter->rWifiVar.au4TcPageCount[TC5_INDEX]);
  1151. prAdapter->rTxCtrl.u4TotalPageNum = 0;
  1152. prAdapter->rTxCtrl.u4TotalTxRsvPageNum = 0;
  1153. for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) {
  1154. /* Page Count */
  1155. prTxCtrl->rTc.au2MaxNumOfPage[ucIdx] = prAdapter->rWifiVar.au4TcPageCount[ucIdx];
  1156. prTxCtrl->rTc.au2FreePageCount[ucIdx] = prAdapter->rWifiVar.au4TcPageCount[ucIdx];
  1157. DBGLOG(TX, LOUD, "Set TC%u Default[%u] Max[%u] Free[%u]\n",
  1158. ucIdx,
  1159. prAdapter->rWifiVar.au4TcPageCount[ucIdx],
  1160. prTxCtrl->rTc.au2MaxNumOfPage[ucIdx], prTxCtrl->rTc.au2FreePageCount[ucIdx]);
  1161. /* Buffer count */
  1162. prTxCtrl->rTc.au2MaxNumOfBuffer[ucIdx] =
  1163. (prTxCtrl->rTc.au2MaxNumOfPage[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME);
  1164. prTxCtrl->rTc.au2FreeBufferCount[ucIdx] =
  1165. (prTxCtrl->rTc.au2FreePageCount[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME);
  1166. DBGLOG(TX, LOUD, "Set TC%u Default[%u] Buffer Max[%u] Free[%u]\n",
  1167. ucIdx,
  1168. prAdapter->rWifiVar.au4TcPageCount[ucIdx],
  1169. prTxCtrl->rTc.au2MaxNumOfBuffer[ucIdx], prTxCtrl->rTc.au2FreeBufferCount[ucIdx]);
  1170. prAdapter->rTxCtrl.u4TotalPageNum += prTxCtrl->rTc.au2MaxNumOfPage[ucIdx];
  1171. }
  1172. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1173. DBGLOG(TX, TRACE, "Reset TCQ free resource to Page:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u %u:%u ]\n",
  1174. prTxCtrl->rTc.au2FreePageCount[TC0_INDEX],
  1175. prTxCtrl->rTc.au2FreeBufferCount[TC0_INDEX],
  1176. prTxCtrl->rTc.au2FreePageCount[TC1_INDEX],
  1177. prTxCtrl->rTc.au2FreeBufferCount[TC1_INDEX],
  1178. prTxCtrl->rTc.au2FreePageCount[TC2_INDEX],
  1179. prTxCtrl->rTc.au2FreeBufferCount[TC2_INDEX],
  1180. prTxCtrl->rTc.au2FreePageCount[TC3_INDEX],
  1181. prTxCtrl->rTc.au2FreeBufferCount[TC3_INDEX],
  1182. prTxCtrl->rTc.au2FreePageCount[TC4_INDEX],
  1183. prTxCtrl->rTc.au2FreeBufferCount[TC4_INDEX],
  1184. prTxCtrl->rTc.au2FreePageCount[TC5_INDEX], prTxCtrl->rTc.au2FreeBufferCount[TC5_INDEX]);
  1185. DBGLOG(TX, TRACE, "Reset TCQ MAX resource to Page:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u %u:%u]\n",
  1186. prTxCtrl->rTc.au2MaxNumOfPage[TC0_INDEX],
  1187. prTxCtrl->rTc.au2MaxNumOfBuffer[TC0_INDEX],
  1188. prTxCtrl->rTc.au2MaxNumOfPage[TC1_INDEX],
  1189. prTxCtrl->rTc.au2MaxNumOfBuffer[TC1_INDEX],
  1190. prTxCtrl->rTc.au2MaxNumOfPage[TC2_INDEX],
  1191. prTxCtrl->rTc.au2MaxNumOfBuffer[TC2_INDEX],
  1192. prTxCtrl->rTc.au2MaxNumOfPage[TC3_INDEX],
  1193. prTxCtrl->rTc.au2MaxNumOfBuffer[TC3_INDEX],
  1194. prTxCtrl->rTc.au2MaxNumOfPage[TC4_INDEX],
  1195. prTxCtrl->rTc.au2MaxNumOfBuffer[TC4_INDEX],
  1196. prTxCtrl->rTc.au2MaxNumOfPage[TC5_INDEX], prTxCtrl->rTc.au2MaxNumOfBuffer[TC5_INDEX]);
  1197. return WLAN_STATUS_SUCCESS;
  1198. }
  1199. /*----------------------------------------------------------------------------*/
  1200. /*!
  1201. * @brief Driver maintain a variable that is synchronous with the usage of individual
  1202. * TC Buffer Count. This function will return the value for other component
  1203. * which needs this information for making decisions
  1204. *
  1205. * @param prAdapter Pointer to the Adapter structure.
  1206. * @param ucTC Specify the resource of TC
  1207. *
  1208. * @retval UINT_8 The number of corresponding TC number
  1209. */
  1210. /*----------------------------------------------------------------------------*/
  1211. UINT_16 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
  1212. {
  1213. P_TX_CTRL_T prTxCtrl;
  1214. ASSERT(prAdapter);
  1215. prTxCtrl = &prAdapter->rTxCtrl;
  1216. ASSERT(prTxCtrl);
  1217. if (ucTC >= TC_NUM)
  1218. return 0;
  1219. else
  1220. return prTxCtrl->rTc.au2FreePageCount[ucTC];
  1221. }
  1222. UINT_8 nicTxGetFrameResourceType(IN UINT_8 eFrameType, IN P_MSDU_INFO_T prMsduInfo)
  1223. {
  1224. UINT_8 ucTC;
  1225. switch (eFrameType) {
  1226. case FRAME_TYPE_802_1X:
  1227. ucTC = TC4_INDEX;
  1228. break;
  1229. case FRAME_TYPE_MMPDU:
  1230. if (prMsduInfo)
  1231. ucTC = prMsduInfo->ucTC;
  1232. else
  1233. ucTC = TC4_INDEX;
  1234. break;
  1235. default:
  1236. DBGLOG(TX, WARN, "Undefined Frame Type(%u)\n", eFrameType);
  1237. ucTC = TC4_INDEX;
  1238. break;
  1239. }
  1240. return ucTC;
  1241. }
  1242. UINT_8 nicTxGetCmdResourceType(IN P_CMD_INFO_T prCmdInfo)
  1243. {
  1244. UINT_8 ucTC;
  1245. switch (prCmdInfo->eCmdType) {
  1246. case COMMAND_TYPE_NETWORK_IOCTL:
  1247. case COMMAND_TYPE_GENERAL_IOCTL:
  1248. ucTC = TC4_INDEX;
  1249. break;
  1250. case COMMAND_TYPE_SECURITY_FRAME:
  1251. ucTC = nicTxGetFrameResourceType(FRAME_TYPE_802_1X, NULL);
  1252. break;
  1253. case COMMAND_TYPE_MANAGEMENT_FRAME:
  1254. ucTC = nicTxGetFrameResourceType(FRAME_TYPE_MMPDU, prCmdInfo->prMsduInfo);
  1255. break;
  1256. default:
  1257. DBGLOG(TX, WARN, "Undefined CMD Type(%u)\n", prCmdInfo->eCmdType);
  1258. ucTC = TC4_INDEX;
  1259. break;
  1260. }
  1261. return ucTC;
  1262. }
  1263. /*----------------------------------------------------------------------------*/
  1264. /*!
  1265. * @brief In this function, we'll aggregate frame(PACKET_INFO_T)
  1266. * corresponding to HIF TX port
  1267. *
  1268. * @param prAdapter Pointer to the Adapter structure.
  1269. * @param prMsduInfoListHead a link list of P_MSDU_INFO_T
  1270. *
  1271. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1272. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1273. */
  1274. /*----------------------------------------------------------------------------*/
  1275. WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  1276. {
  1277. P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
  1278. QUE_T qDataPort0, qDataPort1;
  1279. P_QUE_T prDataPort0, prDataPort1;
  1280. WLAN_STATUS status;
  1281. ASSERT(prAdapter);
  1282. ASSERT(prMsduInfoListHead);
  1283. prMsduInfo = prMsduInfoListHead;
  1284. prDataPort0 = &qDataPort0;
  1285. prDataPort1 = &qDataPort1;
  1286. QUEUE_INITIALIZE(prDataPort0);
  1287. QUEUE_INITIALIZE(prDataPort1);
  1288. /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
  1289. while (prMsduInfo) {
  1290. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1291. switch (prMsduInfo->ucTC) {
  1292. case TC0_INDEX:
  1293. case TC1_INDEX:
  1294. case TC2_INDEX:
  1295. case TC3_INDEX:
  1296. case TC5_INDEX: /* Broadcast/multicast data packets */
  1297. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  1298. QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
  1299. status =
  1300. nicTxAcquireResource(prAdapter, prMsduInfo->ucTC,
  1301. nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE));
  1302. ASSERT(status == WLAN_STATUS_SUCCESS);
  1303. break;
  1304. case TC4_INDEX: /* Management packets */
  1305. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  1306. QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
  1307. status =
  1308. nicTxAcquireResource(prAdapter, prMsduInfo->ucTC,
  1309. nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE));
  1310. ASSERT(status == WLAN_STATUS_SUCCESS);
  1311. break;
  1312. default:
  1313. ASSERT(0);
  1314. break;
  1315. }
  1316. prMsduInfo = prNextMsduInfo;
  1317. }
  1318. if (prDataPort0->u4NumElem > 0)
  1319. nicTxMsduQueue(prAdapter, 0, prDataPort0);
  1320. if (prDataPort1->u4NumElem > 0)
  1321. nicTxMsduQueue(prAdapter, 1, prDataPort1);
  1322. return WLAN_STATUS_SUCCESS;
  1323. }
  1324. #if CFG_SUPPORT_MULTITHREAD
  1325. /*----------------------------------------------------------------------------*/
  1326. /*!
  1327. * @brief In this function, we'll aggregate frame(PACKET_INFO_T)
  1328. * corresponding to HIF TX port
  1329. *
  1330. * @param prAdapter Pointer to the Adapter structure.
  1331. * @param prMsduInfoListHead a link list of P_MSDU_INFO_T
  1332. *
  1333. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1334. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1335. */
  1336. /*----------------------------------------------------------------------------*/
  1337. WLAN_STATUS nicTxMsduInfoListMthread(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  1338. {
  1339. P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
  1340. QUE_T qDataPort0, qDataPort1;
  1341. P_QUE_T prDataPort0, prDataPort1;
  1342. KAL_SPIN_LOCK_DECLARATION();
  1343. ASSERT(prAdapter);
  1344. ASSERT(prMsduInfoListHead);
  1345. prMsduInfo = prMsduInfoListHead;
  1346. prDataPort0 = &qDataPort0;
  1347. prDataPort1 = &qDataPort1;
  1348. QUEUE_INITIALIZE(prDataPort0);
  1349. QUEUE_INITIALIZE(prDataPort1);
  1350. /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
  1351. while (prMsduInfo) {
  1352. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1353. switch (prMsduInfo->ucTC) {
  1354. case TC0_INDEX:
  1355. case TC1_INDEX:
  1356. case TC2_INDEX:
  1357. case TC3_INDEX:
  1358. case TC5_INDEX: /* Broadcast/multicast data packets */
  1359. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  1360. QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
  1361. break;
  1362. case TC4_INDEX: /* Management packets */
  1363. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  1364. QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
  1365. break;
  1366. default:
  1367. ASSERT(0);
  1368. break;
  1369. }
  1370. nicTxFillDesc(prAdapter, prMsduInfo, prMsduInfo->aucTxDescBuffer, NULL);
  1371. prMsduInfo = prNextMsduInfo;
  1372. }
  1373. if (prDataPort0->u4NumElem > 0 || prDataPort1->u4NumElem > 0) {
  1374. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1375. QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP0Queue)), (prDataPort0));
  1376. QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP1Queue)), (prDataPort1));
  1377. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1378. kalSetTxEvent2Hif(prAdapter->prGlueInfo);
  1379. }
  1380. return WLAN_STATUS_SUCCESS;
  1381. }
  1382. /*----------------------------------------------------------------------------*/
  1383. /*!
  1384. * @brief In this function, we'll write frame(PACKET_INFO_T) into HIF when apply multithread.
  1385. *
  1386. * @param prAdapter Pointer to the Adapter structure.
  1387. *
  1388. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1389. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1390. */
  1391. /*----------------------------------------------------------------------------*/
  1392. UINT_32 nicTxMsduQueueMthread(IN P_ADAPTER_T prAdapter)
  1393. {
  1394. QUE_T qDataPort0, qDataPort1;
  1395. P_QUE_T prDataPort0, prDataPort1;
  1396. UINT_32 u4TxLoopCount;
  1397. KAL_SPIN_LOCK_DECLARATION();
  1398. prDataPort0 = &qDataPort0;
  1399. prDataPort1 = &qDataPort1;
  1400. QUEUE_INITIALIZE(prDataPort0);
  1401. QUEUE_INITIALIZE(prDataPort1);
  1402. u4TxLoopCount = prAdapter->rWifiVar.u4HifTxloopCount;
  1403. while (u4TxLoopCount--) {
  1404. while (QUEUE_IS_NOT_EMPTY((&(prAdapter->rTxP0Queue)))) {
  1405. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1406. QUEUE_MOVE_ALL((prDataPort0), (&(prAdapter->rTxP0Queue)));
  1407. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1408. nicTxMsduQueue(prAdapter, 0, prDataPort0);
  1409. }
  1410. while (QUEUE_IS_NOT_EMPTY((&(prAdapter->rTxP1Queue)))) {
  1411. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1412. QUEUE_MOVE_ALL((prDataPort1), (&(prAdapter->rTxP1Queue)));
  1413. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
  1414. nicTxMsduQueue(prAdapter, 1, prDataPort0);
  1415. }
  1416. }
  1417. return WLAN_STATUS_SUCCESS;
  1418. }
  1419. #endif
  1420. /*----------------------------------------------------------------------------*/
  1421. /*!
  1422. * @brief In this function, we'll compose the Tx descriptor of the MSDU.
  1423. *
  1424. * @param prAdapter Pointer to the Adapter structure.
  1425. * @param prMsduInfo Pointer to the Msdu info
  1426. * @param prTxDesc Pointer to the Tx descriptor buffer
  1427. *
  1428. * @retval VOID
  1429. */
  1430. /*----------------------------------------------------------------------------*/
  1431. VOID
  1432. nicTxComposeDesc(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo,
  1433. IN UINT_8 ucTxDescLength, IN BOOLEAN fgIsTemplate, OUT PUINT_8 prTxDescBuffer)
  1434. {
  1435. P_HW_MAC_TX_DESC_T prTxDesc;
  1436. P_STA_RECORD_T prStaRec;
  1437. P_BSS_INFO_T prBssInfo;
  1438. UINT_8 ucEtherTypeOffsetInWord;
  1439. UINT_8 ucTxDescAndPaddingLength;
  1440. prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
  1441. prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
  1442. prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  1443. ucTxDescAndPaddingLength = ucTxDescLength + NIC_TX_DESC_PADDING_LENGTH;
  1444. kalMemZero(prTxDesc, ucTxDescAndPaddingLength);
  1445. /* Move to nicTxFillDesc */
  1446. /* Tx byte count */
  1447. /* HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, ucTxDescAndPaddingLength + prMsduInfo->u2FrameLength); */
  1448. /* Ether-type offset */
  1449. if (prMsduInfo->fgIs802_11) {
  1450. ucEtherTypeOffsetInWord =
  1451. (NIC_TX_DESC_AND_PADDING_LENGTH + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
  1452. } else {
  1453. ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + ucTxDescAndPaddingLength) >> 1;
  1454. }
  1455. HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, ucEtherTypeOffsetInWord);
  1456. if (prMsduInfo->ucTC >= TC_NUM)
  1457. return;
  1458. /* Port index / queue index */
  1459. HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, arTcResourceControl[prMsduInfo->ucTC].ucDestPortIndex);
  1460. HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, arTcResourceControl[prMsduInfo->ucTC].ucDestQueueIndex);
  1461. /* BMC packet */
  1462. if (prMsduInfo->ucStaRecIndex == STA_REC_INDEX_BMCAST) {
  1463. HAL_MAC_TX_DESC_SET_BMC(prTxDesc);
  1464. /* Must set No ACK to mask retry bit in FC */
  1465. HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc);
  1466. }
  1467. /* WLAN index */
  1468. prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex);
  1469. #if DBG
  1470. DBGLOG(RSN, TRACE,
  1471. "Tx WlanIndex = %d eAuthMode = %d\n", prMsduInfo->ucWlanIndex,
  1472. prAdapter->rWifiVar.rConnSettings.eAuthMode);
  1473. #endif
  1474. HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, prMsduInfo->ucWlanIndex);
  1475. /* Header format */
  1476. if (prMsduInfo->fgIs802_11) {
  1477. HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_802_11_NORMAL_MODE);
  1478. HAL_MAC_TX_DESC_SET_802_11_HEADER_LENGTH(prTxDesc, (prMsduInfo->ucMacHeaderLength >> 1));
  1479. } else {
  1480. HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_NON_802_11);
  1481. HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc);
  1482. }
  1483. /* Header Padding */
  1484. HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, NIC_TX_DESC_HEADER_PADDING_LENGTH);
  1485. /* TID */
  1486. HAL_MAC_TX_DESC_SET_TID(prTxDesc, prMsduInfo->ucUserPriority);
  1487. /* Protection */
  1488. if (secIsProtectedFrame(prAdapter, prMsduInfo, prStaRec)) {
  1489. /* Update Packet option, PF bit will be set in nicTxFillDescByPktOption() */
  1490. nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
  1491. }
  1492. /* Own MAC */
  1493. HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, prBssInfo->ucOwnMacIndex);
  1494. if (ucTxDescLength == NIC_TX_DESC_SHORT_FORMAT_LENGTH) {
  1495. HAL_MAC_TX_DESC_SET_SHORT_FORMAT(prTxDesc);
  1496. /* Update Packet option */
  1497. nicTxFillDescByPktOption(prMsduInfo, prTxDesc);
  1498. /* Short format, Skip DW 2~6 */
  1499. return;
  1500. }
  1501. HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc);
  1502. /* Update Packet option */
  1503. nicTxFillDescByPktOption(prMsduInfo, prTxDesc);
  1504. nicTxFillDescByPktControl(prMsduInfo, prTxDesc);
  1505. /* Type */
  1506. if (prMsduInfo->fgIs802_11) {
  1507. P_WLAN_MAC_HEADER_T prWlanHeader =
  1508. (P_WLAN_MAC_HEADER_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
  1509. HAL_MAC_TX_DESC_SET_TYPE(prTxDesc, (prWlanHeader->u2FrameCtrl & MASK_FC_TYPE) >> 2);
  1510. HAL_MAC_TX_DESC_SET_SUB_TYPE(prTxDesc,
  1511. (prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE);
  1512. }
  1513. /* PID */
  1514. if (prMsduInfo->pfTxDoneHandler) {
  1515. prMsduInfo->ucPID = nicTxAssignPID(prAdapter, prMsduInfo->ucWlanIndex);
  1516. HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID);
  1517. HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc);
  1518. }
  1519. /* Remaining TX time */
  1520. if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_LIFE_TIME))
  1521. prMsduInfo->u4RemainingLifetime = arTcTrafficSettings[prMsduInfo->ucTC].u4RemainingTxTime;
  1522. HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, prMsduInfo->u4RemainingLifetime);
  1523. /* Tx count limit */
  1524. if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_RETRY_LIMIT)) {
  1525. /* Note: BMC packet retry limit is set to unlimited */
  1526. prMsduInfo->ucRetryLimit = arTcTrafficSettings[prMsduInfo->ucTC].ucTxCountLimit;
  1527. }
  1528. HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, prMsduInfo->ucRetryLimit);
  1529. /* Power Offset */
  1530. HAL_MAC_TX_DESC_SET_POWER_OFFSET(prTxDesc, prMsduInfo->cPowerOffset);
  1531. /* Fix rate */
  1532. switch (prMsduInfo->ucRateMode) {
  1533. case MSDU_RATE_MODE_MANUAL_DESC:
  1534. HAL_MAC_TX_DESC_SET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);
  1535. HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc);
  1536. HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);
  1537. break;
  1538. case MSDU_RATE_MODE_MANUAL_CR:
  1539. HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_CR(prTxDesc);
  1540. HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);
  1541. break;
  1542. case MSDU_RATE_MODE_AUTO:
  1543. default:
  1544. break;
  1545. }
  1546. }
  1547. VOID
  1548. nicTxComposeSecurityFrameDesc(IN P_ADAPTER_T prAdapter,
  1549. IN P_CMD_INFO_T prCmdInfo, OUT PUINT_8 prTxDescBuffer, OUT PUINT_8 pucTxDescLength)
  1550. {
  1551. P_HW_MAC_TX_DESC_T prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
  1552. UINT_8 ucTxDescAndPaddingLength = NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH;
  1553. /* P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); */
  1554. P_BSS_INFO_T prBssInfo;
  1555. UINT_8 ucTid = 0;
  1556. UINT_8 ucTempTC = TC4_INDEX;
  1557. P_NATIVE_PACKET prNativePacket;
  1558. UINT_8 ucEtherTypeOffsetInWord;
  1559. P_MSDU_INFO_T prMsduInfo;
  1560. prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prCmdInfo->ucBssIndex);
  1561. prMsduInfo = prCmdInfo->prMsduInfo;
  1562. prNativePacket = prMsduInfo->prPacket;
  1563. ASSERT(prNativePacket);
  1564. kalMemZero(prTxDesc, ucTxDescAndPaddingLength);
  1565. /* WLAN index */
  1566. prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex);
  1567. /* UC to a connected peer */
  1568. HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, prMsduInfo->ucWlanIndex);
  1569. /* Redirect Security frame to TID0 */
  1570. /* ucTempTC = arNetwork2TcResource[prStaRec->ucBssIndex][aucTid2ACI[ucTid]]; */
  1571. /* Tx byte count */
  1572. HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, ucTxDescAndPaddingLength + prCmdInfo->u2InfoBufLen);
  1573. /* Ether-type offset */
  1574. ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + ucTxDescAndPaddingLength) >> 1;
  1575. HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, ucEtherTypeOffsetInWord);
  1576. /* Port index / queue index */
  1577. HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, arTcResourceControl[ucTempTC].ucDestPortIndex);
  1578. HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, arTcResourceControl[ucTempTC].ucDestQueueIndex);
  1579. /* Header format */
  1580. HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_NON_802_11);
  1581. /* Long Format */
  1582. HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc);
  1583. /* Update Packet option */
  1584. nicTxFillDescByPktOption(prMsduInfo, prTxDesc);
  1585. if (!GLUE_TEST_PKT_FLAG(prNativePacket, ENUM_PKT_802_3)) {
  1586. /* Set EthernetII */
  1587. HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc);
  1588. }
  1589. /* Header Padding */
  1590. HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, NIC_TX_DESC_HEADER_PADDING_LENGTH);
  1591. /* TID */
  1592. HAL_MAC_TX_DESC_SET_TID(prTxDesc, ucTid);
  1593. /* Remaining TX time */
  1594. HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, arTcTrafficSettings[ucTempTC].u4RemainingTxTime);
  1595. /* Tx count limit */
  1596. HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, arTcTrafficSettings[ucTempTC].ucTxCountLimit);
  1597. /* Set lowest BSS basic rate */
  1598. HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, prBssInfo->u2HwDefaultFixedRateCode);
  1599. HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc);
  1600. HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);
  1601. /* Own MAC */
  1602. HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, prBssInfo->ucOwnMacIndex);
  1603. /* PID */
  1604. if (prMsduInfo->pfTxDoneHandler) {
  1605. prMsduInfo->ucPID = nicTxAssignPID(prAdapter, prMsduInfo->ucWlanIndex);
  1606. HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID);
  1607. HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc);
  1608. }
  1609. if (pucTxDescLength)
  1610. *pucTxDescLength = ucTxDescAndPaddingLength;
  1611. }
  1612. BOOLEAN nicTxIsTXDTemplateAllowd(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec)
  1613. {
  1614. if (prMsduInfo->fgIsTXDTemplateValid && (prMsduInfo->ucControlFlag == 0)
  1615. && prStaRec && !prMsduInfo->pfTxDoneHandler) {
  1616. return TRUE;
  1617. } else {
  1618. return FALSE;
  1619. }
  1620. }
  1621. /*----------------------------------------------------------------------------*/
  1622. /*!
  1623. * @brief In this function, we'll compose the Tx descriptor of the MSDU.
  1624. *
  1625. * @param prAdapter Pointer to the Adapter structure.
  1626. * @param prMsduInfo Pointer to the Msdu info
  1627. * @param prTxDesc Pointer to the Tx descriptor buffer
  1628. *
  1629. * @retval VOID
  1630. */
  1631. /*----------------------------------------------------------------------------*/
  1632. VOID
  1633. nicTxFillDesc(IN P_ADAPTER_T prAdapter,
  1634. IN P_MSDU_INFO_T prMsduInfo, OUT PUINT_8 prTxDescBuffer, OUT PUINT_8 pucTxDescLength)
  1635. {
  1636. P_HW_MAC_TX_DESC_T prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
  1637. P_HW_MAC_TX_DESC_T prTxDescTemplate = NULL;
  1638. P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  1639. UINT_8 ucTxDescLength;
  1640. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1641. UINT_8 ucChksumFlag = 0;
  1642. #endif
  1643. /*
  1644. *------------------------------------------------------------------------------
  1645. * Fill up common fileds
  1646. *------------------------------------------------------------------------------
  1647. */
  1648. /* Get TXD from pre-allocated template */
  1649. if (nicTxIsTXDTemplateAllowd(prAdapter, prMsduInfo, prStaRec)) {
  1650. prTxDescTemplate = prStaRec->aprTxDescTemplate[prMsduInfo->ucUserPriority];
  1651. if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDescTemplate))
  1652. ucTxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
  1653. else
  1654. ucTxDescLength = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1655. kalMemCopy(prTxDesc, prTxDescTemplate, ucTxDescLength);
  1656. /* Overwrite fields for EOSP or More data */
  1657. nicTxFillDescByPktOption(prMsduInfo, prTxDesc);
  1658. }
  1659. /* Compose TXD by Msdu info */
  1660. else {
  1661. ucTxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
  1662. nicTxComposeDesc(prAdapter, prMsduInfo, ucTxDescLength, FALSE, prTxDescBuffer);
  1663. }
  1664. /*
  1665. *------------------------------------------------------------------------------
  1666. * Fill up remaining parts, per-packet variant fields
  1667. *------------------------------------------------------------------------------
  1668. */
  1669. /* Calculate Tx byte count */
  1670. HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc,
  1671. ucTxDescLength + NIC_TX_DESC_PADDING_LENGTH + prMsduInfo->u2FrameLength);
  1672. /* Checksum offload */
  1673. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1674. if (prMsduInfo->eSrc == TX_PACKET_OS) {
  1675. if (prAdapter->u4CSUMFlags &
  1676. (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) {
  1677. kalQueryTxChksumOffloadParam(prMsduInfo->prPacket, &ucChksumFlag);
  1678. if ((ucChksumFlag & TX_CS_IP_GEN))
  1679. HAL_MAC_TX_DESC_SET_IP_CHKSUM(prTxDesc);
  1680. if ((ucChksumFlag & TX_CS_TCP_UDP_GEN))
  1681. HAL_MAC_TX_DESC_SET_TCP_UDP_CHKSUM(prTxDesc);
  1682. }
  1683. }
  1684. #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
  1685. /* Set EtherType & VLAN for non 802.11 frame */
  1686. if (!prMsduInfo->fgIs802_11) {
  1687. if (prMsduInfo->fgIs802_3)
  1688. HAL_MAC_TX_DESC_UNSET_ETHERNET_II(prTxDesc);
  1689. if (prMsduInfo->fgIsVlanExists)
  1690. HAL_MAC_TX_DESC_SET_VLAN(prTxDesc);
  1691. }
  1692. if (pucTxDescLength)
  1693. *pucTxDescLength = ucTxDescLength;
  1694. }
  1695. VOID
  1696. nicTxCopyDesc(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTarTxDesc, IN PUINT_8 pucSrcTxDesc, OUT PUINT_8 pucTxDescLength)
  1697. {
  1698. UINT_8 ucTxDescLength;
  1699. if (HAL_MAC_TX_DESC_IS_LONG_FORMAT((P_HW_MAC_TX_DESC_T) pucSrcTxDesc))
  1700. ucTxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
  1701. else
  1702. ucTxDescLength = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1703. kalMemCopy(pucTarTxDesc, pucSrcTxDesc, ucTxDescLength);
  1704. if (pucTxDescLength)
  1705. *pucTxDescLength = ucTxDescLength;
  1706. }
  1707. /*----------------------------------------------------------------------------*/
  1708. /*!
  1709. * @brief In this function, we'll generate Tx descriptor template for each TID.
  1710. *
  1711. * @param prAdapter Pointer to the Adapter structure.
  1712. * @param prStaRec Pointer to the StaRec structure.
  1713. *
  1714. * @retval VOID
  1715. */
  1716. /*----------------------------------------------------------------------------*/
  1717. WLAN_STATUS nicTxGenerateDescTemplate(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
  1718. {
  1719. UINT_8 ucTid;
  1720. UINT_8 ucTc;
  1721. UINT_8 ucTxDescSize;
  1722. P_HW_MAC_TX_DESC_T prTxDesc;
  1723. P_MSDU_INFO_T prMsduInfo;
  1724. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1725. ASSERT(prAdapter);
  1726. /* Free previous template, first */
  1727. /* nicTxFreeDescTemplate(prAdapter, prStaRec); */
  1728. for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++)
  1729. prStaRec->aprTxDescTemplate[ucTid] = NULL;
  1730. prMsduInfo = cnmPktAlloc(prAdapter, 0);
  1731. if (!prMsduInfo)
  1732. return WLAN_STATUS_RESOURCES;
  1733. /* Fill up MsduInfo template */
  1734. prMsduInfo->eSrc = TX_PACKET_OS;
  1735. prMsduInfo->fgIs802_11 = FALSE;
  1736. prMsduInfo->fgIs802_1x = FALSE;
  1737. prMsduInfo->fgIs802_3 = FALSE;
  1738. prMsduInfo->fgIsVlanExists = FALSE;
  1739. prMsduInfo->pfTxDoneHandler = NULL;
  1740. prMsduInfo->prPacket = NULL;
  1741. prMsduInfo->u2FrameLength = 0;
  1742. prMsduInfo->u4Option = 0;
  1743. prMsduInfo->u4FixedRateOption = 0;
  1744. prMsduInfo->ucRateMode = MSDU_RATE_MODE_AUTO;
  1745. prMsduInfo->ucBssIndex = prStaRec->ucBssIndex;
  1746. prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA;
  1747. prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
  1748. prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;
  1749. ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1750. DBGLOG(TX, TRACE, "Generate TXD template for STA[%u] QoS[%u]\n", prStaRec->ucIndex, prStaRec->fgIsQoS);
  1751. /* Generate new template */
  1752. if (prStaRec->fgIsQoS) {
  1753. /* For QoS STA, generate 8 TXD template (TID0~TID7) */
  1754. for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {
  1755. if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM)
  1756. ucTc = prAdapter->rWifiVar.ucTcRestrict;
  1757. else
  1758. ucTc = arNetwork2TcResource[prStaRec->ucBssIndex][aucTid2ACI[ucTid]];
  1759. ucTxDescSize = arTcTrafficSettings[ucTc].ucTxDescLength;
  1760. prTxDesc = kalMemAlloc(ucTxDescSize, VIR_MEM_TYPE);
  1761. if (!prTxDesc) {
  1762. rStatus = WLAN_STATUS_RESOURCES;
  1763. break;
  1764. }
  1765. /* Update MsduInfo TID & TC */
  1766. prMsduInfo->ucUserPriority = ucTid;
  1767. prMsduInfo->ucTC = ucTc;
  1768. /* Compose Tx desc template */
  1769. nicTxComposeDesc(prAdapter, prMsduInfo, ucTxDescSize, TRUE, (PUINT_8) prTxDesc);
  1770. prStaRec->aprTxDescTemplate[ucTid] = prTxDesc;
  1771. }
  1772. } else {
  1773. /* For non-QoS STA, generate 1 TXD template (TID0) */
  1774. do {
  1775. if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM) {
  1776. ucTc = prAdapter->rWifiVar.ucTcRestrict;
  1777. } else {
  1778. ucTc = arNetwork2TcResource[prStaRec->ucBssIndex]
  1779. [NET_TC_NON_STAREC_NON_QOS_INDEX];
  1780. }
  1781. /* ucTxDescSize = arTcTrafficSettings[ucTc].ucTxDescLength; */
  1782. ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1783. prTxDesc = kalMemAlloc(ucTxDescSize, VIR_MEM_TYPE);
  1784. if (!prTxDesc) {
  1785. rStatus = WLAN_STATUS_RESOURCES;
  1786. break;
  1787. }
  1788. /* Update MsduInfo TID & TC */
  1789. prMsduInfo->ucUserPriority = 0;
  1790. prMsduInfo->ucTC = ucTc;
  1791. /* Compose Tx desc template */
  1792. nicTxComposeDesc(prAdapter, prMsduInfo, ucTxDescSize, TRUE, (PUINT_8) prTxDesc);
  1793. for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {
  1794. prStaRec->aprTxDescTemplate[ucTid] = prTxDesc;
  1795. DBGLOG(TX, TRACE, "TXD template: TID[%u] Ptr[0x%x]\n", ucTid, (ULONG) prTxDesc);
  1796. }
  1797. } while (FALSE);
  1798. }
  1799. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  1800. return rStatus;
  1801. }
  1802. /*----------------------------------------------------------------------------*/
  1803. /*!
  1804. * @brief In this function, we'll free Tx descriptor template for each TID.
  1805. *
  1806. * @param prAdapter Pointer to the Adapter structure.
  1807. * @param prStaRec Pointer to the StaRec structure.
  1808. *
  1809. * @retval VOID
  1810. */
  1811. /*----------------------------------------------------------------------------*/
  1812. VOID nicTxFreeDescTemplate(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
  1813. {
  1814. UINT_8 ucTid;
  1815. UINT_8 ucTxDescSize;
  1816. P_HW_MAC_TX_DESC_T prTxDesc;
  1817. DBGLOG(TX, TRACE, "Free TXD template for STA[%u] QoS[%u]\n", prStaRec->ucIndex, prStaRec->fgIsQoS);
  1818. if (prStaRec->fgIsQoS) {
  1819. for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {
  1820. prTxDesc = (P_HW_MAC_TX_DESC_T) prStaRec->aprTxDescTemplate[ucTid];
  1821. if (prTxDesc) {
  1822. if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc))
  1823. ucTxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;
  1824. else
  1825. ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1826. kalMemFree(prTxDesc, VIR_MEM_TYPE, ucTxDescSize);
  1827. prTxDesc = prStaRec->aprTxDescTemplate[ucTid] = NULL;
  1828. }
  1829. }
  1830. } else {
  1831. prTxDesc = (P_HW_MAC_TX_DESC_T) prStaRec->aprTxDescTemplate[0];
  1832. if (prTxDesc) {
  1833. if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc))
  1834. ucTxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;
  1835. else
  1836. ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
  1837. kalMemFree(prTxDesc, VIR_MEM_TYPE, ucTxDescSize);
  1838. prTxDesc = NULL;
  1839. }
  1840. for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++)
  1841. prStaRec->aprTxDescTemplate[ucTid] = NULL;
  1842. }
  1843. }
  1844. /*----------------------------------------------------------------------------*/
  1845. /*!
  1846. * @brief In this function, we'll write frame(PACKET_INFO_T) into HIF.
  1847. *
  1848. * @param prAdapter Pointer to the Adapter structure.
  1849. * @param ucPortIdx Port Number
  1850. * @param prQue a link list of P_MSDU_INFO_T
  1851. *
  1852. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1853. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1854. */
  1855. /*----------------------------------------------------------------------------*/
  1856. WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue)
  1857. {
  1858. P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
  1859. P_NATIVE_PACKET prNativePacket;
  1860. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  1861. UINT_8 ucTxDescSize;
  1862. UINT_32 u4ValidBufSize;
  1863. UINT_32 u4TotalLength;
  1864. P_TX_CTRL_T prTxCtrl;
  1865. QUE_T rFreeQueue;
  1866. P_QUE_T prFreeQueue;
  1867. PUINT_8 pucBufferTxD;
  1868. #if ((CFG_SDIO_TX_AGG == 1) && (CFG_SDIO_TX_AGG_LIMIT != 0))
  1869. BOOLEAN fgWriteNow;
  1870. #endif
  1871. ASSERT(prAdapter);
  1872. ASSERT(ucPortIdx < 2);
  1873. ASSERT(prQue);
  1874. prTxCtrl = &prAdapter->rTxCtrl;
  1875. u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize;
  1876. #if CFG_HIF_STATISTICS
  1877. prTxCtrl->u4TotalTxAccessNum++;
  1878. prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem;
  1879. #endif
  1880. prFreeQueue = &rFreeQueue;
  1881. QUEUE_INITIALIZE(prFreeQueue);
  1882. if (prQue->u4NumElem > 0) {
  1883. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue);
  1884. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  1885. u4TotalLength = 0;
  1886. while (prMsduInfo) {
  1887. prNativePacket = prMsduInfo->prPacket;
  1888. ASSERT(prNativePacket);
  1889. #if CFG_SUPPORT_MULTITHREAD
  1890. nicTxCopyDesc(prAdapter, (pucOutputBuf + u4TotalLength),
  1891. prMsduInfo->aucTxDescBuffer, &ucTxDescSize);
  1892. #else
  1893. nicTxFillDesc(prAdapter, prMsduInfo, (pucOutputBuf + u4TotalLength), &ucTxDescSize);
  1894. #endif
  1895. pucBufferTxD = (pucOutputBuf + u4TotalLength);
  1896. u4TotalLength += (ucTxDescSize + NIC_TX_DESC_PADDING_LENGTH);
  1897. if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING)
  1898. kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength);
  1899. else if (prMsduInfo->eSrc == TX_PACKET_MGMT)
  1900. kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength);
  1901. else
  1902. ASSERT(0);
  1903. u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength);
  1904. prNextMsduInfo = (P_MSDU_INFO_T)
  1905. QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry);
  1906. /* Free MSDU_INFO */
  1907. if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  1908. GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  1909. } else if (prMsduInfo->eSrc == TX_PACKET_OS) {
  1910. wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, TX_PROF_TAG_DRV_TX_DONE);
  1911. kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS);
  1912. prMsduInfo->prPacket = NULL;
  1913. } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
  1914. GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
  1915. }
  1916. if (prMsduInfo->pfTxDoneHandler) {
  1917. KAL_SPIN_LOCK_DECLARATION();
  1918. DBGLOG(TX, TRACE, "Wait WIDX:PID[%u:%u] SEQ[%u]\n",
  1919. prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, prMsduInfo->ucTxSeqNum);
  1920. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1921. QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
  1922. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1923. } else {
  1924. if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  1925. cnmMgtPktFree(prAdapter, prMsduInfo);
  1926. } else {
  1927. /* only free MSDU when it is not a MGMT frame */
  1928. QUEUE_INSERT_TAIL(prFreeQueue, (P_QUE_ENTRY_T) prMsduInfo);
  1929. }
  1930. }
  1931. #if (CFG_SDIO_TX_AGG == 0)
  1932. ASSERT(u4TotalLength <= u4ValidBufSize);
  1933. HAL_WRITE_TX_PORT(prAdapter, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
  1934. /* reset total length */
  1935. u4TotalLength = 0;
  1936. #elif ((CFG_SDIO_TX_AGG == 1) && (CFG_SDIO_TX_AGG_LIMIT != 0))
  1937. fgWriteNow = TRUE;
  1938. if (prNextMsduInfo) {
  1939. if ((u4TotalLength + prNextMsduInfo->u2FrameLength +
  1940. NIC_TX_DESC_AND_PADDING_LENGTH) < CFG_SDIO_TX_AGG_LIMIT) {
  1941. fgWriteNow = FALSE;
  1942. }
  1943. }
  1944. /* Write to HIF */
  1945. if (fgWriteNow) {
  1946. ASSERT(u4TotalLength <= u4ValidBufSize);
  1947. HAL_WRITE_TX_PORT(prAdapter, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
  1948. /* reset total length */
  1949. u4TotalLength = 0;
  1950. }
  1951. #endif
  1952. prMsduInfo = prNextMsduInfo;
  1953. }
  1954. #if ((CFG_SDIO_TX_AGG == 1) && (CFG_SDIO_TX_AGG_LIMIT == 0))
  1955. if (u4TotalLength > u4ValidBufSize) {
  1956. DBGLOG(TX, ERROR, "Tx Error! Port[%u] u4TotalLength[%u] > u4ValidBufSize[%u]\n",
  1957. ucPortIdx, u4TotalLength, u4ValidBufSize);
  1958. DBGLOG(TX, ERROR, "Tx Error! TxQ count[%u], FreeQ count[%u]\n",
  1959. prQue->u4NumElem, prFreeQueue->u4NumElem);
  1960. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prFreeQueue);
  1961. DBGLOG(TX, WARN, "=== Dump MsduInfo ===\n");
  1962. while (prMsduInfo) {
  1963. DBGLOG(TX, WARN, "Msdu[0x%p] Src[%u] Len[%u] Bss[%u] Sta[%u] TC[%u]\n",
  1964. prMsduInfo, prMsduInfo->eSrc, prMsduInfo->u2FrameLength,
  1965. prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex,
  1966. prMsduInfo->ucTC);
  1967. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry);
  1968. }
  1969. DBGLOG(TX, WARN, "=== Dump done ===\n");
  1970. qmDumpQueueStatus(prAdapter);
  1971. }
  1972. ASSERT(u4TotalLength <= u4ValidBufSize);
  1973. HAL_WRITE_TX_PORT(prAdapter, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
  1974. #endif
  1975. nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
  1976. }
  1977. return WLAN_STATUS_SUCCESS;
  1978. }
  1979. /*----------------------------------------------------------------------------*/
  1980. /*!
  1981. * \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
  1982. *
  1983. * @param prAdapter Pointer to the Adapter structure.
  1984. * @param prPacketInfo Pointer of CMD_INFO_T
  1985. * @param ucTC Specify the resource of TC
  1986. *
  1987. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1988. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1989. */
  1990. /*----------------------------------------------------------------------------*/
  1991. WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
  1992. {
  1993. P_WIFI_CMD_T prWifiCmd;
  1994. UINT_16 u2OverallBufferLength;
  1995. UINT_8 ucTxDescLength;
  1996. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  1997. P_NATIVE_PACKET prNativePacket;
  1998. P_MSDU_INFO_T prMsduInfo;
  1999. P_TX_CTRL_T prTxCtrl;
  2000. KAL_SPIN_LOCK_DECLARATION();
  2001. ASSERT(prAdapter);
  2002. ASSERT(prCmdInfo);
  2003. prTxCtrl = &prAdapter->rTxCtrl;
  2004. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  2005. if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
  2006. prMsduInfo = prCmdInfo->prMsduInfo;
  2007. #if CFG_SUPPORT_MULTITHREAD
  2008. nicTxCopyDesc(prAdapter, &pucOutputBuf[0], prMsduInfo->aucTxDescBuffer, &ucTxDescLength);
  2009. #else
  2010. nicTxComposeSecurityFrameDesc(prAdapter, prCmdInfo, &pucOutputBuf[0], &ucTxDescLength);
  2011. #endif
  2012. prNativePacket = prMsduInfo->prPacket;
  2013. u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + ucTxDescLength));
  2014. /* <3> Copy Frame Body */
  2015. kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + ucTxDescLength);
  2016. DBGLOG(TX, INFO, "TX SEC Frame: BSS[%u] WIDX:PID[%u:%u] STA[%u] LEN[%u] ENC[%u] RSP[%u]\n",
  2017. prCmdInfo->ucBssIndex,
  2018. HAL_MAC_TX_DESC_GET_WLAN_INDEX((P_HW_MAC_TX_DESC_T) &pucOutputBuf[0]),
  2019. prMsduInfo->ucPID, prCmdInfo->ucStaRecIndex,
  2020. ucTxDescLength + prCmdInfo->u2InfoBufLen,
  2021. HAL_MAC_TX_DESC_IS_PROTECTION((P_HW_MAC_TX_DESC_T) &pucOutputBuf[0]),
  2022. prMsduInfo->pfTxDoneHandler ? TRUE : FALSE);
  2023. prMsduInfo->prPacket = NULL;
  2024. if (prMsduInfo->pfTxDoneHandler) {
  2025. /* DBGLOG(INIT, TRACE,("Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum)); */
  2026. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2027. QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
  2028. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2029. } else {
  2030. /* Only return MSDU_INFO */
  2031. /* NativePacket will be freed at SEC frame CMD callback */
  2032. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  2033. }
  2034. } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
  2035. prMsduInfo = prCmdInfo->prMsduInfo;
  2036. ASSERT(prMsduInfo->fgIs802_11 == TRUE);
  2037. ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
  2038. #if CFG_SUPPORT_MULTITHREAD
  2039. nicTxCopyDesc(prAdapter, &pucOutputBuf[0], prMsduInfo->aucTxDescBuffer, &ucTxDescLength);
  2040. #else
  2041. nicTxFillDesc(prAdapter, prMsduInfo, &pucOutputBuf[0], &ucTxDescLength);
  2042. #endif
  2043. u2OverallBufferLength = ucTxDescLength + NIC_TX_DESC_PADDING_LENGTH + prMsduInfo->u2FrameLength;
  2044. /* <3> Copy Frame Body */
  2045. kalMemCopy(pucOutputBuf + ucTxDescLength + NIC_TX_DESC_PADDING_LENGTH,
  2046. prMsduInfo->prPacket, prMsduInfo->u2FrameLength);
  2047. /* <4> Management Frame Post-Processing */
  2048. GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  2049. DBGLOG(TX, INFO,
  2050. "TX MGMT Frame: BSS[%u] WIDX:PID[%u:%u] SEQ[%u] STA[%u] LEN[%u] RSP[%u]\n",
  2051. prCmdInfo->ucBssIndex, prMsduInfo->ucWlanIndex, prMsduInfo->ucPID,
  2052. prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, u2OverallBufferLength,
  2053. prMsduInfo->pfTxDoneHandler ? TRUE : FALSE);
  2054. if (prMsduInfo->pfTxDoneHandler) {
  2055. /* DBGLOG(INIT, TRACE,("Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum)); */
  2056. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2057. QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
  2058. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2059. } else {
  2060. cnmMgtPktFree(prAdapter, prMsduInfo);
  2061. }
  2062. } else {
  2063. prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer;
  2064. /* <2> Compose the Header of Transmit Data Structure for CMD Packet */
  2065. u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16)
  2066. HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  2067. prWifiCmd->u2TxByteCount = u2OverallBufferLength;
  2068. prWifiCmd->u2PQ_ID = CMD_PQ_ID;
  2069. prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
  2070. /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
  2071. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
  2072. ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
  2073. DBGLOG(TX, TRACE, "TX CMD: ID[0x%02X] SEQ[%u] SET[%u] LEN[%u]\n",
  2074. prWifiCmd->ucCID, prWifiCmd->ucSeqNum, prWifiCmd->ucSetQuery,
  2075. u2OverallBufferLength);
  2076. }
  2077. /* <4> Write frame to data port */
  2078. HAL_WRITE_TX_PORT(prAdapter,
  2079. (UINT_32) u2OverallBufferLength,
  2080. (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
  2081. return WLAN_STATUS_SUCCESS;
  2082. } /* end of nicTxCmd() */
  2083. /*----------------------------------------------------------------------------*/
  2084. /*!
  2085. * @brief This function will clean up all the pending frames in internal SW Queues
  2086. * by return the pending TX packet to the system.
  2087. *
  2088. * @param prAdapter Pointer to the Adapter structure.
  2089. *
  2090. * @return (none)
  2091. */
  2092. /*----------------------------------------------------------------------------*/
  2093. VOID nicTxRelease(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgProcTxDoneHandler)
  2094. {
  2095. P_TX_CTRL_T prTxCtrl;
  2096. P_MSDU_INFO_T prMsduInfo;
  2097. KAL_SPIN_LOCK_DECLARATION();
  2098. ASSERT(prAdapter);
  2099. prTxCtrl = &prAdapter->rTxCtrl;
  2100. nicTxFlush(prAdapter);
  2101. /* free MSDU_INFO_T from rTxMgmtMsduInfoList */
  2102. do {
  2103. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2104. QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T);
  2105. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  2106. if (prMsduInfo) {
  2107. DBGLOG(TX, INFO, "%s: Get Msdu WIDX:PID[%u:%u] SEQ[%u] from Pending Q\n",
  2108. __func__,
  2109. prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, prMsduInfo->ucTxSeqNum);
  2110. /* invoke done handler */
  2111. if (prMsduInfo->pfTxDoneHandler && fgProcTxDoneHandler)
  2112. prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
  2113. nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
  2114. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  2115. } else {
  2116. break;
  2117. }
  2118. } while (TRUE);
  2119. } /* end of nicTxRelease() */
  2120. VOID nicTxInterruptSanityCheck(IN P_ADAPTER_T prAdapter, IN UINT_16 *au2TxRlsCnt)
  2121. {
  2122. UINT_8 ucIdx;
  2123. BOOLEAN fgError = FALSE;
  2124. if (prAdapter->rWifiVar.ucTxDbg & BIT(1)) {
  2125. for (ucIdx = HIF_TX_AC0_INDEX; ucIdx < HIF_TX_NUM; ucIdx++) {
  2126. if (au2TxRlsCnt[ucIdx] > CFG_MAX_TX_PAGE_COUNT)
  2127. fgError = TRUE;
  2128. }
  2129. if (fgError)
  2130. DBGLOG(TX, ERROR, "Tx Done INT result, FFA[%u] AC[%u:%u:%u:%u:%u] CPU[%u]\n",
  2131. au2TxRlsCnt[HIF_TX_FFA_INDEX], au2TxRlsCnt[HIF_TX_AC0_INDEX],
  2132. au2TxRlsCnt[HIF_TX_AC1_INDEX], au2TxRlsCnt[HIF_TX_AC2_INDEX],
  2133. au2TxRlsCnt[HIF_TX_AC3_INDEX], au2TxRlsCnt[HIF_TX_AC4_INDEX],
  2134. au2TxRlsCnt[HIF_TX_CPU_INDEX]);
  2135. }
  2136. }
  2137. /*----------------------------------------------------------------------------*/
  2138. /*!
  2139. * @brief Process the TX Done interrupt and pull in more pending frames in SW
  2140. * Queues for transmission.
  2141. *
  2142. * @param prAdapter Pointer to the Adapter structure.
  2143. *
  2144. * @return (none)
  2145. */
  2146. /*----------------------------------------------------------------------------*/
  2147. VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter)
  2148. {
  2149. P_TX_CTRL_T prTxCtrl;
  2150. #if CFG_SDIO_INTR_ENHANCE
  2151. P_SDIO_CTRL_T prSDIOCtrl;
  2152. #else
  2153. UINT_32 au4TxCount[2];
  2154. #endif /* CFG_SDIO_INTR_ENHANCE */
  2155. ASSERT(prAdapter);
  2156. prTxCtrl = &prAdapter->rTxCtrl;
  2157. ASSERT(prTxCtrl);
  2158. /* Get the TX STATUS */
  2159. #if CFG_SDIO_INTR_ENHANCE
  2160. prSDIOCtrl = prAdapter->prSDIOCtrl;
  2161. #if DBG
  2162. /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */
  2163. #endif
  2164. nicTxInterruptSanityCheck(prAdapter, (PUINT_16) &prSDIOCtrl->rTxInfo);
  2165. nicTxReleaseResource(prAdapter, (PUINT_16) &prSDIOCtrl->rTxInfo);
  2166. kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo));
  2167. #else
  2168. HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]);
  2169. HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]);
  2170. DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]);
  2171. nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount);
  2172. #endif /* CFG_SDIO_INTR_ENHANCE */
  2173. nicTxAdjustTcq(prAdapter);
  2174. /* Indicate Service Thread */
  2175. if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
  2176. kalSetEvent(prAdapter->prGlueInfo);
  2177. } /* end of nicProcessTxInterrupt() */
  2178. /*----------------------------------------------------------------------------*/
  2179. /*!
  2180. * @brief this function frees packet of P_MSDU_INFO_T linked-list
  2181. *
  2182. * @param prAdapter Pointer to the Adapter structure.
  2183. * @param prMsduInfoList a link list of P_MSDU_INFO_T
  2184. *
  2185. * @return (none)
  2186. */
  2187. /*----------------------------------------------------------------------------*/
  2188. VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  2189. {
  2190. P_NATIVE_PACKET prNativePacket;
  2191. P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead;
  2192. P_TX_CTRL_T prTxCtrl;
  2193. ASSERT(prAdapter);
  2194. ASSERT(prMsduInfoListHead);
  2195. prTxCtrl = &prAdapter->rTxCtrl;
  2196. while (prMsduInfo) {
  2197. prNativePacket = prMsduInfo->prPacket;
  2198. if (prMsduInfo->eSrc == TX_PACKET_OS) {
  2199. if (prNativePacket)
  2200. kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE);
  2201. /*get per-AC Tx drop packets */
  2202. wlanUpdateTxStatistics(prAdapter, prMsduInfo, TRUE);
  2203. } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  2204. if (prMsduInfo->pfTxDoneHandler)
  2205. prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
  2206. if (prNativePacket)
  2207. cnmMemFree(prAdapter, prNativePacket);
  2208. } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
  2209. GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
  2210. }
  2211. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  2212. }
  2213. }
  2214. /*----------------------------------------------------------------------------*/
  2215. /*!
  2216. * @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList
  2217. *
  2218. * @param prAdapter Pointer to the Adapter structure.
  2219. * @param prMsduInfoList a link list of P_MSDU_INFO_T
  2220. *
  2221. * @return (none)
  2222. */
  2223. /*----------------------------------------------------------------------------*/
  2224. VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  2225. {
  2226. P_TX_CTRL_T prTxCtrl;
  2227. P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;
  2228. KAL_SPIN_LOCK_DECLARATION();
  2229. ASSERT(prAdapter);
  2230. prTxCtrl = &prAdapter->rTxCtrl;
  2231. ASSERT(prTxCtrl);
  2232. while (prMsduInfo) {
  2233. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  2234. switch (prMsduInfo->eSrc) {
  2235. case TX_PACKET_FORWARDING:
  2236. wlanReturnPacket(prAdapter, prMsduInfo->prPacket);
  2237. break;
  2238. case TX_PACKET_OS:
  2239. case TX_PACKET_OS_OID:
  2240. case TX_PACKET_MGMT:
  2241. default:
  2242. break;
  2243. }
  2244. /* Reset MSDU_INFO fields */
  2245. kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
  2246. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  2247. QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
  2248. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  2249. prMsduInfo = prNextMsduInfo;
  2250. };
  2251. }
  2252. /*----------------------------------------------------------------------------*/
  2253. /*!
  2254. * @brief this function fills packet information to P_MSDU_INFO_T
  2255. *
  2256. * @param prAdapter Pointer to the Adapter structure.
  2257. * @param prMsduInfo P_MSDU_INFO_T
  2258. * @param prPacket P_NATIVE_PACKET
  2259. *
  2260. * @retval TRUE Success to extract information
  2261. * @retval FALSE Fail to extract correct information
  2262. */
  2263. /*----------------------------------------------------------------------------*/
  2264. BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
  2265. {
  2266. P_GLUE_INFO_T prGlueInfo;
  2267. ASSERT(prAdapter);
  2268. kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
  2269. prGlueInfo = prAdapter->prGlueInfo;
  2270. ASSERT(prGlueInfo);
  2271. kalGetEthDestAddr(prAdapter->prGlueInfo, prPacket, prMsduInfo->aucEthDestAddr);
  2272. prMsduInfo->prPacket = prPacket;
  2273. prMsduInfo->ucBssIndex = GLUE_GET_PKT_BSS_IDX(prPacket);
  2274. prMsduInfo->ucUserPriority = GLUE_GET_PKT_TID(prPacket);
  2275. prMsduInfo->ucMacHeaderLength = GLUE_GET_PKT_HEADER_LEN(prPacket);
  2276. prMsduInfo->u2FrameLength = (UINT_16) GLUE_GET_PKT_FRAME_LEN(prPacket);
  2277. prMsduInfo->ucPageCount = nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE);
  2278. if (GLUE_IS_PKT_FLAG_SET(prPacket)) {
  2279. prMsduInfo->fgIs802_1x = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X);
  2280. prMsduInfo->fgIs802_3 = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_802_3);
  2281. prMsduInfo->fgIsVlanExists = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_VLAN_EXIST);
  2282. if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DHCP) && prAdapter->rWifiVar.ucDhcpTxDone)
  2283. prMsduInfo->pfTxDoneHandler = wlanDhcpTxDone;
  2284. else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ARP) && prAdapter->rWifiVar.ucArpTxDone)
  2285. prMsduInfo->pfTxDoneHandler = wlanArpTxDone;
  2286. }
  2287. /* Reset to default value by memory zero */
  2288. /* prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED; */
  2289. /* prMsduInfo->ucRateMode = MSDU_RATE_MODE_AUTO; */
  2290. /* prMsduInfo->fgIsTXDTemplateValid = FALSE; */
  2291. /* prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA; */
  2292. /* prMsduInfo->fgIs802_11 = FALSE; */
  2293. return TRUE;
  2294. }
  2295. /*----------------------------------------------------------------------------*/
  2296. /*!
  2297. * @brief this function update TCQ values by passing current status to txAdjustTcQuotas
  2298. *
  2299. * @param prAdapter Pointer to the Adapter structure.
  2300. *
  2301. * @retval WLAN_STATUS_SUCCESS Updated successfully
  2302. */
  2303. /*----------------------------------------------------------------------------*/
  2304. WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter)
  2305. {
  2306. #if CFG_SUPPORT_MULTITHREAD
  2307. TX_TCQ_ADJUST_T rTcqAdjust;
  2308. P_TX_CTRL_T prTxCtrl;
  2309. ASSERT(prAdapter);
  2310. prTxCtrl = &prAdapter->rTxCtrl;
  2311. ASSERT(prTxCtrl);
  2312. qmAdjustTcQuotasMthread(prAdapter, &rTcqAdjust, &prTxCtrl->rTc);
  2313. #else
  2314. UINT_32 u4Num;
  2315. TX_TCQ_ADJUST_T rTcqAdjust;
  2316. P_TX_CTRL_T prTxCtrl;
  2317. P_TX_TCQ_STATUS_T prTcqStatus;
  2318. KAL_SPIN_LOCK_DECLARATION();
  2319. ASSERT(prAdapter);
  2320. prTxCtrl = &prAdapter->rTxCtrl;
  2321. prTcqStatus = &prAdapter->rTxCtrl.rTc;
  2322. ASSERT(prTxCtrl);
  2323. if (qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc)) {
  2324. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  2325. for (u4Num = 0; u4Num < TC_NUM; u4Num++) {
  2326. /* Page count */
  2327. prTxCtrl->rTc.au2FreePageCount[u4Num] +=
  2328. (rTcqAdjust.acVariation[u4Num] * NIC_TX_MAX_PAGE_PER_FRAME);
  2329. prTxCtrl->rTc.au2MaxNumOfPage[u4Num] +=
  2330. (rTcqAdjust.acVariation[u4Num] * NIC_TX_MAX_PAGE_PER_FRAME);
  2331. /* Buffer count */
  2332. prTxCtrl->rTc.au2FreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num];
  2333. prTxCtrl->rTc.au2MaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num];
  2334. ASSERT(prTxCtrl->rTc.au2FreeBufferCount[u4Num] >= 0);
  2335. ASSERT(prTxCtrl->rTc.au2MaxNumOfBuffer[u4Num] >= 0);
  2336. }
  2337. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  2338. #if 0
  2339. DBGLOG(TX, LOUD,
  2340. "TCQ Status Free Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n",
  2341. prTcqStatus->au2FreePageCount[TC0_INDEX],
  2342. prTcqStatus->au2FreeBufferCount[TC0_INDEX],
  2343. prTcqStatus->au2FreePageCount[TC1_INDEX],
  2344. prTcqStatus->au2FreeBufferCount[TC1_INDEX],
  2345. prTcqStatus->au2FreePageCount[TC2_INDEX],
  2346. prTcqStatus->au2FreeBufferCount[TC2_INDEX],
  2347. prTcqStatus->au2FreePageCount[TC3_INDEX],
  2348. prTcqStatus->au2FreeBufferCount[TC3_INDEX],
  2349. prTcqStatus->au2FreePageCount[TC4_INDEX],
  2350. prTcqStatus->au2FreeBufferCount[TC4_INDEX],
  2351. prTcqStatus->au2FreePageCount[TC5_INDEX], prTcqStatus->au2FreeBufferCount[TC5_INDEX]));
  2352. #endif
  2353. DBGLOG(TX, LOUD,
  2354. "TCQ Status Max Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n",
  2355. prTcqStatus->au2MaxNumOfPage[TC0_INDEX],
  2356. prTcqStatus->au2MaxNumOfBuffer[TC0_INDEX],
  2357. prTcqStatus->au2MaxNumOfPage[TC1_INDEX],
  2358. prTcqStatus->au2MaxNumOfBuffer[TC1_INDEX],
  2359. prTcqStatus->au2MaxNumOfPage[TC2_INDEX],
  2360. prTcqStatus->au2MaxNumOfBuffer[TC2_INDEX],
  2361. prTcqStatus->au2MaxNumOfPage[TC3_INDEX],
  2362. prTcqStatus->au2MaxNumOfBuffer[TC3_INDEX],
  2363. prTcqStatus->au2MaxNumOfPage[TC4_INDEX],
  2364. prTcqStatus->au2MaxNumOfBuffer[TC4_INDEX],
  2365. prTcqStatus->au2MaxNumOfPage[TC5_INDEX], prTcqStatus->au2MaxNumOfBuffer[TC5_INDEX]));
  2366. }
  2367. #endif
  2368. return WLAN_STATUS_SUCCESS;
  2369. }
  2370. /*----------------------------------------------------------------------------*/
  2371. /*!
  2372. * @brief this function flushes all packets queued in STA/AC queue
  2373. *
  2374. * @param prAdapter Pointer to the Adapter structure.
  2375. *
  2376. * @retval WLAN_STATUS_SUCCESS Flushed successfully
  2377. */
  2378. /*----------------------------------------------------------------------------*/
  2379. WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter)
  2380. {
  2381. P_MSDU_INFO_T prMsduInfo;
  2382. KAL_SPIN_LOCK_DECLARATION();
  2383. ASSERT(prAdapter);
  2384. /* ask Per STA/AC queue to be fllushed and return all queued packets */
  2385. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  2386. prMsduInfo = qmFlushTxQueues(prAdapter);
  2387. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  2388. if (prMsduInfo != NULL) {
  2389. nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
  2390. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  2391. }
  2392. return WLAN_STATUS_SUCCESS;
  2393. }
  2394. #if CFG_ENABLE_FW_DOWNLOAD
  2395. /*----------------------------------------------------------------------------*/
  2396. /*!
  2397. * \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
  2398. * However this function is used for INIT_CMD.
  2399. *
  2400. * In order to avoid further maintenance issues, these 2 functions are separated
  2401. *
  2402. * @param prAdapter Pointer to the Adapter structure.
  2403. * @param prPacketInfo Pointer of CMD_INFO_T
  2404. * @param ucTC Specify the resource of TC
  2405. *
  2406. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  2407. * @retval WLAN_STATUS_FAILURE Bus access fail.
  2408. */
  2409. /*----------------------------------------------------------------------------*/
  2410. WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
  2411. {
  2412. UINT_16 u2OverallBufferLength;
  2413. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  2414. P_TX_CTRL_T prTxCtrl;
  2415. ASSERT(prAdapter);
  2416. ASSERT(prCmdInfo);
  2417. prTxCtrl = &prAdapter->rTxCtrl;
  2418. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  2419. u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16)
  2420. HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  2421. /* <1> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
  2422. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
  2423. ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
  2424. /* <2> Write frame to data port */
  2425. HAL_WRITE_TX_PORT(prAdapter,
  2426. (UINT_32) u2OverallBufferLength,
  2427. (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
  2428. return WLAN_STATUS_SUCCESS;
  2429. }
  2430. /*----------------------------------------------------------------------------*/
  2431. /*!
  2432. * \brief In this function, we'll reset TX resource counter to initial value used
  2433. * in F/W download state
  2434. *
  2435. * @param prAdapter Pointer to the Adapter structure.
  2436. *
  2437. * @retval WLAN_STATUS_SUCCESS Reset is done successfully.
  2438. */
  2439. /*----------------------------------------------------------------------------*/
  2440. WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter)
  2441. {
  2442. P_TX_CTRL_T prTxCtrl;
  2443. UINT_8 ucIdx;
  2444. DEBUGFUNC("nicTxInitResetResource");
  2445. ASSERT(prAdapter);
  2446. prTxCtrl = &prAdapter->rTxCtrl;
  2447. /* Delta page count */
  2448. kalMemZero(prTxCtrl->rTc.au2TxDonePageCount, sizeof(prTxCtrl->rTc.au2TxDonePageCount));
  2449. kalMemZero(prTxCtrl->rTc.au2PreUsedPageCount, sizeof(prTxCtrl->rTc.au2PreUsedPageCount));
  2450. prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX;
  2451. prTxCtrl->rTc.u2AvaliablePageCount = 0;
  2452. /* Page count */
  2453. prTxCtrl->rTc.au2MaxNumOfPage[TC0_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC0;
  2454. prTxCtrl->rTc.au2FreePageCount[TC0_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC0;
  2455. prTxCtrl->rTc.au2MaxNumOfPage[TC1_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC1;
  2456. prTxCtrl->rTc.au2FreePageCount[TC1_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC1;
  2457. prTxCtrl->rTc.au2MaxNumOfPage[TC2_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC2;
  2458. prTxCtrl->rTc.au2FreePageCount[TC2_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC2;
  2459. prTxCtrl->rTc.au2MaxNumOfPage[TC3_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC3;
  2460. prTxCtrl->rTc.au2FreePageCount[TC3_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC3;
  2461. prTxCtrl->rTc.au2MaxNumOfPage[TC4_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC4;
  2462. prTxCtrl->rTc.au2FreePageCount[TC4_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC4;
  2463. prTxCtrl->rTc.au2MaxNumOfPage[TC5_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC5;
  2464. prTxCtrl->rTc.au2FreePageCount[TC5_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC5;
  2465. /* Buffer count */
  2466. for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) {
  2467. prTxCtrl->rTc.au2MaxNumOfBuffer[ucIdx] =
  2468. prTxCtrl->rTc.au2MaxNumOfPage[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME;
  2469. prTxCtrl->rTc.au2FreeBufferCount[ucIdx] =
  2470. prTxCtrl->rTc.au2FreePageCount[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME;
  2471. }
  2472. return WLAN_STATUS_SUCCESS;
  2473. }
  2474. #endif
  2475. BOOLEAN nicTxProcessMngPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
  2476. {
  2477. UINT_16 u2RateCode;
  2478. P_BSS_INFO_T prBssInfo;
  2479. P_STA_RECORD_T prStaRec;
  2480. if (prMsduInfo->eSrc != TX_PACKET_MGMT)
  2481. return FALSE;
  2482. /* Sanity check */
  2483. if (!prMsduInfo->prPacket)
  2484. return FALSE;
  2485. if (!prMsduInfo->u2FrameLength)
  2486. return FALSE;
  2487. if (!prMsduInfo->ucMacHeaderLength)
  2488. return FALSE;
  2489. prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
  2490. prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  2491. /* MMPDU: force stick to TC4 */
  2492. prMsduInfo->ucTC = TC4_INDEX;
  2493. /* No Tx descriptor template for MMPDU */
  2494. prMsduInfo->fgIsTXDTemplateValid = FALSE;
  2495. /* Fixed Rate */
  2496. if (prMsduInfo->ucRateMode == MSDU_RATE_MODE_AUTO) {
  2497. prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC;
  2498. if (prStaRec)
  2499. u2RateCode = prStaRec->u2HwDefaultFixedRateCode;
  2500. else
  2501. u2RateCode = prBssInfo->u2HwDefaultFixedRateCode;
  2502. nicTxSetPktFixedRateOption(prMsduInfo, u2RateCode, FIX_BW_NO_FIXED, FALSE, FALSE);
  2503. }
  2504. #if CFG_SUPPORT_MULTITHREAD
  2505. nicTxFillDesc(prAdapter, prMsduInfo, prMsduInfo->aucTxDescBuffer, NULL);
  2506. #endif
  2507. return TRUE;
  2508. }
  2509. VOID nicTxProcessTxDoneEvent(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
  2510. {
  2511. P_EVENT_TX_DONE_T prTxDone;
  2512. P_MSDU_INFO_T prMsduInfo;
  2513. prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer);
  2514. if (prTxDone->ucFlag & BIT(0)) {
  2515. /* Tx Done with advanced info */
  2516. DBGLOG(TX, TRACE, "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u] SN[%u] CNT[%u] RATE[0x%04x]\n",
  2517. prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, prTxDone->ucStatus,
  2518. prTxDone->u2SequenceNumber, prTxDone->ucTxCount, prTxDone->u2TxRate);
  2519. } else {
  2520. DBGLOG(TX, TRACE, "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u] SN[%u]\n",
  2521. prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, prTxDone->ucStatus,
  2522. prTxDone->u2SequenceNumber);
  2523. }
  2524. /* call related TX Done Handler */
  2525. prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucWlanIndex, prTxDone->ucPacketSeq);
  2526. #if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
  2527. DBGLOG(TX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n",
  2528. prTxDone->au4Reserved1, prTxDone->au4Reserved2);
  2529. wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex,
  2530. prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2);
  2531. #endif
  2532. if (prMsduInfo) {
  2533. prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus));
  2534. if (prMsduInfo->eSrc == TX_PACKET_MGMT)
  2535. cnmMgtPktFree(prAdapter, prMsduInfo);
  2536. else
  2537. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  2538. }
  2539. }
  2540. /*----------------------------------------------------------------------------*/
  2541. /*!
  2542. * \brief this function enqueues MSDU_INFO_T into queue management,
  2543. * or command queue
  2544. *
  2545. * @param prAdapter Pointer to the Adapter structure.
  2546. * prMsduInfo Pointer to MSDU
  2547. *
  2548. * @retval WLAN_STATUS_SUCCESS Reset is done successfully.
  2549. */
  2550. /*----------------------------------------------------------------------------*/
  2551. WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
  2552. {
  2553. P_TX_CTRL_T prTxCtrl;
  2554. P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead;
  2555. QUE_T qDataPort0, qDataPort1;
  2556. P_QUE_T prDataPort0, prDataPort1;
  2557. P_CMD_INFO_T prCmdInfo;
  2558. WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
  2559. KAL_SPIN_LOCK_DECLARATION();
  2560. ASSERT(prAdapter);
  2561. ASSERT(prMsduInfo);
  2562. prTxCtrl = &prAdapter->rTxCtrl;
  2563. ASSERT(prTxCtrl);
  2564. prDataPort0 = &qDataPort0;
  2565. prDataPort1 = &qDataPort1;
  2566. QUEUE_INITIALIZE(prDataPort0);
  2567. QUEUE_INITIALIZE(prDataPort1);
  2568. /* check how many management frame are being queued */
  2569. while (prMsduInfo) {
  2570. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  2571. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  2572. if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  2573. if (nicTxProcessMngPacket(prAdapter, prMsduInfo)) {
  2574. /* Valid MGMT */
  2575. QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
  2576. } else {
  2577. /* Invalid MGMT */
  2578. DBGLOG(TX, WARN, "Invalid MGMT[0x%p] BSS[%u] STA[%u],free it\n",
  2579. prMsduInfo, prMsduInfo->ucBssIndex,
  2580. prMsduInfo->ucStaRecIndex);
  2581. cnmMgtPktFree(prAdapter, prMsduInfo);
  2582. }
  2583. } else {
  2584. QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
  2585. }
  2586. prMsduInfo = prNextMsduInfo;
  2587. }
  2588. if (prDataPort0->u4NumElem) {
  2589. /* send to QM */
  2590. KAL_SPIN_LOCK_DECLARATION();
  2591. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  2592. prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prDataPort0));
  2593. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  2594. /* post-process for dropped packets */
  2595. if (prRetMsduInfo) { /* unable to enqueue */
  2596. nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo);
  2597. nicTxReturnMsduInfo(prAdapter, prRetMsduInfo);
  2598. }
  2599. }
  2600. if (prDataPort1->u4NumElem) {
  2601. prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prDataPort1);
  2602. if (nicTxGetFreeCmdCount(prAdapter) < NIC_TX_CMD_INFO_RESERVED_COUNT) {
  2603. /* not enough descriptors for sending */
  2604. u4Status = WLAN_STATUS_FAILURE;
  2605. /* free all MSDUs */
  2606. while (prMsduInfoHead) {
  2607. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
  2608. if (prMsduInfoHead->pfTxDoneHandler != NULL) {
  2609. prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead,
  2610. TX_RESULT_DROPPED_IN_DRIVER);
  2611. }
  2612. cnmMgtPktFree(prAdapter, prMsduInfoHead);
  2613. prMsduInfoHead = prNextMsduInfo;
  2614. }
  2615. } else {
  2616. /* send to command queue */
  2617. while (prMsduInfoHead) {
  2618. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
  2619. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
  2620. QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
  2621. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
  2622. if (prCmdInfo) {
  2623. GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  2624. kalMemZero(prCmdInfo, sizeof(CMD_INFO_T));
  2625. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  2626. /* Tag MGMT enqueue time */
  2627. GET_CURRENT_SYSTIME(&prMsduInfoHead->rPktProfile.rEnqueueTimestamp);
  2628. #endif
  2629. prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME;
  2630. prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength;
  2631. prCmdInfo->pucInfoBuffer = NULL;
  2632. prCmdInfo->prMsduInfo = prMsduInfoHead;
  2633. prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex;
  2634. prCmdInfo->ucBssIndex = prMsduInfoHead->ucBssIndex;
  2635. prCmdInfo->pfCmdDoneHandler = NULL;
  2636. prCmdInfo->pfCmdTimeoutHandler = NULL;
  2637. prCmdInfo->fgIsOid = FALSE;
  2638. prCmdInfo->fgSetQuery = TRUE;
  2639. prCmdInfo->fgNeedResp = FALSE;
  2640. prCmdInfo->ucCmdSeqNum = prMsduInfoHead->ucTxSeqNum;
  2641. DBGLOG(TX, TRACE, "%s: EN-Q MSDU[0x%p] SEQ[%u] BSS[%u] STA[%u] to CMD Q\n",
  2642. __func__, prMsduInfoHead,
  2643. prMsduInfoHead->ucTxSeqNum, prMsduInfoHead->ucBssIndex,
  2644. prMsduInfoHead->ucStaRecIndex);
  2645. kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
  2646. } else {
  2647. /* Cmd free count is larger than expected, but allocation fail. */
  2648. u4Status = WLAN_STATUS_FAILURE;
  2649. if (prMsduInfoHead->pfTxDoneHandler != NULL) {
  2650. prMsduInfoHead->pfTxDoneHandler(prAdapter,
  2651. prMsduInfoHead,
  2652. TX_RESULT_DROPPED_IN_DRIVER);
  2653. }
  2654. cnmMgtPktFree(prAdapter, prMsduInfoHead);
  2655. }
  2656. prMsduInfoHead = prNextMsduInfo;
  2657. }
  2658. }
  2659. }
  2660. /* indicate service thread for sending */
  2661. if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0)
  2662. kalSetEvent(prAdapter->prGlueInfo);
  2663. return u4Status;
  2664. }
  2665. /*----------------------------------------------------------------------------*/
  2666. /*!
  2667. * \brief this function returns WLAN index
  2668. *
  2669. * @param prAdapter Pointer to the Adapter structure.
  2670. *
  2671. * @retval
  2672. */
  2673. /*----------------------------------------------------------------------------*/
  2674. UINT_8 nicTxGetWlanIdx(P_ADAPTER_T prAdapter, UINT_8 ucBssIdx, UINT_8 ucStaRecIdx)
  2675. {
  2676. P_STA_RECORD_T prStaRec;
  2677. P_BSS_INFO_T prBssInfo;
  2678. UINT_8 ucWlanIndex = NIC_TX_DEFAULT_WLAN_INDEX;
  2679. prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIdx);
  2680. prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx);
  2681. if (prStaRec)
  2682. ucWlanIndex = prStaRec->ucWlanIndex;
  2683. else if ((ucStaRecIdx == STA_REC_INDEX_BMCAST) && prBssInfo->fgIsInUse)
  2684. ucWlanIndex = prBssInfo->ucBMCWlanIndex;
  2685. if (ucWlanIndex >= WTBL_SIZE) {
  2686. DBGLOG(TX, WARN, "%s: Unexpected WIDX[%u] BSS[%u] STA[%u], set WIDX to default value[%u]\n",
  2687. ucWlanIndex, ucBssIdx, ucStaRecIdx, NIC_TX_DEFAULT_WLAN_INDEX);
  2688. ucWlanIndex = NIC_TX_DEFAULT_WLAN_INDEX;
  2689. }
  2690. return ucWlanIndex;
  2691. }
  2692. /*----------------------------------------------------------------------------*/
  2693. /*!
  2694. * \brief
  2695. *
  2696. * @param prAdapter Pointer to the Adapter structure.
  2697. *
  2698. * @retval
  2699. */
  2700. /*----------------------------------------------------------------------------*/
  2701. BOOLEAN nicTxIsMgmtResourceEnough(IN P_ADAPTER_T prAdapter)
  2702. {
  2703. if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2))
  2704. return TRUE;
  2705. else
  2706. return FALSE;
  2707. }
  2708. /*----------------------------------------------------------------------------*/
  2709. /*!
  2710. * \brief this function returns available count in command queue
  2711. *
  2712. * @param prAdapter Pointer to the Adapter structure.
  2713. *
  2714. * @retval
  2715. */
  2716. /*----------------------------------------------------------------------------*/
  2717. UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter)
  2718. {
  2719. ASSERT(prAdapter);
  2720. return prAdapter->rFreeCmdList.u4NumElem;
  2721. }
  2722. /*----------------------------------------------------------------------------*/
  2723. /*!
  2724. * \brief this function returns page count of frame
  2725. *
  2726. * @param u4FrameLength frame length
  2727. *
  2728. * @retval page count of this frame
  2729. */
  2730. /*----------------------------------------------------------------------------*/
  2731. UINT_8 nicTxGetPageCount(IN UINT_32 u4FrameLength, IN BOOLEAN fgIncludeDesc)
  2732. {
  2733. UINT_32 u4RequiredBufferSize;
  2734. UINT_8 ucPageCount;
  2735. /* Frame Buffer
  2736. * |<--Tx Descriptor-->|<--Tx descriptor padding-->|<--802.3/802.11 Header-->|
  2737. * <--Header padding-->|<--Payload-->|
  2738. */
  2739. if (fgIncludeDesc)
  2740. u4RequiredBufferSize = u4FrameLength;
  2741. else
  2742. u4RequiredBufferSize = NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH + u4FrameLength;
  2743. if (NIC_TX_PAGE_SIZE_IS_POWER_OF_2)
  2744. ucPageCount = (UINT_8) ((u4RequiredBufferSize + (NIC_TX_PAGE_SIZE - 1)) >>
  2745. NIC_TX_PAGE_SIZE_IN_POWER_OF_2);
  2746. else
  2747. ucPageCount = (UINT_8) ((u4RequiredBufferSize + (NIC_TX_PAGE_SIZE - 1)) / NIC_TX_PAGE_SIZE);
  2748. return ucPageCount;
  2749. }
  2750. UINT_8 nicTxGetCmdPageCount(IN P_CMD_INFO_T prCmdInfo)
  2751. {
  2752. UINT_8 ucPageCount;
  2753. switch (prCmdInfo->eCmdType) {
  2754. case COMMAND_TYPE_NETWORK_IOCTL:
  2755. case COMMAND_TYPE_GENERAL_IOCTL:
  2756. ucPageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen, TRUE);
  2757. break;
  2758. case COMMAND_TYPE_SECURITY_FRAME:
  2759. case COMMAND_TYPE_MANAGEMENT_FRAME:
  2760. ucPageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen, FALSE);
  2761. break;
  2762. default:
  2763. DBGLOG(TX, WARN, "Undefined CMD Type(%u)\n", prCmdInfo->eCmdType);
  2764. ucPageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen, FALSE);
  2765. break;
  2766. }
  2767. return ucPageCount;
  2768. }
  2769. VOID
  2770. nicTxSetMngPacket(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo,
  2771. UINT_8 ucBssIndex, UINT_8 ucStaRecIndex, UINT_8 ucMacHeaderLength,
  2772. UINT_16 u2FrameLength, PFN_TX_DONE_HANDLER pfTxDoneHandler, UINT_8 ucRateMode)
  2773. {
  2774. ASSERT(prMsduInfo);
  2775. prMsduInfo->ucBssIndex = ucBssIndex;
  2776. prMsduInfo->ucStaRecIndex = ucStaRecIndex;
  2777. prMsduInfo->ucMacHeaderLength = ucMacHeaderLength;
  2778. prMsduInfo->u2FrameLength = u2FrameLength;
  2779. prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
  2780. prMsduInfo->ucRateMode = ucRateMode;
  2781. /* Reset default value for MMPDU */
  2782. prMsduInfo->fgIs802_11 = TRUE;
  2783. prMsduInfo->fgIs802_1x = FALSE;
  2784. prMsduInfo->u4FixedRateOption = 0;
  2785. prMsduInfo->cPowerOffset = 0;
  2786. prMsduInfo->u4Option = 0;
  2787. prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  2788. prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;
  2789. prMsduInfo->ucPacketType = TX_PACKET_TYPE_MGMT;
  2790. prMsduInfo->ucUserPriority = 0;
  2791. prMsduInfo->eSrc = TX_PACKET_MGMT;
  2792. }
  2793. VOID
  2794. nicTxSetDataPacket(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo,
  2795. UINT_8 ucBssIndex, UINT_8 ucStaRecIndex, UINT_8 ucMacHeaderLength,
  2796. UINT_16 u2FrameLength, PFN_TX_DONE_HANDLER pfTxDoneHandler,
  2797. UINT_8 ucRateMode, ENUM_TX_PACKET_SRC_T eSrc, UINT_8 ucTID,
  2798. BOOLEAN fgIs802_11Frame, BOOLEAN fgIs1xFrame)
  2799. {
  2800. ASSERT(prMsduInfo);
  2801. prMsduInfo->ucBssIndex = ucBssIndex;
  2802. prMsduInfo->ucStaRecIndex = ucStaRecIndex;
  2803. prMsduInfo->ucMacHeaderLength = ucMacHeaderLength;
  2804. prMsduInfo->u2FrameLength = u2FrameLength;
  2805. prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
  2806. prMsduInfo->ucRateMode = ucRateMode;
  2807. prMsduInfo->ucUserPriority = ucTID;
  2808. prMsduInfo->fgIs802_11 = fgIs802_11Frame;
  2809. prMsduInfo->eSrc = eSrc;
  2810. prMsduInfo->fgIs802_1x = fgIs1xFrame;
  2811. /* Reset default value for data packet */
  2812. prMsduInfo->u4FixedRateOption = 0;
  2813. prMsduInfo->cPowerOffset = 0;
  2814. prMsduInfo->u4Option = 0;
  2815. prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  2816. prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;
  2817. prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA;
  2818. }
  2819. VOID nicTxFillDescByPktOption(P_MSDU_INFO_T prMsduInfo, P_HW_MAC_TX_DESC_T prTxDesc)
  2820. {
  2821. UINT_32 u4PktOption = prMsduInfo->u4Option;
  2822. BOOLEAN fgIsLongFormat;
  2823. BOOLEAN fgProtected = FALSE;
  2824. /* Skip this function if no options is set */
  2825. if (!u4PktOption)
  2826. return;
  2827. fgIsLongFormat = HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc);
  2828. /* Fields in DW0 and DW1 (Short Format) */
  2829. if (u4PktOption & MSDU_OPT_NO_ACK)
  2830. HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc);
  2831. if (u4PktOption & MSDU_OPT_PROTECTED_FRAME) {
  2832. HAL_MAC_TX_DESC_SET_PROTECTION(prTxDesc);
  2833. fgProtected = TRUE;
  2834. }
  2835. switch (HAL_MAC_TX_DESC_GET_HEADER_FORMAT(prTxDesc)) {
  2836. case HEADER_FORMAT_802_11_ENHANCE_MODE:
  2837. if (u4PktOption & MSDU_OPT_EOSP)
  2838. HAL_MAC_TX_DESC_SET_EOSP(prTxDesc);
  2839. if (u4PktOption & MSDU_OPT_AMSDU)
  2840. HAL_MAC_TX_DESC_SET_AMSDU(prTxDesc);
  2841. break;
  2842. case HEADER_FORMAT_NON_802_11:
  2843. if (u4PktOption & MSDU_OPT_EOSP)
  2844. HAL_MAC_TX_DESC_SET_EOSP(prTxDesc);
  2845. if (u4PktOption & MSDU_OPT_MORE_DATA)
  2846. HAL_MAC_TX_DESC_SET_MORE_DATA(prTxDesc);
  2847. if (u4PktOption & MSDU_OPT_REMOVE_VLAN)
  2848. HAL_MAC_TX_DESC_SET_REMOVE_VLAN(prTxDesc);
  2849. break;
  2850. case HEADER_FORMAT_802_11_NORMAL_MODE:
  2851. if (fgProtected && prMsduInfo->prPacket) {
  2852. P_WLAN_MAC_HEADER_T prWlanHeader =
  2853. (P_WLAN_MAC_HEADER_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
  2854. prWlanHeader->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
  2855. }
  2856. break;
  2857. default:
  2858. break;
  2859. }
  2860. if (!fgIsLongFormat)
  2861. return;
  2862. /* Fields in DW2~6 (Long Format) */
  2863. if (u4PktOption & MSDU_OPT_NO_AGGREGATE)
  2864. HAL_MAC_TX_DESC_SET_BA_DISABLE(prTxDesc);
  2865. if (u4PktOption & MSDU_OPT_TIMING_MEASURE)
  2866. HAL_MAC_TX_DESC_SET_TIMING_MEASUREMENT(prTxDesc);
  2867. if (u4PktOption & MSDU_OPT_NDP)
  2868. HAL_MAC_TX_DESC_SET_NDP(prTxDesc);
  2869. if (u4PktOption & MSDU_OPT_NDPA)
  2870. HAL_MAC_TX_DESC_SET_NDPA(prTxDesc);
  2871. if (u4PktOption & MSDU_OPT_SOUNDING)
  2872. HAL_MAC_TX_DESC_SET_SOUNDING_FRAME(prTxDesc);
  2873. if (u4PktOption & MSDU_OPT_FORCE_RTS)
  2874. HAL_MAC_TX_DESC_SET_FORCE_RTS_CTS(prTxDesc);
  2875. if (u4PktOption & MSDU_OPT_BIP)
  2876. HAL_MAC_TX_DESC_SET_BIP(prTxDesc);
  2877. /* SW field */
  2878. if (u4PktOption & MSDU_OPT_SW_DURATION)
  2879. HAL_MAC_TX_DESC_SET_DURATION_CONTROL_BY_SW(prTxDesc);
  2880. if (u4PktOption & MSDU_OPT_SW_PS_BIT)
  2881. HAL_MAC_TX_DESC_SET_SW_PM_CONTROL(prTxDesc);
  2882. if (u4PktOption & MSDU_OPT_SW_HTC)
  2883. HAL_MAC_TX_DESC_SET_HTC_EXIST(prTxDesc);
  2884. if (u4PktOption & MSDU_OPT_SW_BAR_SN)
  2885. HAL_MAC_TX_DESC_SET_SW_BAR_SSN(prTxDesc);
  2886. if (u4PktOption & MSDU_OPT_MANUAL_SN) {
  2887. HAL_MAC_TX_DESC_SET_TXD_SN_VALID(prTxDesc);
  2888. HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(prTxDesc, prMsduInfo->u2SwSN);
  2889. }
  2890. }
  2891. /*----------------------------------------------------------------------------*/
  2892. /*!
  2893. * @brief Extra configuration for Tx packet
  2894. *
  2895. * @retval
  2896. */
  2897. /*----------------------------------------------------------------------------*/
  2898. VOID nicTxConfigPktOption(P_MSDU_INFO_T prMsduInfo, UINT_32 u4OptionMask, BOOLEAN fgSetOption)
  2899. {
  2900. if (fgSetOption)
  2901. prMsduInfo->u4Option |= u4OptionMask;
  2902. else
  2903. prMsduInfo->u4Option &= ~u4OptionMask;
  2904. }
  2905. VOID nicTxFillDescByPktControl(P_MSDU_INFO_T prMsduInfo, P_HW_MAC_TX_DESC_T prTxDesc)
  2906. {
  2907. UINT_8 ucPktControl = prMsduInfo->ucControlFlag;
  2908. UINT_8 ucSwReserved;
  2909. /* Skip this function if no options is set */
  2910. if (!ucPktControl)
  2911. return;
  2912. if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc)) {
  2913. ucSwReserved = HAL_MAC_TX_DESC_GET_SW_RESERVED(prTxDesc);
  2914. if (ucPktControl & MSDU_CONTROL_FLAG_FORCE_TX)
  2915. ucSwReserved |= MSDU_CONTROL_FLAG_FORCE_TX;
  2916. HAL_MAC_TX_DESC_SET_SW_RESERVED(prTxDesc, ucSwReserved);
  2917. }
  2918. }
  2919. VOID nicTxConfigPktControlFlag(P_MSDU_INFO_T prMsduInfo, UINT_8 ucControlFlagMask, BOOLEAN fgSetFlag)
  2920. {
  2921. /* Set control flag */
  2922. if (fgSetFlag)
  2923. prMsduInfo->ucControlFlag |= ucControlFlagMask;
  2924. else
  2925. prMsduInfo->ucControlFlag &= ~ucControlFlagMask; /* Clear control flag */
  2926. }
  2927. VOID nicTxSetPktLifeTime(P_MSDU_INFO_T prMsduInfo, UINT_32 u4TxLifeTimeInMs)
  2928. {
  2929. prMsduInfo->u4RemainingLifetime = u4TxLifeTimeInMs;
  2930. prMsduInfo->u4Option |= MSDU_OPT_MANUAL_LIFE_TIME;
  2931. }
  2932. VOID nicTxSetPktRetryLimit(P_MSDU_INFO_T prMsduInfo, UINT_8 ucRetryLimit)
  2933. {
  2934. prMsduInfo->ucRetryLimit = ucRetryLimit;
  2935. prMsduInfo->u4Option |= MSDU_OPT_MANUAL_RETRY_LIMIT;
  2936. }
  2937. VOID nicTxSetPktPowerOffset(P_MSDU_INFO_T prMsduInfo, INT_8 cPowerOffset)
  2938. {
  2939. prMsduInfo->cPowerOffset = cPowerOffset;
  2940. prMsduInfo->u4Option |= MSDU_OPT_MANUAL_POWER_OFFSET;
  2941. }
  2942. VOID nicTxSetPktSequenceNumber(P_MSDU_INFO_T prMsduInfo, UINT_16 u2SN)
  2943. {
  2944. prMsduInfo->u2SwSN = u2SN;
  2945. prMsduInfo->u4Option |= MSDU_OPT_MANUAL_SN;
  2946. }
  2947. VOID nicTxSetPktMacTxQue(P_MSDU_INFO_T prMsduInfo, UINT_8 ucMacTxQue)
  2948. {
  2949. UINT_8 ucTcIdx;
  2950. for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
  2951. if (arTcResourceControl[ucTcIdx].ucDestQueueIndex == ucMacTxQue)
  2952. break;
  2953. }
  2954. if (ucTcIdx < TC_NUM) {
  2955. prMsduInfo->ucTC = ucTcIdx;
  2956. prMsduInfo->u4Option |= MSDU_OPT_MANUAL_TX_QUE;
  2957. }
  2958. }
  2959. VOID
  2960. nicTxSetPktFixedRateOptionFull(P_MSDU_INFO_T prMsduInfo,
  2961. UINT_16 u2RateCode,
  2962. UINT_8 ucBandwidth,
  2963. BOOLEAN fgShortGI,
  2964. BOOLEAN fgLDPC,
  2965. BOOLEAN fgDynamicBwRts,
  2966. BOOLEAN fgSpatialExt,
  2967. BOOLEAN fgEtxBeamforming,
  2968. BOOLEAN fgItxBeamforming, UINT_8 ucAntennaIndex, UINT_8 ucAntennaPriority)
  2969. {
  2970. HW_MAC_TX_DESC_T rTxDesc;
  2971. P_HW_MAC_TX_DESC_T prTxDesc = &rTxDesc;
  2972. kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH);
  2973. /* Follow the format of Tx descriptor DW 6 */
  2974. HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode);
  2975. if (ucBandwidth)
  2976. HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth);
  2977. if (fgShortGI)
  2978. HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc);
  2979. if (fgLDPC)
  2980. HAL_MAC_TX_DESC_SET_FR_LDPC(prTxDesc);
  2981. if (fgDynamicBwRts)
  2982. HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc);
  2983. if (fgSpatialExt)
  2984. HAL_MAC_TX_DESC_SET_FR_SPE_EN(prTxDesc);
  2985. if (fgEtxBeamforming)
  2986. HAL_MAC_TX_DESC_SET_FR_ETX_BF(prTxDesc);
  2987. if (fgItxBeamforming)
  2988. HAL_MAC_TX_DESC_SET_FR_ITX_BF(prTxDesc);
  2989. HAL_MAC_TX_DESC_SET_FR_ANTENNA_ID(prTxDesc, ucAntennaIndex);
  2990. HAL_MAC_TX_DESC_SET_FR_ANTENNA_PRIORITY(prTxDesc, ucAntennaPriority);
  2991. /* Write back to RateOption of MSDU_INFO */
  2992. HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);
  2993. }
  2994. VOID
  2995. nicTxSetPktFixedRateOption(P_MSDU_INFO_T prMsduInfo,
  2996. UINT_16 u2RateCode, UINT_8 ucBandwidth, BOOLEAN fgShortGI, BOOLEAN fgDynamicBwRts)
  2997. {
  2998. HW_MAC_TX_DESC_T rTxDesc;
  2999. P_HW_MAC_TX_DESC_T prTxDesc = &rTxDesc;
  3000. kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH);
  3001. /* Follow the format of Tx descriptor DW 6 */
  3002. HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode);
  3003. if (ucBandwidth)
  3004. HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth);
  3005. if (fgShortGI)
  3006. HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc);
  3007. if (fgDynamicBwRts)
  3008. HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc);
  3009. /* Write back to RateOption of MSDU_INFO */
  3010. HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);
  3011. }
  3012. VOID nicTxSetPktMoreData(P_MSDU_INFO_T prCurrentMsduInfo, BOOLEAN fgSetMoreDataBit)
  3013. {
  3014. P_WLAN_MAC_HEADER_T prWlanMacHeader = NULL;
  3015. if (prCurrentMsduInfo->fgIs802_11) {
  3016. prWlanMacHeader =
  3017. (P_WLAN_MAC_HEADER_T) (((PUINT_8) (prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD);
  3018. }
  3019. if (fgSetMoreDataBit) {
  3020. if (!prCurrentMsduInfo->fgIs802_11)
  3021. prCurrentMsduInfo->u4Option |= MSDU_OPT_MORE_DATA;
  3022. else
  3023. prWlanMacHeader->u2FrameCtrl |= MASK_FC_MORE_DATA;
  3024. } else {
  3025. if (!prCurrentMsduInfo->fgIs802_11)
  3026. prCurrentMsduInfo->u4Option &= ~MSDU_OPT_MORE_DATA;
  3027. else
  3028. prWlanMacHeader->u2FrameCtrl &= ~MASK_FC_MORE_DATA;
  3029. }
  3030. }
  3031. UINT_8 nicTxAssignPID(IN P_ADAPTER_T prAdapter, IN UINT_8 ucWlanIndex)
  3032. {
  3033. UINT_8 ucRetval;
  3034. PUINT_8 pucPidPool;
  3035. ASSERT(prAdapter);
  3036. pucPidPool = &prAdapter->aucPidPool[ucWlanIndex];
  3037. ucRetval = *pucPidPool;
  3038. /* Driver side Tx Sequence number: 1~127 */
  3039. (*pucPidPool)++;
  3040. if (*pucPidPool > NIC_TX_DESC_DRIVER_PID_MAX)
  3041. *pucPidPool = NIC_TX_DESC_DRIVER_PID_MIN;
  3042. return ucRetval;
  3043. }
  3044. VOID nicTxSetPktEOSP(P_MSDU_INFO_T prCurrentMsduInfo, BOOLEAN fgSetEOSPBit)
  3045. {
  3046. P_WLAN_MAC_HEADER_QOS_T prWlanMacHeader = NULL;
  3047. BOOLEAN fgWriteToDesc = TRUE;
  3048. if (prCurrentMsduInfo->fgIs802_11) {
  3049. prWlanMacHeader =
  3050. (P_WLAN_MAC_HEADER_QOS_T) (((PUINT_8) (prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD);
  3051. fgWriteToDesc = FALSE;
  3052. }
  3053. if (fgSetEOSPBit) {
  3054. if (fgWriteToDesc)
  3055. prCurrentMsduInfo->u4Option |= MSDU_OPT_EOSP;
  3056. else
  3057. prWlanMacHeader->u2QosCtrl |= MASK_QC_EOSP;
  3058. } else {
  3059. if (fgWriteToDesc)
  3060. prCurrentMsduInfo->u4Option &= ~MSDU_OPT_EOSP;
  3061. else
  3062. prWlanMacHeader->u2QosCtrl &= ~MASK_QC_EOSP;
  3063. }
  3064. }
  3065. WLAN_STATUS
  3066. nicTxDummyTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
  3067. {
  3068. DBGLOG(TX, TRACE, "Msdu WIDX:PID[%u:%u] SEQ[%u] Tx Status[%u]\n",
  3069. prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, prMsduInfo->ucTxSeqNum, rTxDoneStatus);
  3070. return WLAN_STATUS_SUCCESS;
  3071. }
  3072. /*----------------------------------------------------------------------------*/
  3073. /*!
  3074. * @brief Update BSS Tx Params
  3075. *
  3076. * @param prStaRec The peer
  3077. *
  3078. * @return (none)
  3079. */
  3080. /*----------------------------------------------------------------------------*/
  3081. VOID nicTxUpdateBssDefaultRate(P_BSS_INFO_T prBssInfo)
  3082. {
  3083. UINT_8 ucLowestBasicRateIndex;
  3084. prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
  3085. /* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
  3086. if (rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) {
  3087. nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE, ucLowestBasicRateIndex,
  3088. &prBssInfo->u2HwDefaultFixedRateCode);
  3089. } else {
  3090. switch (prBssInfo->ucNonHTBasicPhyType) {
  3091. case PHY_TYPE_ERP_INDEX:
  3092. case PHY_TYPE_OFDM_INDEX:
  3093. prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
  3094. break;
  3095. default:
  3096. prBssInfo->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG;
  3097. break;
  3098. }
  3099. }
  3100. }
  3101. /*----------------------------------------------------------------------------*/
  3102. /*!
  3103. * @brief Update StaRec Tx parameters
  3104. *
  3105. * @param prStaRec The peer
  3106. *
  3107. * @return (none)
  3108. */
  3109. /*----------------------------------------------------------------------------*/
  3110. VOID nicTxUpdateStaRecDefaultRate(P_STA_RECORD_T prStaRec)
  3111. {
  3112. UINT_8 ucLowestBasicRateIndex;
  3113. prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
  3114. /* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
  3115. if (rateGetLowestRateIndexFromRateSet(prStaRec->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) {
  3116. nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE,
  3117. ucLowestBasicRateIndex, &prStaRec->u2HwDefaultFixedRateCode);
  3118. } else {
  3119. if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11B)
  3120. prStaRec->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG;
  3121. else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11G)
  3122. prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
  3123. else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11A)
  3124. prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
  3125. else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N)
  3126. prStaRec->u2HwDefaultFixedRateCode = RATE_MM_MCS_0;
  3127. }
  3128. }