nic_tx.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1
  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. * 06 13 2012 yuche.tsai
  13. * NULL
  14. * Update maintrunk driver.
  15. * Add support for driver compose assoc request frame.
  16. *
  17. * 11 18 2011 eddie.chen
  18. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  19. * Add log counter for tx
  20. *
  21. * 11 09 2011 eddie.chen
  22. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  23. * Add xlog for beacon timeout and sta aging timeout.
  24. *
  25. * 11 08 2011 eddie.chen
  26. * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
  27. * Add xlog function.
  28. *
  29. * 05 17 2011 cp.wu
  30. * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss
  31. * disconnection
  32. * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state.
  33. *
  34. * 04 12 2011 eddie.chen
  35. * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
  36. * Fix the sta index in processing security frame
  37. * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
  38. * Add debug message.
  39. *
  40. * 04 12 2011 cp.wu
  41. * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
  42. * dropping cases for TC4 path
  43. * remove unused variables.
  44. *
  45. * 04 12 2011 cp.wu
  46. * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame
  47. * dropping cases for TC4 path
  48. * 1. add nicTxGetResource() API for QM to make decisions.
  49. * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case.
  50. *
  51. * 03 17 2011 cp.wu
  52. * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage
  53. * after system running for a long period
  54. * use pre-allocated buffer for storing enhanced interrupt response as well
  55. *
  56. * 03 15 2011 cp.wu
  57. * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous
  58. * memory consumption
  59. * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
  60. * 2. Use common coalescing buffer for both TX/RX directions
  61. *
  62. *
  63. * 02 16 2011 cp.wu
  64. * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count
  65. * and modify behavior
  66. * 1. add new API: nicTxGetFreeCmdCount()
  67. * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly
  68. *
  69. * 01 24 2011 cp.wu
  70. * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
  71. * 1. add an extra counter for tracking pending forward frames.
  72. * 2. notify TX service thread as well when there is pending forward frame
  73. * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
  74. *
  75. * 01 12 2011 cp.wu
  76. * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
  77. * needs such information
  78. * fill mac header length information for 802.1x frames.
  79. *
  80. * 12 31 2010 cp.wu
  81. * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system
  82. * scheduling
  83. * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being
  84. * loaded
  85. *
  86. * 11 01 2010 yarco.yang
  87. * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
  88. * Add GPIO debug function
  89. *
  90. * 10 18 2010 cp.wu
  91. * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore
  92. * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion
  93. * 2. shorten polling count for shorter response time
  94. * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well
  95. *
  96. * 10 06 2010 cp.wu
  97. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  98. * code reorganization to improve isolation between GLUE and CORE layers.
  99. *
  100. * 09 29 2010 wh.su
  101. * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
  102. * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
  103. *
  104. * 09 27 2010 wh.su
  105. * NULL
  106. * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error
  107. *
  108. * 09 24 2010 wh.su
  109. * NULL
  110. * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra
  111. * bytes padding.
  112. *
  113. * 09 01 2010 cp.wu
  114. * NULL
  115. * HIFSYS Clock Source Workaround
  116. *
  117. * 08 30 2010 cp.wu
  118. * NULL
  119. * API added: nicTxPendingPackets(), for simplifying porting layer
  120. *
  121. * 08 30 2010 cp.wu
  122. * NULL
  123. * eliminate klockwork errors
  124. *
  125. * 08 20 2010 wh.su
  126. * NULL
  127. * adding the eapol callback setting.
  128. *
  129. * 08 18 2010 yarco.yang
  130. * NULL
  131. * 1. Fixed HW checksum offload function not work under Linux issue.
  132. * 2. Add debug message.
  133. *
  134. * 08 05 2010 yuche.tsai
  135. * NULL
  136. * .
  137. *
  138. * 08 03 2010 cp.wu
  139. * NULL
  140. * surpress compilation warning.
  141. *
  142. * 08 02 2010 jeffrey.chang
  143. * NULL
  144. * 1) modify tx service thread to avoid busy looping
  145. * 2) add spin lock declartion for linux build
  146. *
  147. * 07 29 2010 cp.wu
  148. * NULL
  149. * simplify post-handling after TX_DONE interrupt is handled.
  150. *
  151. * 07 19 2010 jeffrey.chang
  152. *
  153. * Linux port modification
  154. *
  155. * 07 13 2010 cp.wu
  156. *
  157. * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets
  158. * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending
  159. * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network
  160. * operation
  161. *
  162. * 07 08 2010 cp.wu
  163. *
  164. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  165. *
  166. * 06 29 2010 yarco.yang
  167. * [WPD00003837][MT6620]Data Path Refine
  168. * replace g_rQM with Adpater->rQM
  169. *
  170. * 06 25 2010 cp.wu
  171. * [WPD00003833][MT6620 and MT5931] Driver migration
  172. * add API in que_mgt to retrieve sta-rec index for security frames.
  173. *
  174. * 06 24 2010 cp.wu
  175. * [WPD00003833][MT6620 and MT5931] Driver migration
  176. * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path.
  177. *
  178. * 06 23 2010 yarco.yang
  179. * [WPD00003837][MT6620]Data Path Refine
  180. * Merge g_arStaRec[] into adapter->arStaRec[]
  181. *
  182. * 06 22 2010 cp.wu
  183. * [WPD00003833][MT6620 and MT5931] Driver migration
  184. * 1) add command warpper for STA-REC/BSS-INFO sync.
  185. * 2) enhance command packet sending procedure for non-oid part
  186. * 3) add command packet definitions for STA-REC/BSS-INFO sync.
  187. *
  188. * 06 21 2010 cp.wu
  189. * [WPD00003833][MT6620 and MT5931] Driver migration
  190. * add checking for TX descriptor poll.
  191. *
  192. * 06 21 2010 cp.wu
  193. * [WPD00003833][MT6620 and MT5931] Driver migration
  194. * TX descriptors are now allocated once for reducing allocation overhead
  195. *
  196. * 06 18 2010 cm.chang
  197. * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
  198. * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
  199. *
  200. * 06 15 2010 cp.wu
  201. * [WPD00003833][MT6620 and MT5931] Driver migration
  202. * change zero-padding for TX port access to HAL.
  203. *
  204. * 06 15 2010 cp.wu
  205. * [WPD00003833][MT6620 and MT5931] Driver migration
  206. * .
  207. *
  208. * 06 15 2010 cp.wu
  209. * [WPD00003833][MT6620 and MT5931] Driver migration
  210. * .
  211. *
  212. * 06 14 2010 cp.wu
  213. * [WPD00003833][MT6620 and MT5931] Driver migration
  214. * fill extra information for revised HIF_TX_HEADER.
  215. *
  216. * 06 11 2010 cp.wu
  217. * [WPD00003833][MT6620 and MT5931] Driver migration
  218. * 1) migrate assoc.c.
  219. * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
  220. * 3) add configuration options for CNM_MEM and RSN modules
  221. * 4) add data path for management frames
  222. * 5) eliminate rPacketInfo of MSDU_INFO_T
  223. *
  224. * 06 10 2010 cp.wu
  225. * [WPD00003833][MT6620 and MT5931] Driver migration
  226. * change to enqueue TX frame infinitely.
  227. *
  228. * 06 09 2010 cp.wu
  229. * [WPD00003833][MT6620 and MT5931] Driver migration
  230. * add TX_PACKET_MGMT to indicate the frame is coming from management modules
  231. *
  232. * 06 06 2010 kevin.huang
  233. * [WPD00003832][MT6620 5931] Create driver base
  234. * [MT6620 5931] Create driver base
  235. *
  236. * 05 10 2010 cp.wu
  237. * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
  238. * fill network type field while doing frame identification.
  239. *
  240. * 04 23 2010 cp.wu
  241. * [WPD00001943]Create WiFi test driver framework on WinXP
  242. * surpress compiler warning
  243. *
  244. * 04 06 2010 jeffrey.chang
  245. * [WPD00003826]Initial import for Linux port
  246. * Tag the packet for QoS on Tx path
  247. *
  248. * 03 30 2010 cp.wu
  249. * [WPD00001943]Create WiFi test driver framework on WinXP
  250. * remove driver-land statistics.
  251. *
  252. * 03 29 2010 jeffrey.chang
  253. * [WPD00003826]Initial import for Linux port
  254. * improve none-glue code portability
  255. *
  256. * 03 24 2010 jeffrey.chang
  257. * [WPD00003826]Initial import for Linux port
  258. * initial import for Linux port
  259. *
  260. * 03 24 2010 cp.wu
  261. * [WPD00001943]Create WiFi test driver framework on WinXP
  262. * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
  263. * * * * *
  264. *
  265. * 03 10 2010 cp.wu
  266. * [WPD00001943]Create WiFi test driver framework on WinXP
  267. * code clean: removing unused variables and structure definitions
  268. *
  269. * 03 08 2010 cp.wu
  270. * [WPD00001943]Create WiFi test driver framework on WinXP
  271. * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
  272. * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
  273. *
  274. * 03 02 2010 cp.wu
  275. * [WPD00001943]Create WiFi test driver framework on WinXP
  276. * add mutex to avoid multiple access to qmTxQueue simultaneously.
  277. *
  278. * 02 26 2010 cp.wu
  279. * [WPD00001943]Create WiFi test driver framework on WinXP
  280. * avoid referring to NDIS-specific data structure directly from non-glue layer.
  281. *
  282. * 02 24 2010 cp.wu
  283. * [WPD00001943]Create WiFi test driver framework on WinXP
  284. * add Ethernet destination address information in packet info for TX
  285. *
  286. * 02 10 2010 cp.wu
  287. * [WPD00001943]Create WiFi test driver framework on WinXP
  288. * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
  289. * * * * * * 2) firmware image length is now retrieved via NdisFileOpen
  290. * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
  291. * * * * * * 4) nicRxWaitResponse() revised
  292. * * * * * * 5) another set of TQ counter default value is added for fw-download state
  293. * * * * * * 6) Wi-Fi load address is now retrieved from registry too
  294. *
  295. * 02 09 2010 cp.wu
  296. * [WPD00001943]Create WiFi test driver framework on WinXP
  297. * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
  298. * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP
  299. * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes
  300. *
  301. * 02 08 2010 cp.wu
  302. * [WPD00001943]Create WiFi test driver framework on WinXP
  303. * prepare for implementing fw download logic
  304. *
  305. * 01 27 2010 cp.wu
  306. * [WPD00001943]Create WiFi test driver framework on WinXP
  307. * 1. eliminate improper variable in rHifInfo
  308. * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged
  309. * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode
  310. * * * * * * * * * 4. correct some HAL implementation
  311. *
  312. * 01 13 2010 tehuang.liu
  313. * [WPD00001943]Create WiFi test driver framework on WinXP
  314. * Enabled the Burst_End Indication mechanism
  315. *
  316. * 01 13 2010 cp.wu
  317. * [WPD00001943]Create WiFi test driver framework on WinXP
  318. * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo
  319. *
  320. * 12 30 2009 cp.wu
  321. * [WPD00001943]Create WiFi test driver framework on WinXP
  322. * 1) According to CMD/EVENT documentation v0.8,
  323. * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
  324. * * * * * * * * * * and result is retrieved by get ATInfo instead
  325. * * * * * * * * * * 2) add 4 counter for recording aggregation statistics
  326. ** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752
  327. ** remove unused API
  328. ** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752
  329. ** correct assertion criterion
  330. ** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752
  331. ** correct trivial mistake
  332. ** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752
  333. ** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data
  334. ** + add more assertion for packet size check
  335. ** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752
  336. ** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort
  337. ** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752
  338. ** add 2 assertion for size check
  339. ** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461
  340. ** Add debug message
  341. ** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752
  342. ** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T
  343. ** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752
  344. ** use TC4 instead of TC5 for command packet
  345. ** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752
  346. ** add flush for reset
  347. ** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752
  348. ** fill prMsduInfo->ucUserPriority
  349. ** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752
  350. ** fill u2SeqNo
  351. ** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752
  352. ** integration with SD1's data path API
  353. ** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752
  354. ** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList
  355. ** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752
  356. ** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum,
  357. ** WIFI_CMD_T will be created inside oid handler
  358. ** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752
  359. ** use TxAccquireResource instead of accessing TCQ directly.
  360. ** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084
  361. ** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752
  362. ** add nicTxMsduInfoList () implementation
  363. ** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752
  364. ** add nicTxAdjustTcq() implementation
  365. ** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752
  366. ** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure
  367. ** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752
  368. ** add SD1_SD3_DATAPATH_INTEGRATION data path handling
  369. ** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084
  370. ** modify TX hdr format, fix tx retransmission issue
  371. ** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084
  372. ** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084
  373. ** modify TX SW data structure
  374. ** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084
  375. ** modify HAL part
  376. ** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084
  377. ** update for new HW design
  378. ** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725
  379. ** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461
  380. ** Assign SeqNum to CMD Packet
  381. ** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461
  382. ** Add debug message
  383. ** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461
  384. ** Fix Query Command need resp issue
  385. ** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461
  386. ** Move OS dependent code to kalQueryTxOOBData()
  387. ** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461
  388. ** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port
  389. ** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461
  390. ** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand()
  391. ** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461
  392. ** Move the CMD_INFO_T related function to cmd_buf.c
  393. ** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426
  394. ** Update OOB query for TX packet
  395. ** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426
  396. ** Support PKGUIO
  397. ** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461
  398. ** Add virtual OOB for HIF LOOPBACK SW PRETEST
  399. ** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461
  400. ** Add function for SDIO_TX_ENHANCE
  401. ** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461
  402. ** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test.
  403. ** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461
  404. ** Add code for TX Data & Cmd Packet
  405. ** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461
  406. ** Fix LINT warning
  407. ** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461
  408. ** Update TX PATH API
  409. ** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426
  410. ** Init for develop
  411. **
  412. */
  413. /*******************************************************************************
  414. * C O M P I L E R F L A G S
  415. ********************************************************************************
  416. */
  417. /*******************************************************************************
  418. * E X T E R N A L R E F E R E N C E S
  419. ********************************************************************************
  420. */
  421. #include "precomp.h"
  422. /*******************************************************************************
  423. * C O N S T A N T S
  424. ********************************************************************************
  425. */
  426. /*******************************************************************************
  427. * D A T A T Y P E S
  428. ********************************************************************************
  429. */
  430. /*******************************************************************************
  431. * P U B L I C D A T A
  432. ********************************************************************************
  433. */
  434. /*******************************************************************************
  435. * P R I V A T E D A T A
  436. ********************************************************************************
  437. */
  438. /*******************************************************************************
  439. * M A C R O S
  440. ********************************************************************************
  441. */
  442. /*******************************************************************************
  443. * F U N C T I O N D E C L A R A T I O N S
  444. ********************************************************************************
  445. */
  446. /*******************************************************************************
  447. * F U N C T I O N S
  448. ********************************************************************************
  449. */
  450. /*----------------------------------------------------------------------------*/
  451. /*!
  452. * @brief This function will initial all variables in regard to SW TX Queues and
  453. * all free lists of MSDU_INFO_T and SW_TFCB_T.
  454. *
  455. * @param prAdapter Pointer to the Adapter structure.
  456. *
  457. * @return (none)
  458. */
  459. /*----------------------------------------------------------------------------*/
  460. VOID nicTxInitialize(IN P_ADAPTER_T prAdapter)
  461. {
  462. P_TX_CTRL_T prTxCtrl;
  463. PUINT_8 pucMemHandle;
  464. P_MSDU_INFO_T prMsduInfo;
  465. UINT_32 i;
  466. KAL_SPIN_LOCK_DECLARATION();
  467. DEBUGFUNC("nicTxInitialize");
  468. ASSERT(prAdapter);
  469. prTxCtrl = &prAdapter->rTxCtrl;
  470. /* 4 <1> Initialization of Traffic Class Queue Parameters */
  471. nicTxResetResource(prAdapter);
  472. #if CFG_SDIO_TX_AGG
  473. prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;
  474. #endif /* CFG_SDIO_TX_AGG */
  475. /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */
  476. QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList);
  477. pucMemHandle = prTxCtrl->pucTxCached;
  478. for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) {
  479. prMsduInfo = (P_MSDU_INFO_T) pucMemHandle;
  480. kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
  481. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  482. QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
  483. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  484. pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T));
  485. }
  486. ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM);
  487. /* Check if the memory allocation consist with this initialization function */
  488. ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize);
  489. QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue);
  490. prTxCtrl->i4TxMgmtPendingNum = 0;
  491. #if CFG_HIF_STATISTICS
  492. prTxCtrl->u4TotalTxAccessNum = 0;
  493. prTxCtrl->u4TotalTxPacketNum = 0;
  494. #endif
  495. prTxCtrl->i4PendingFwdFrameCount = 0;
  496. qmInit(prAdapter);
  497. TX_RESET_ALL_CNTS(prTxCtrl);
  498. } /* end of nicTxInitialize() */
  499. /*----------------------------------------------------------------------------*/
  500. /*!
  501. * \brief Driver maintain a variable that is synchronous with the usage of individual
  502. * TC Buffer Count. This function will check if has enough TC Buffer for incoming
  503. * packet and then update the value after promise to provide the resources.
  504. *
  505. * \param[in] prAdapter Pointer to the Adapter structure.
  506. * \param[in] ucTC Specify the resource of TC
  507. *
  508. * \retval WLAN_STATUS_SUCCESS Resource is available and been assigned.
  509. * \retval WLAN_STATUS_RESOURCES Resource is not available.
  510. */
  511. /*----------------------------------------------------------------------------*/
  512. UINT_32 u4CurrTick = 0;
  513. WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt)
  514. {
  515. #define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */
  516. #define TC4_NO_RESOURCE_DELAY_1S 1 /* exponential of 1s */
  517. P_TX_CTRL_T prTxCtrl;
  518. WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES;
  519. KAL_SPIN_LOCK_DECLARATION();
  520. ASSERT(prAdapter);
  521. prTxCtrl = &prAdapter->rTxCtrl;
  522. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  523. /* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n",
  524. ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */
  525. do {
  526. if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) {
  527. if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) {
  528. DBGLOG(TX, EVENT, "<wlan> aucFreeBufferCount = %d\n",
  529. prTxCtrl->rTc.aucFreeBufferCount[ucTC]);
  530. if (prTxCtrl->rTc.aucFreeBufferCount[ucTC])
  531. u4CurrTick = 0;
  532. break;
  533. }
  534. }
  535. if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) {
  536. if (ucTC == TC4_INDEX)
  537. u4CurrTick = 0;
  538. /* get a available TX entry */
  539. prTxCtrl->rTc.aucFreeBufferCount[ucTC]--;
  540. DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n",
  541. ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]);
  542. u4Status = WLAN_STATUS_SUCCESS;
  543. }
  544. } while (FALSE);
  545. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  546. if (ucTC == TC4_INDEX) {
  547. if (u4CurrTick == 0)
  548. u4CurrTick = kalGetTimeTick();
  549. if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick,
  550. SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_1S))) {
  551. wlanDumpCommandFwStatus();
  552. }
  553. if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick,
  554. SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) {
  555. wlanDumpTcResAndTxedCmd(NULL, 0);
  556. cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue");
  557. glDumpConnSysCpuInfo(prAdapter->prGlueInfo);
  558. kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__);
  559. glDoChipReset();
  560. u4CurrTick = 0;
  561. }
  562. }
  563. return u4Status;
  564. } /* end of nicTxAcquireResourceAndTFCBs() */
  565. /*----------------------------------------------------------------------------*/
  566. /*!
  567. * @brief Driver maintain a variable that is synchronous with the usage of individual
  568. * TC Buffer Count. This function will do polling if FW has return the resource.
  569. * Used when driver start up before enable interrupt.
  570. *
  571. * @param prAdapter Pointer to the Adapter structure.
  572. * @param ucTC Specify the resource of TC
  573. *
  574. * @retval WLAN_STATUS_SUCCESS Resource is available.
  575. * @retval WLAN_STATUS_FAILURE Resource is not available.
  576. */
  577. /*----------------------------------------------------------------------------*/
  578. WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
  579. {
  580. P_TX_CTRL_T prTxCtrl;
  581. WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
  582. INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT;
  583. UINT_32 au4WTSR[2];
  584. ASSERT(prAdapter);
  585. prTxCtrl = &prAdapter->rTxCtrl;
  586. if (ucTC >= TC_NUM)
  587. return WLAN_STATUS_FAILURE;
  588. if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0)
  589. return WLAN_STATUS_SUCCESS;
  590. while (i-- > 0) {
  591. HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR);
  592. if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
  593. u4Status = WLAN_STATUS_FAILURE;
  594. break;
  595. } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) {
  596. if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) {
  597. u4Status = WLAN_STATUS_SUCCESS;
  598. break;
  599. }
  600. kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
  601. } else {
  602. kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
  603. }
  604. if (i < NIC_TX_RESOURCE_POLLING_TIMEOUT - 30) {
  605. wlanReadFwStatus(prAdapter);
  606. wlanDumpCommandFwStatus();
  607. }
  608. }
  609. if (i <= 0 && ucTC == TC4_INDEX) {
  610. DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n");
  611. wlanDumpTcResAndTxedCmd(NULL, 0);
  612. glDumpConnSysCpuInfo(prAdapter->prGlueInfo);
  613. }
  614. #if DBG
  615. {
  616. INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1);
  617. if (i4Times) {
  618. DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n",
  619. i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC));
  620. }
  621. }
  622. #endif /* DBG */
  623. return u4Status;
  624. } /* end of nicTxPollingResource() */
  625. /*----------------------------------------------------------------------------*/
  626. /*!
  627. * \brief Driver maintain a variable that is synchronous with the usage of individual
  628. * TC Buffer Count. This function will release TC Buffer count according to
  629. * the given TX_STATUS COUNTER after TX Done.
  630. *
  631. * \param[in] prAdapter Pointer to the Adapter structure.
  632. * \param[in] u4TxStatusCnt Value of TX STATUS
  633. *
  634. * @return (none)
  635. */
  636. /*----------------------------------------------------------------------------*/
  637. BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt)
  638. {
  639. PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt;
  640. P_TX_CTRL_T prTxCtrl;
  641. BOOLEAN bStatus = FALSE;
  642. UINT_32 i;
  643. KAL_SPIN_LOCK_DECLARATION();
  644. ASSERT(prAdapter);
  645. prTxCtrl = &prAdapter->rTxCtrl;
  646. if (pu4Tmp[0] | pu4Tmp[1]) {
  647. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  648. for (i = 0; i < TC_NUM; i++)
  649. prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i];
  650. if (aucTxRlsCnt[TC4_INDEX] != 0)
  651. wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]);
  652. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  653. #if 0
  654. for (i = 0; i < TC_NUM; i++) {
  655. DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n",
  656. i, prTxCtrl->rTc.aucFreeBufferCount[i], i,
  657. prTxCtrl->rTc.aucMaxNumOfBuffer[i]);
  658. }
  659. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]);
  660. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]);
  661. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]);
  662. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]);
  663. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]);
  664. DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]);
  665. #endif
  666. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]);
  667. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]);
  668. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]);
  669. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]);
  670. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]);
  671. ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]);
  672. bStatus = TRUE;
  673. }
  674. return bStatus;
  675. } /* end of nicTxReleaseResource() */
  676. /*----------------------------------------------------------------------------*/
  677. /*!
  678. * \brief Reset TC Buffer Count to initialized value
  679. *
  680. * \param[in] prAdapter Pointer to the Adapter structure.
  681. *
  682. * @return WLAN_STATUS_SUCCESS
  683. */
  684. /*----------------------------------------------------------------------------*/
  685. WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter)
  686. {
  687. P_TX_CTRL_T prTxCtrl;
  688. KAL_SPIN_LOCK_DECLARATION();
  689. DEBUGFUNC("nicTxResetResource");
  690. ASSERT(prAdapter);
  691. prTxCtrl = &prAdapter->rTxCtrl;
  692. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  693. prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0;
  694. prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0;
  695. prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1;
  696. prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1;
  697. prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2;
  698. prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2;
  699. prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3;
  700. prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3;
  701. prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4;
  702. prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4;
  703. prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5;
  704. prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5;
  705. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  706. return WLAN_STATUS_SUCCESS;
  707. }
  708. /*----------------------------------------------------------------------------*/
  709. /*!
  710. * @brief Driver maintain a variable that is synchronous with the usage of individual
  711. * TC Buffer Count. This function will return the value for other component
  712. * which needs this information for making decisions
  713. *
  714. * @param prAdapter Pointer to the Adapter structure.
  715. * @param ucTC Specify the resource of TC
  716. *
  717. * @retval UINT_8 The number of corresponding TC number
  718. */
  719. /*----------------------------------------------------------------------------*/
  720. UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
  721. {
  722. P_TX_CTRL_T prTxCtrl;
  723. ASSERT(prAdapter);
  724. prTxCtrl = &prAdapter->rTxCtrl;
  725. ASSERT(prTxCtrl);
  726. if (ucTC >= TC_NUM)
  727. return 0;
  728. else
  729. return prTxCtrl->rTc.aucFreeBufferCount[ucTC];
  730. }
  731. /*----------------------------------------------------------------------------*/
  732. /*!
  733. * @brief In this function, we'll aggregate frame(PACKET_INFO_T)
  734. * corresponding to HIF TX port
  735. *
  736. * @param prAdapter Pointer to the Adapter structure.
  737. * @param prMsduInfoListHead a link list of P_MSDU_INFO_T
  738. *
  739. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  740. * @retval WLAN_STATUS_FAILURE Bus access fail.
  741. */
  742. /*----------------------------------------------------------------------------*/
  743. WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  744. {
  745. P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
  746. QUE_T qDataPort0, qDataPort1;
  747. WLAN_STATUS status;
  748. BOOLEAN pfgIsSecOrMgmt = FALSE;
  749. ASSERT(prAdapter);
  750. ASSERT(prMsduInfoListHead);
  751. prMsduInfo = prMsduInfoListHead;
  752. QUEUE_INITIALIZE(&qDataPort0);
  753. QUEUE_INITIALIZE(&qDataPort1);
  754. /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
  755. while (prMsduInfo) {
  756. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  757. #if DBG && 0
  758. LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n",
  759. prMsduInfo->ucTC,
  760. prMsduInfo->ucNetworkType,
  761. prMsduInfo->ucMacHeaderLength,
  762. prMsduInfo->u2FrameLength,
  763. prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11);
  764. LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr);
  765. #endif
  766. /* double-check available TX resouce (need to sync with CONNSYS FW) */
  767. /* caller must guarantee that the TX resource is enough in the func; OR assert here */
  768. switch (prMsduInfo->ucTC) {
  769. case TC0_INDEX:
  770. case TC1_INDEX:
  771. case TC2_INDEX:
  772. case TC3_INDEX:
  773. case TC5_INDEX: /* Broadcast/multicast data packets */
  774. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  775. QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
  776. status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE);
  777. ASSERT(status == WLAN_STATUS_SUCCESS)
  778. break;
  779. case TC4_INDEX: /* Command or 802.1x packets */
  780. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  781. QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
  782. if ((prMsduInfo->fgIs802_1x == TRUE) ||
  783. (prMsduInfo->fgIs802_11 == TRUE))
  784. pfgIsSecOrMgmt = TRUE;
  785. status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt);
  786. ASSERT(status == WLAN_STATUS_SUCCESS)
  787. break;
  788. default:
  789. ASSERT(0);
  790. break;
  791. }
  792. prMsduInfo = prNextMsduInfo;
  793. }
  794. /* send packets to HIF port0 or port1 here */
  795. if (qDataPort0.u4NumElem > 0)
  796. nicTxMsduQueue(prAdapter, 0, &qDataPort0);
  797. if (qDataPort1.u4NumElem > 0)
  798. nicTxMsduQueue(prAdapter, 1, &qDataPort1);
  799. return WLAN_STATUS_SUCCESS;
  800. }
  801. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  802. #if CFG_PRINT_RTP_PROFILE
  803. PKT_PROFILE_T rPrevRoundLastPkt;
  804. BOOLEAN
  805. nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo,
  806. IN P_PKT_PROFILE_T prPrevRoundLastPkt,
  807. IN P_PKT_PROFILE_T prPktProfile,
  808. IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted)
  809. {
  810. BOOLEAN fgPrintCurPkt = FALSE;
  811. if (u4MaxDeltaTime) {
  812. /* 4 1. check delta between current round first pkt and prevous round last pkt */
  813. if (!*pfgGotFirst) {
  814. *pfgGotFirst = TRUE;
  815. if (prPrevRoundLastPkt->fgIsValid) {
  816. if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) {
  817. PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR");
  818. fgPrintCurPkt = TRUE;
  819. }
  820. }
  821. }
  822. /* 4 2. check delta between current pkt and previous pkt */
  823. if (prPrevProfileMsduInfo) {
  824. if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) {
  825. PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P");
  826. fgPrintCurPkt = TRUE;
  827. }
  828. }
  829. /* 4 3. check delta of current pkt lifetime */
  830. if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime))
  831. fgPrintCurPkt = TRUE;
  832. }
  833. /* 4 4. print every X RTP packets */
  834. #if CFG_SUPPORT_WFD
  835. if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0)
  836. fgPrintCurPkt = TRUE;
  837. #endif
  838. return fgPrintCurPkt;
  839. }
  840. BOOLEAN
  841. nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo,
  842. IN P_PKT_PROFILE_T prPrevRoundLastPkt,
  843. IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer)
  844. {
  845. BOOLEAN fgPrintCurPkt = FALSE;
  846. P_PKT_PROFILE_T prTarPktProfile = NULL;
  847. UINT_16 u2PredictSn = 0;
  848. UINT_16 u2CurrentSn = 0;
  849. UINT_8 aucNote[8];
  850. /* 4 1. Get the target packet profile to compare */
  851. /* 4 1.1 check SN between current round first pkt and prevous round last pkt */
  852. if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) {
  853. *pfgGotFirst = TRUE;
  854. prTarPktProfile = prPrevRoundLastPkt;
  855. kalMemCopy(aucNote, "PR\0", 3);
  856. }
  857. /* 4 1.2 check SN between current pkt and previous pkt */
  858. else if (prPrevProfileMsduInfo) {
  859. prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile;
  860. kalMemCopy(aucNote, "P\0", 2);
  861. }
  862. if (!prTarPktProfile)
  863. return FALSE;
  864. /* 4 2. Check IP or RTP SN */
  865. switch (ucLayer) {
  866. /* Check IP SN */
  867. case 0:
  868. u2PredictSn = prTarPktProfile->u2IpSn + 1;
  869. u2CurrentSn = prPktProfile->u2IpSn;
  870. break;
  871. /* Check RTP SN */
  872. case 1:
  873. default:
  874. u2PredictSn = prTarPktProfile->u2RtpSn + 1;
  875. u2CurrentSn = prPktProfile->u2RtpSn;
  876. break;
  877. }
  878. /* 4 */
  879. /* 4 3. Compare SN */
  880. if (u2CurrentSn != u2PredictSn) {
  881. PRINT_PKT_PROFILE(prTarPktProfile, aucNote);
  882. fgPrintCurPkt = TRUE;
  883. }
  884. return fgPrintCurPkt;
  885. }
  886. #endif
  887. VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  888. {
  889. P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;
  890. P_PKT_PROFILE_T prPktProfile;
  891. UINT_16 u2MagicCode = 0;
  892. UINT_8 ucDebugtMode = 0;
  893. #if CFG_PRINT_RTP_PROFILE
  894. P_MSDU_INFO_T prPrevProfileMsduInfo = NULL;
  895. P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt;
  896. BOOLEAN fgPrintCurPkt = FALSE;
  897. BOOLEAN fgGotFirst = FALSE;
  898. UINT_8 ucSnToBePrinted = 0;
  899. UINT_32 u4MaxDeltaTime = 50; /* in ms */
  900. #endif
  901. #if CFG_ENABLE_PER_STA_STATISTICS
  902. UINT_32 u4PktPrintPeriod = 0;
  903. #endif
  904. #if CFG_SUPPORT_WFD
  905. P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
  906. if (prAdapter->fgIsP2PRegistered) {
  907. prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
  908. u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp;
  909. ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode;
  910. /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */
  911. /* u2MagicCode = 0xE040; */
  912. /* } */
  913. }
  914. #endif
  915. #if CFG_PRINT_RTP_PROFILE
  916. if ((u2MagicCode >= 0xF000)) {
  917. ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7));
  918. u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10);
  919. } else {
  920. ucSnToBePrinted = 0;
  921. u4MaxDeltaTime = 0;
  922. }
  923. #endif
  924. #if CFG_ENABLE_PER_STA_STATISTICS
  925. if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000))
  926. u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32);
  927. else
  928. u4PktPrintPeriod = 0;
  929. #endif
  930. while (prMsduInfo) {
  931. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  932. prPktProfile = &prMsduInfo->rPktProfile;
  933. if (prPktProfile->fgIsValid) {
  934. prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick();
  935. if (ucDebugtMode > 1) {
  936. #if CFG_PRINT_RTP_PROFILE
  937. #if CFG_PRINT_RTP_SN_SKIP
  938. fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo,
  939. prPrevRoundLastPkt,
  940. prPktProfile, &fgGotFirst, 0);
  941. #else
  942. fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo,
  943. prPrevRoundLastPkt,
  944. prPktProfile,
  945. &fgGotFirst,
  946. u4MaxDeltaTime, ucSnToBePrinted);
  947. #endif
  948. /* Print current pkt profile */
  949. if (fgPrintCurPkt && ucDebugtMode > 1)
  950. PRINT_PKT_PROFILE(prPktProfile, "C");
  951. prPrevProfileMsduInfo = prMsduInfo;
  952. fgPrintCurPkt = FALSE;
  953. #endif
  954. }
  955. #if CFG_ENABLE_PER_STA_STATISTICS
  956. {
  957. P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  958. UINT_32 u4DeltaTime;
  959. P_QUE_MGT_T prQM = &prAdapter->rQM;
  960. UINT_8 ucNetIndex;
  961. if (prStaRec) {
  962. ucNetIndex = prStaRec->ucNetTypeIndex;
  963. u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp -
  964. prPktProfile->rHardXmitArrivalTimestamp);
  965. prStaRec->u4TotalTxPktsNumber++;
  966. prStaRec->u4TotalTxPktsTime += u4DeltaTime;
  967. if (u4DeltaTime > prStaRec->u4MaxTxPktsTime)
  968. prStaRec->u4MaxTxPktsTime = u4DeltaTime;
  969. if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD)
  970. prStaRec->u4ThresholdCounter++;
  971. if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) {
  972. DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n",
  973. prStaRec->ucIndex,
  974. prStaRec->u4TotalTxPktsNumber,
  975. prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber,
  976. prStaRec->u4MaxTxPktsTime,
  977. prStaRec->u4ThresholdCounter,
  978. prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]);
  979. prStaRec->u4TotalTxPktsNumber = 0;
  980. prStaRec->u4TotalTxPktsTime = 0;
  981. prStaRec->u4MaxTxPktsTime = 0;
  982. prStaRec->u4ThresholdCounter = 0;
  983. prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0;
  984. }
  985. }
  986. }
  987. #endif
  988. }
  989. prMsduInfo = prNextMsduInfo;
  990. };
  991. #if CFG_PRINT_RTP_PROFILE
  992. /* 4 4. record the lifetime of current round last pkt */
  993. if (prPrevProfileMsduInfo) {
  994. prPktProfile = &prPrevProfileMsduInfo->rPktProfile;
  995. prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn;
  996. prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn;
  997. prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp;
  998. prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp;
  999. prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp;
  1000. prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp;
  1001. prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount;
  1002. prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted;
  1003. prPrevRoundLastPkt->fgIsValid = TRUE;
  1004. }
  1005. #endif
  1006. nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead);
  1007. }
  1008. VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
  1009. {
  1010. P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
  1011. /* Enable packet lifetime profiling */
  1012. prPktProfile->fgIsValid = TRUE;
  1013. /* Packet arrival time at kernel Hard Xmit */
  1014. prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket);
  1015. /* Packet enqueue time */
  1016. prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick();
  1017. }
  1018. #if CFG_PRINT_RTP_PROFILE
  1019. /*
  1020. in:
  1021. data RTP packet pointer
  1022. size RTP size
  1023. return
  1024. 0:audio 1: video, -1:none
  1025. */
  1026. UINT8 checkRtpAV(PUINT_8 data, UINT_32 size)
  1027. {
  1028. PUINT_8 buf = data + 12;
  1029. while (buf + 188 <= data + size) {
  1030. int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF);
  1031. if (pid == 0 || pid == 0x100 || pid == 0x1000)
  1032. buf += 188;
  1033. else if (pid == 0x1100)
  1034. return 0;
  1035. else if (pid == 0x1011)
  1036. return 1;
  1037. }
  1038. return -1;
  1039. }
  1040. VOID
  1041. nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter,
  1042. IN P_MSDU_INFO_T prMsduInfo,
  1043. IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType)
  1044. {
  1045. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  1046. UINT_16 u2EtherTypeLen;
  1047. PUINT_8 aucLookAheadBuf = NULL;
  1048. P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
  1049. /* UINT_8 ucRtpHdrOffset = 28; */
  1050. UINT_8 ucRtpSnOffset = 30;
  1051. /* UINT_32 u4RtpSrcPort = 15550; */
  1052. P_TX_CTRL_T prTxCtrl;
  1053. #if CFG_SUPPORT_WFD
  1054. P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
  1055. P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL;
  1056. BOOLEAN fgEnProfiling = FALSE;
  1057. if (prAdapter->fgIsP2PRegistered) {
  1058. prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
  1059. prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting;
  1060. #if CFG_PRINT_RTP_SN_SKIP
  1061. if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) {
  1062. fgEnProfiling = TRUE;
  1063. } else
  1064. #endif
  1065. if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) ||
  1066. (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) {
  1067. fgEnProfiling = TRUE;
  1068. }
  1069. }
  1070. if (fgEnProfiling == FALSE) {
  1071. /* prPktProfile->fgIsValid = FALSE; */
  1072. return;
  1073. }
  1074. #endif
  1075. prTxCtrl = &prAdapter->rTxCtrl;
  1076. /* prPktProfile->fgIsValid = FALSE; */
  1077. aucLookAheadBuf = prSkb->data;
  1078. u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]);
  1079. if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) {
  1080. PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN];
  1081. UINT_16 u2tmpIpSN = 0;
  1082. UINT_8 ucIpVersion;
  1083. ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
  1084. if (ucIpVersion == IPVERSION) {
  1085. if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) {
  1086. /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset],
  1087. (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */
  1088. if (prPktProfile->fgIsValid == FALSE)
  1089. nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket);
  1090. prPktProfile->fgIsPrinted = FALSE;
  1091. prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX];
  1092. /* RTP SN */
  1093. prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1];
  1094. /* IP SN */
  1095. prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 |
  1096. pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1];
  1097. u2tmpIpSN = prPktProfile->u2IpSn;
  1098. if (prWfdDbgSettings->ucWfdDebugMode == 1) {
  1099. if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0)
  1100. DBGLOG(TX, TRACE,
  1101. "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn,
  1102. prPktProfile->u2IpSn, jiffies);
  1103. }
  1104. /* } */
  1105. }
  1106. }
  1107. }
  1108. }
  1109. #endif
  1110. #if CFG_ENABLE_PER_STA_STATISTICS
  1111. VOID
  1112. nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter,
  1113. IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam)
  1114. {
  1115. switch (ucPriorityParam) {
  1116. /* BK */
  1117. /* case 1: */
  1118. /* case 2: */
  1119. /* BE */
  1120. /* case 0: */
  1121. /* case 3: */
  1122. /* VI */
  1123. case 4:
  1124. case 5:
  1125. /* VO */
  1126. case 6:
  1127. case 7:
  1128. nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket);
  1129. break;
  1130. default:
  1131. break;
  1132. }
  1133. }
  1134. #endif
  1135. VOID
  1136. nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter,
  1137. IN P_MSDU_INFO_T prMsduInfo,
  1138. IN P_NATIVE_PACKET prPacket,
  1139. IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType)
  1140. {
  1141. P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile;
  1142. /* Reset packet profile */
  1143. prPktProfile->fgIsValid = FALSE;
  1144. #if CFG_ENABLE_PER_STA_STATISTICS
  1145. nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam);
  1146. #endif
  1147. #if CFG_PRINT_RTP_PROFILE
  1148. nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType);
  1149. #endif
  1150. }
  1151. #endif
  1152. /*----------------------------------------------------------------------------*/
  1153. /*!
  1154. * @brief In this function, we'll write frame(PACKET_INFO_T) into HIF.
  1155. *
  1156. * @param prAdapter Pointer to the Adapter structure.
  1157. * @param ucPortIdx Port Number
  1158. * @param prQue a link list of P_MSDU_INFO_T
  1159. *
  1160. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1161. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1162. */
  1163. /*----------------------------------------------------------------------------*/
  1164. WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue)
  1165. {
  1166. P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
  1167. HIF_TX_HEADER_T rHwTxHeader;
  1168. P_NATIVE_PACKET prNativePacket;
  1169. UINT_16 u2OverallBufferLength;
  1170. UINT_8 ucEtherTypeOffsetInWord;
  1171. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  1172. UINT_32 u4TxHdrSize;
  1173. UINT_32 u4ValidBufSize;
  1174. UINT_32 u4TotalLength;
  1175. P_TX_CTRL_T prTxCtrl;
  1176. QUE_T rFreeQueue;
  1177. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1178. UINT_8 ucChksumFlag;
  1179. #endif
  1180. ASSERT(prAdapter);
  1181. ASSERT(ucPortIdx < 2);
  1182. ASSERT(prQue);
  1183. prTxCtrl = &prAdapter->rTxCtrl;
  1184. u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize;
  1185. #if CFG_HIF_STATISTICS
  1186. prTxCtrl->u4TotalTxAccessNum++;
  1187. prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem;
  1188. #endif
  1189. QUEUE_INITIALIZE(&rFreeQueue);
  1190. if (prQue->u4NumElem > 0) {
  1191. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue);
  1192. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  1193. u4TotalLength = 0;
  1194. while (prMsduInfo) {
  1195. #if (CFG_SUPPORT_TDLS_DBG == 1)
  1196. {
  1197. struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket;
  1198. UINT8 *pkt = prSkb->data;
  1199. UINT16 u2Identifier;
  1200. if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) {
  1201. /* ip */
  1202. u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19));
  1203. DBGLOG(TX, TRACE, "<hif> %d\n", u2Identifier);
  1204. }
  1205. }
  1206. #endif
  1207. #if (CFG_SUPPORT_MET_PROFILING == 1)
  1208. kalMetProfilingFinish(prAdapter, prMsduInfo);
  1209. #endif
  1210. kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
  1211. prNativePacket = prMsduInfo->prPacket;
  1212. ASSERT(prNativePacket);
  1213. u4TxHdrSize = TX_HDR_SIZE;
  1214. u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) &
  1215. (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1216. /* init TX header */
  1217. rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength;
  1218. rHwTxHeader.u2TxByteCount_UserPriority |=
  1219. ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET);
  1220. if (prMsduInfo->fgIs802_11) {
  1221. ucEtherTypeOffsetInWord =
  1222. (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
  1223. } else {
  1224. ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1;
  1225. }
  1226. rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
  1227. rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET;
  1228. rHwTxHeader.ucResource_PktType_CSflags |=
  1229. (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) &
  1230. (HIF_TX_HDR_PACKET_TYPE_MASK));
  1231. #if CFG_TCP_IP_CHKSUM_OFFLOAD
  1232. if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
  1233. if (prAdapter->u4CSUMFlags &
  1234. (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) {
  1235. kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag);
  1236. if (ucChksumFlag & TX_CS_IP_GEN)
  1237. rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM;
  1238. if (ucChksumFlag & TX_CS_TCP_UDP_GEN)
  1239. rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM;
  1240. }
  1241. }
  1242. #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
  1243. rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH;
  1244. rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex;
  1245. rHwTxHeader.ucForwardingType_SessionID_Reserved =
  1246. (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) <<
  1247. HIF_TX_HDR_PS_SESSION_ID_OFFSET)
  1248. | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0);
  1249. rHwTxHeader.ucWlanHeaderLength =
  1250. (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
  1251. rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK)
  1252. | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) &
  1253. HIF_TX_HDR_NETWORK_TYPE_MASK)
  1254. | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) &
  1255. HIF_TX_HDR_FLAG_1X_FRAME_MASK)
  1256. | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) &
  1257. HIF_TX_HDR_FLAG_802_11_FORMAT_MASK);
  1258. rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN;
  1259. if (prMsduInfo->pfTxDoneHandler) {
  1260. rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum;
  1261. rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK;
  1262. } else {
  1263. rHwTxHeader.ucPacketSeqNo = 0;
  1264. rHwTxHeader.ucAck_BIP_BasicRate = 0;
  1265. }
  1266. if (prMsduInfo->fgNeedTxDoneStatus == TRUE)
  1267. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS;
  1268. if (prMsduInfo->fgIsBIP)
  1269. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP;
  1270. if (prMsduInfo->fgIsBasicRate)
  1271. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE;
  1272. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  1273. if (prMsduInfo->rPktProfile.fgIsValid)
  1274. prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick();
  1275. #endif
  1276. /* record the queue time in driver */
  1277. STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader);
  1278. #if CFG_SDIO_TX_AGG
  1279. /* attach to coalescing buffer */
  1280. kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize);
  1281. u4TotalLength += u4TxHdrSize;
  1282. if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING)
  1283. kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength);
  1284. else if (prMsduInfo->eSrc == TX_PACKET_MGMT)
  1285. kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength);
  1286. else
  1287. ASSERT(0);
  1288. u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength);
  1289. #else
  1290. kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize);
  1291. /* Copy Frame Body */
  1292. if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING)
  1293. kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize);
  1294. else if (prMsduInfo->eSrc == TX_PACKET_MGMT)
  1295. kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength);
  1296. else
  1297. ASSERT(0);
  1298. ASSERT(u2OverallBufferLength <= u4ValidBufSize);
  1299. HAL_WRITE_TX_PORT(prAdapter,
  1300. ucPortIdx,
  1301. (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
  1302. /* send immediately */
  1303. #endif
  1304. prNextMsduInfo = (P_MSDU_INFO_T)
  1305. QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry);
  1306. if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  1307. GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  1308. if (prMsduInfo->pfTxDoneHandler == NULL) {
  1309. cnmMgtPktFree(prAdapter, prMsduInfo);
  1310. } else {
  1311. KAL_SPIN_LOCK_DECLARATION();
  1312. DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum);
  1313. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1314. QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
  1315. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1316. }
  1317. } else {
  1318. /* only free MSDU when it is not a MGMT frame */
  1319. QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo);
  1320. if (prMsduInfo->eSrc == TX_PACKET_OS)
  1321. kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS);
  1322. else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING)
  1323. GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
  1324. }
  1325. prMsduInfo = prNextMsduInfo;
  1326. }
  1327. #if CFG_SDIO_TX_AGG
  1328. ASSERT(u4TotalLength <= u4ValidBufSize);
  1329. #if CFG_DBG_GPIO_PINS
  1330. {
  1331. /* Start port write */
  1332. mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW);
  1333. kalUdelay(1);
  1334. mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH);
  1335. }
  1336. #endif
  1337. /* send coalescing buffer */
  1338. HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize);
  1339. #endif
  1340. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  1341. #if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS
  1342. do {
  1343. P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
  1344. prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
  1345. if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) {
  1346. /* Enable profiling */
  1347. nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
  1348. } else {
  1349. /* Skip profiling */
  1350. nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
  1351. }
  1352. } while (FALSE);
  1353. #else
  1354. nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
  1355. #endif
  1356. #else
  1357. /* return */
  1358. nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
  1359. #endif
  1360. }
  1361. return WLAN_STATUS_SUCCESS;
  1362. }
  1363. /*----------------------------------------------------------------------------*/
  1364. /*!
  1365. * \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
  1366. *
  1367. * @param prAdapter Pointer to the Adapter structure.
  1368. * @param prPacketInfo Pointer of CMD_INFO_T
  1369. * @param ucTC Specify the resource of TC
  1370. *
  1371. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1372. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1373. */
  1374. /*----------------------------------------------------------------------------*/
  1375. WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
  1376. {
  1377. P_WIFI_CMD_T prWifiCmd;
  1378. UINT_16 u2OverallBufferLength;
  1379. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  1380. UINT_8 ucPortIdx;
  1381. HIF_TX_HEADER_T rHwTxHeader;
  1382. P_NATIVE_PACKET prNativePacket;
  1383. UINT_8 ucEtherTypeOffsetInWord;
  1384. P_MSDU_INFO_T prMsduInfo;
  1385. P_TX_CTRL_T prTxCtrl;
  1386. KAL_SPIN_LOCK_DECLARATION();
  1387. ASSERT(prAdapter);
  1388. ASSERT(prCmdInfo);
  1389. prTxCtrl = &prAdapter->rTxCtrl;
  1390. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  1391. /* <1> Assign Data Port */
  1392. if (ucTC != TC4_INDEX) {
  1393. ucPortIdx = 0;
  1394. } else {
  1395. /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */
  1396. ucPortIdx = 1;
  1397. }
  1398. wlanTraceTxCmd(prAdapter, prCmdInfo);
  1399. if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
  1400. /* <2> Compose HIF_TX_HEADER */
  1401. kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
  1402. prNativePacket = prCmdInfo->prPacket;
  1403. ASSERT(prNativePacket);
  1404. u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE)
  1405. & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1406. rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE)
  1407. & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1408. ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1;
  1409. rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
  1410. rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET);
  1411. rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex;
  1412. rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK;
  1413. rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
  1414. rHwTxHeader.ucPktFormtId_Flags =
  1415. (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) &
  1416. HIF_TX_HDR_NETWORK_TYPE_MASK)
  1417. | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK);
  1418. rHwTxHeader.u2SeqNo = 0;
  1419. rHwTxHeader.ucPacketSeqNo = 0;
  1420. rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS;
  1421. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */;
  1422. /* <2.3> Copy HIF TX HEADER */
  1423. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE);
  1424. /* <3> Copy Frame Body Copy */
  1425. kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE);
  1426. } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
  1427. prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket;
  1428. ASSERT(prMsduInfo->fgIs802_11 == TRUE);
  1429. ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
  1430. /* <2> Compose HIF_TX_HEADER */
  1431. kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader));
  1432. u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) &
  1433. (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1434. rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength;
  1435. rHwTxHeader.u2TxByteCount_UserPriority |=
  1436. ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET);
  1437. ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
  1438. rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK;
  1439. rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET;
  1440. rHwTxHeader.ucResource_PktType_CSflags |=
  1441. (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) &
  1442. (HIF_TX_HDR_PACKET_TYPE_MASK));
  1443. rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH;
  1444. rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex;
  1445. rHwTxHeader.ucForwardingType_SessionID_Reserved =
  1446. (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET)
  1447. | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0);
  1448. rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK);
  1449. rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK)
  1450. | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK)
  1451. | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK)
  1452. | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) &
  1453. HIF_TX_HDR_FLAG_802_11_FORMAT_MASK);
  1454. rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN;
  1455. if (prMsduInfo->pfTxDoneHandler) {
  1456. rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum;
  1457. rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK;
  1458. } else {
  1459. rHwTxHeader.ucPacketSeqNo = 0;
  1460. rHwTxHeader.ucAck_BIP_BasicRate = 0;
  1461. }
  1462. if (prMsduInfo->fgIsBIP)
  1463. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP;
  1464. if (prMsduInfo->fgIsBasicRate)
  1465. rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE;
  1466. /* <2.3> Copy HIF TX HEADER */
  1467. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE);
  1468. /* <3> Copy Frame Body */
  1469. kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength);
  1470. /* <4> Management Frame Post-Processing */
  1471. GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  1472. if (prMsduInfo->pfTxDoneHandler == NULL) {
  1473. cnmMgtPktFree(prAdapter, prMsduInfo);
  1474. } else {
  1475. DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum);
  1476. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1477. QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
  1478. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1479. }
  1480. } else {
  1481. prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer;
  1482. /* <2> Compose the Header of Transmit Data Structure for CMD Packet */
  1483. u2OverallBufferLength =
  1484. TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1485. prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength;
  1486. prWifiCmd->ucEtherTypeOffset = 0;
  1487. prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET)
  1488. | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK));
  1489. /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
  1490. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
  1491. ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
  1492. if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) ||
  1493. (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) ||
  1494. (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2))
  1495. DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID);
  1496. }
  1497. /* <4> Write frame to data port */
  1498. HAL_WRITE_TX_PORT(prAdapter,
  1499. ucPortIdx,
  1500. (UINT_32) u2OverallBufferLength,
  1501. (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
  1502. return WLAN_STATUS_SUCCESS;
  1503. } /* end of nicTxCmd() */
  1504. /*----------------------------------------------------------------------------*/
  1505. /*!
  1506. * @brief This function will clean up all the pending frames in internal SW Queues
  1507. * by return the pending TX packet to the system.
  1508. *
  1509. * @param prAdapter Pointer to the Adapter structure.
  1510. *
  1511. * @return (none)
  1512. */
  1513. /*----------------------------------------------------------------------------*/
  1514. VOID nicTxRelease(IN P_ADAPTER_T prAdapter)
  1515. {
  1516. P_TX_CTRL_T prTxCtrl;
  1517. P_MSDU_INFO_T prMsduInfo;
  1518. KAL_SPIN_LOCK_DECLARATION();
  1519. ASSERT(prAdapter);
  1520. prTxCtrl = &prAdapter->rTxCtrl;
  1521. nicTxFlush(prAdapter);
  1522. /* free MSDU_INFO_T from rTxMgmtMsduInfoList */
  1523. do {
  1524. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1525. QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T);
  1526. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
  1527. if (prMsduInfo) {
  1528. /* the packet must be mgmt frame with tx done callback */
  1529. ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
  1530. /* invoke done handler */
  1531. prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT);
  1532. cnmMgtPktFree(prAdapter, prMsduInfo);
  1533. } else {
  1534. break;
  1535. }
  1536. } while (TRUE);
  1537. } /* end of nicTxRelease() */
  1538. /*----------------------------------------------------------------------------*/
  1539. /*!
  1540. * @brief Process the TX Done interrupt and pull in more pending frames in SW
  1541. * Queues for transmission.
  1542. *
  1543. * @param prAdapter Pointer to the Adapter structure.
  1544. *
  1545. * @return (none)
  1546. */
  1547. /*----------------------------------------------------------------------------*/
  1548. VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter)
  1549. {
  1550. P_TX_CTRL_T prTxCtrl;
  1551. #if CFG_SDIO_INTR_ENHANCE
  1552. P_SDIO_CTRL_T prSDIOCtrl;
  1553. #else
  1554. UINT_32 au4TxCount[2];
  1555. #endif /* CFG_SDIO_INTR_ENHANCE */
  1556. ASSERT(prAdapter);
  1557. prTxCtrl = &prAdapter->rTxCtrl;
  1558. ASSERT(prTxCtrl);
  1559. /* Get the TX STATUS */
  1560. #if CFG_SDIO_INTR_ENHANCE
  1561. prSDIOCtrl = prAdapter->prSDIOCtrl;
  1562. #if DBG
  1563. /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */
  1564. #endif
  1565. nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo);
  1566. kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo));
  1567. #else
  1568. HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]);
  1569. HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]);
  1570. DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]);
  1571. nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount);
  1572. #endif /* CFG_SDIO_INTR_ENHANCE */
  1573. nicTxAdjustTcq(prAdapter);
  1574. /* Indicate Service Thread */
  1575. if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
  1576. kalSetEvent(prAdapter->prGlueInfo);
  1577. } /* end of nicProcessTxInterrupt() */
  1578. /*----------------------------------------------------------------------------*/
  1579. /*!
  1580. * @brief this function frees packet of P_MSDU_INFO_T linked-list
  1581. *
  1582. * @param prAdapter Pointer to the Adapter structure.
  1583. * @param prMsduInfoList a link list of P_MSDU_INFO_T
  1584. *
  1585. * @return (none)
  1586. */
  1587. /*----------------------------------------------------------------------------*/
  1588. VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  1589. {
  1590. P_NATIVE_PACKET prNativePacket;
  1591. P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead;
  1592. P_TX_CTRL_T prTxCtrl;
  1593. ASSERT(prAdapter);
  1594. ASSERT(prMsduInfoListHead);
  1595. prTxCtrl = &prAdapter->rTxCtrl;
  1596. while (prMsduInfo) {
  1597. prNativePacket = prMsduInfo->prPacket;
  1598. if (prMsduInfo->eSrc == TX_PACKET_OS) {
  1599. kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE);
  1600. } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  1601. P_MSDU_INFO_T prTempMsduInfo = prMsduInfo;
  1602. if (prMsduInfo->pfTxDoneHandler)
  1603. prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
  1604. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1605. cnmMgtPktFree(prAdapter, prTempMsduInfo);
  1606. continue;
  1607. } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
  1608. GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
  1609. }
  1610. prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1611. }
  1612. }
  1613. /*----------------------------------------------------------------------------*/
  1614. /*!
  1615. * @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList
  1616. *
  1617. * @param prAdapter Pointer to the Adapter structure.
  1618. * @param prMsduInfoList a link list of P_MSDU_INFO_T
  1619. *
  1620. * @return (none)
  1621. */
  1622. /*----------------------------------------------------------------------------*/
  1623. VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
  1624. {
  1625. P_TX_CTRL_T prTxCtrl;
  1626. P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;
  1627. KAL_SPIN_LOCK_DECLARATION();
  1628. ASSERT(prAdapter);
  1629. prTxCtrl = &prAdapter->rTxCtrl;
  1630. ASSERT(prTxCtrl);
  1631. while (prMsduInfo) {
  1632. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1633. switch (prMsduInfo->eSrc) {
  1634. case TX_PACKET_FORWARDING:
  1635. wlanReturnPacket(prAdapter, prMsduInfo->prPacket);
  1636. break;
  1637. case TX_PACKET_OS:
  1638. case TX_PACKET_OS_OID:
  1639. case TX_PACKET_MGMT:
  1640. default:
  1641. break;
  1642. }
  1643. /* Reset MSDU_INFO fields */
  1644. kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));
  1645. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  1646. QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
  1647. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
  1648. prMsduInfo = prNextMsduInfo;
  1649. };
  1650. }
  1651. /*----------------------------------------------------------------------------*/
  1652. /*!
  1653. * @brief this function fills packet information to P_MSDU_INFO_T
  1654. *
  1655. * @param prAdapter Pointer to the Adapter structure.
  1656. * @param prMsduInfo P_MSDU_INFO_T
  1657. * @param prPacket P_NATIVE_PACKET
  1658. *
  1659. * @retval TRUE Success to extract information
  1660. * @retval FALSE Fail to extract correct information
  1661. */
  1662. /*----------------------------------------------------------------------------*/
  1663. BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
  1664. {
  1665. P_GLUE_INFO_T prGlueInfo;
  1666. UINT_8 ucPriorityParam;
  1667. UINT_8 ucMacHeaderLen;
  1668. UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN];
  1669. BOOLEAN fgIs1x = FALSE;
  1670. BOOLEAN fgIsPAL = FALSE;
  1671. UINT_32 u4PacketLen;
  1672. ULONG u4SysTime;
  1673. UINT_8 ucNetworkType;
  1674. struct sk_buff *prSkb = (struct sk_buff *)prPacket;
  1675. ASSERT(prAdapter);
  1676. prGlueInfo = prAdapter->prGlueInfo;
  1677. ASSERT(prGlueInfo);
  1678. if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo,
  1679. prPacket,
  1680. &ucPriorityParam,
  1681. &u4PacketLen,
  1682. aucEthDestAddr,
  1683. &fgIs1x, &fgIsPAL, &ucNetworkType,
  1684. NULL) == FALSE) {
  1685. return FALSE;
  1686. }
  1687. #if CFG_ENABLE_PKT_LIFETIME_PROFILE
  1688. nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType);
  1689. #endif
  1690. /* Save the value of Priority Parameter */
  1691. GLUE_SET_PKT_TID(prPacket, ucPriorityParam);
  1692. if (fgIs1x)
  1693. GLUE_SET_PKT_FLAG_1X(prPacket);
  1694. if (fgIsPAL)
  1695. GLUE_SET_PKT_FLAG_PAL(prPacket);
  1696. ucMacHeaderLen = ETH_HLEN;
  1697. /* Save the value of Header Length */
  1698. GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen);
  1699. /* Save the value of Frame Length */
  1700. GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen);
  1701. /* Save the value of Arrival Time */
  1702. u4SysTime = (OS_SYSTIME) kalGetTimeTick();
  1703. GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime);
  1704. prMsduInfo->prPacket = prPacket;
  1705. prMsduInfo->fgIs802_1x = fgIs1x;
  1706. prMsduInfo->fgIs802_11 = FALSE;
  1707. prMsduInfo->ucNetworkType = ucNetworkType;
  1708. prMsduInfo->ucUserPriority = ucPriorityParam;
  1709. prMsduInfo->ucMacHeaderLength = ucMacHeaderLen;
  1710. prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen;
  1711. COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr);
  1712. if (prSkb->len > ETH_HLEN)
  1713. STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo);
  1714. return TRUE;
  1715. }
  1716. /*----------------------------------------------------------------------------*/
  1717. /*!
  1718. * @brief this function update TCQ values by passing current status to txAdjustTcQuotas
  1719. *
  1720. * @param prAdapter Pointer to the Adapter structure.
  1721. *
  1722. * @retval WLAN_STATUS_SUCCESS Updated successfully
  1723. */
  1724. /*----------------------------------------------------------------------------*/
  1725. WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter)
  1726. {
  1727. UINT_32 u4Num;
  1728. TX_TCQ_ADJUST_T rTcqAdjust;
  1729. P_TX_CTRL_T prTxCtrl;
  1730. KAL_SPIN_LOCK_DECLARATION();
  1731. ASSERT(prAdapter);
  1732. prTxCtrl = &prAdapter->rTxCtrl;
  1733. ASSERT(prTxCtrl);
  1734. qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc);
  1735. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1736. for (u4Num = 0; u4Num < TC_NUM; u4Num++) {
  1737. prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num];
  1738. prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num];
  1739. }
  1740. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
  1741. return WLAN_STATUS_SUCCESS;
  1742. }
  1743. /*----------------------------------------------------------------------------*/
  1744. /*!
  1745. * @brief this function flushes all packets queued in STA/AC queue
  1746. *
  1747. * @param prAdapter Pointer to the Adapter structure.
  1748. *
  1749. * @retval WLAN_STATUS_SUCCESS Flushed successfully
  1750. */
  1751. /*----------------------------------------------------------------------------*/
  1752. WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter)
  1753. {
  1754. P_MSDU_INFO_T prMsduInfo;
  1755. KAL_SPIN_LOCK_DECLARATION();
  1756. ASSERT(prAdapter);
  1757. /* ask Per STA/AC queue to be fllushed and return all queued packets */
  1758. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  1759. prMsduInfo = qmFlushTxQueues(prAdapter);
  1760. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  1761. if (prMsduInfo != NULL) {
  1762. nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
  1763. nicTxReturnMsduInfo(prAdapter, prMsduInfo);
  1764. }
  1765. return WLAN_STATUS_SUCCESS;
  1766. }
  1767. #if CFG_ENABLE_FW_DOWNLOAD
  1768. /*----------------------------------------------------------------------------*/
  1769. /*!
  1770. * \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
  1771. * However this function is used for INIT_CMD.
  1772. *
  1773. * In order to avoid further maintenance issues, these 2 functions are separated
  1774. *
  1775. * @param prAdapter Pointer to the Adapter structure.
  1776. * @param prPacketInfo Pointer of CMD_INFO_T
  1777. * @param ucTC Specify the resource of TC
  1778. *
  1779. * @retval WLAN_STATUS_SUCCESS Bus access ok.
  1780. * @retval WLAN_STATUS_FAILURE Bus access fail.
  1781. */
  1782. /*----------------------------------------------------------------------------*/
  1783. WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
  1784. {
  1785. P_INIT_HIF_TX_HEADER_T prInitTxHeader;
  1786. UINT_16 u2OverallBufferLength;
  1787. PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */
  1788. UINT_32 ucPortIdx;
  1789. P_TX_CTRL_T prTxCtrl;
  1790. ASSERT(prAdapter);
  1791. ASSERT(prCmdInfo);
  1792. ASSERT(ucTC == TC0_INDEX);
  1793. prTxCtrl = &prAdapter->rTxCtrl;
  1794. pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
  1795. prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer;
  1796. /* <1> Compose the Header of Transmit Data Structure for CMD Packet */
  1797. u2OverallBufferLength =
  1798. TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
  1799. prInitTxHeader->u2TxByteCount = u2OverallBufferLength;
  1800. prInitTxHeader->ucEtherTypeOffset = 0;
  1801. prInitTxHeader->ucCSflags = 0;
  1802. /* <2> Assign Data Port */
  1803. if (ucTC != TC4_INDEX) {
  1804. ucPortIdx = 0;
  1805. } else { /* Broadcast/multicast data packets */
  1806. ucPortIdx = 1;
  1807. }
  1808. /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
  1809. kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);
  1810. ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);
  1811. /* <4> Write frame to data port */
  1812. HAL_WRITE_TX_PORT(prAdapter,
  1813. ucPortIdx,
  1814. (UINT_32) u2OverallBufferLength,
  1815. (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);
  1816. return WLAN_STATUS_SUCCESS;
  1817. }
  1818. /*----------------------------------------------------------------------------*/
  1819. /*!
  1820. * \brief In this function, we'll reset TX resource counter to initial value used
  1821. * in F/W download state
  1822. *
  1823. * @param prAdapter Pointer to the Adapter structure.
  1824. *
  1825. * @retval WLAN_STATUS_SUCCESS Reset is done successfully.
  1826. */
  1827. /*----------------------------------------------------------------------------*/
  1828. WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter)
  1829. {
  1830. P_TX_CTRL_T prTxCtrl;
  1831. DEBUGFUNC("nicTxInitResetResource");
  1832. ASSERT(prAdapter);
  1833. prTxCtrl = &prAdapter->rTxCtrl;
  1834. prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0;
  1835. prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0;
  1836. prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1;
  1837. prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1;
  1838. prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2;
  1839. prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2;
  1840. prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3;
  1841. prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3;
  1842. prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4;
  1843. prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4;
  1844. prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5;
  1845. prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5;
  1846. return WLAN_STATUS_SUCCESS;
  1847. }
  1848. #endif
  1849. /*----------------------------------------------------------------------------*/
  1850. /*!
  1851. * \brief this function enqueues MSDU_INFO_T into queue management,
  1852. * or command queue
  1853. *
  1854. * @param prAdapter Pointer to the Adapter structure.
  1855. * prMsduInfo Pointer to MSDU
  1856. *
  1857. * @retval WLAN_STATUS_SUCCESS Reset is done successfully.
  1858. */
  1859. /*----------------------------------------------------------------------------*/
  1860. WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
  1861. {
  1862. P_TX_CTRL_T prTxCtrl;
  1863. P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead;
  1864. QUE_T qDataPort0, qDataPort1;
  1865. P_CMD_INFO_T prCmdInfo;
  1866. WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
  1867. KAL_SPIN_LOCK_DECLARATION();
  1868. ASSERT(prAdapter);
  1869. ASSERT(prMsduInfo);
  1870. prTxCtrl = &prAdapter->rTxCtrl;
  1871. ASSERT(prTxCtrl);
  1872. QUEUE_INITIALIZE(&qDataPort0);
  1873. QUEUE_INITIALIZE(&qDataPort1);
  1874. /* check how many management frame are being queued */
  1875. while (prMsduInfo) {
  1876. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
  1877. QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
  1878. if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
  1879. /* MMPDU: force stick to TC4 */
  1880. prMsduInfo->ucTC = TC4_INDEX;
  1881. QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
  1882. } else {
  1883. QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
  1884. }
  1885. prMsduInfo = prNextMsduInfo;
  1886. }
  1887. if (qDataPort0.u4NumElem) {
  1888. /* send to QM: queue the packet to different TX queue by policy */
  1889. KAL_SPIN_LOCK_DECLARATION();
  1890. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  1891. prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0));
  1892. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
  1893. /* post-process for "dropped" packets */
  1894. if (prRetMsduInfo != NULL) { /* unable to enqueue */
  1895. nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo);
  1896. nicTxReturnMsduInfo(prAdapter, prRetMsduInfo);
  1897. }
  1898. }
  1899. if (qDataPort1.u4NumElem) {
  1900. prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1);
  1901. if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) {
  1902. /* not enough descriptors for sending */
  1903. u4Status = WLAN_STATUS_FAILURE;
  1904. /* free all MSDUs */
  1905. while (prMsduInfoHead) {
  1906. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
  1907. if (prMsduInfoHead->pfTxDoneHandler != NULL) {
  1908. prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead,
  1909. TX_RESULT_DROPPED_IN_DRIVER);
  1910. }
  1911. cnmMgtPktFree(prAdapter, prMsduInfoHead);
  1912. prMsduInfoHead = prNextMsduInfo;
  1913. }
  1914. } else {
  1915. /* send to command queue */
  1916. while (prMsduInfoHead) {
  1917. prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);
  1918. KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
  1919. QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
  1920. KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
  1921. if (prCmdInfo) {
  1922. GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);
  1923. kalMemZero(prCmdInfo, sizeof(CMD_INFO_T));
  1924. prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME;
  1925. prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength;
  1926. prCmdInfo->pucInfoBuffer = NULL;
  1927. prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead;
  1928. prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex;
  1929. prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType;
  1930. prCmdInfo->pfCmdDoneHandler = NULL;
  1931. prCmdInfo->pfCmdTimeoutHandler = NULL;
  1932. prCmdInfo->fgIsOid = FALSE;
  1933. prCmdInfo->fgSetQuery = TRUE;
  1934. prCmdInfo->fgNeedResp = FALSE;
  1935. kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
  1936. } else {
  1937. /* Cmd free count is larger than expected, but allocation fail. */
  1938. ASSERT(0);
  1939. u4Status = WLAN_STATUS_FAILURE;
  1940. cnmMgtPktFree(prAdapter, prMsduInfoHead);
  1941. }
  1942. prMsduInfoHead = prNextMsduInfo;
  1943. }
  1944. }
  1945. }
  1946. /* indicate service thread for sending */
  1947. if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0)
  1948. kalSetEvent(prAdapter->prGlueInfo);
  1949. return u4Status;
  1950. }
  1951. /*----------------------------------------------------------------------------*/
  1952. /*!
  1953. * \brief this function returns available count in command queue
  1954. *
  1955. * @param prAdapter Pointer to the Adapter structure.
  1956. *
  1957. * @retval
  1958. */
  1959. /*----------------------------------------------------------------------------*/
  1960. UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter)
  1961. {
  1962. ASSERT(prAdapter);
  1963. return prAdapter->rFreeCmdList.u4NumElem;
  1964. }