hal_halmac.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2015 - 2016 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. #define _HAL_HALMAC_C_
  21. #include <drv_types.h> /* PADAPTER, struct dvobj_priv, SDIO_ERR_VAL8 and etc. */
  22. #include <hal_data.h> /* efuse, PHAL_DATA_TYPE and etc. */
  23. #include "halmac/halmac_api.h" /* HALMAC_FW_SIZE_MAX_88XX and etc. */
  24. #include "hal_halmac.h" /* dvobj_to_halmac() and ect. */
  25. #define DEFAULT_INDICATOR_TIMELMT 1000 /* ms */
  26. #define FIRMWARE_MAX_SIZE HALMAC_FW_SIZE_MAX_88XX
  27. #define MSG_PREFIX "[HALMAC]"
  28. /*
  29. * Driver API for HALMAC operations
  30. */
  31. #ifdef CONFIG_SDIO_HCI
  32. #include <rtw_sdio.h>
  33. static u8 _halmac_mac_reg_page0_chk(const char *func, struct dvobj_priv *dvobj, u32 offset)
  34. {
  35. #if defined(CONFIG_IO_CHECK_IN_ANA_LOW_CLK) && defined(CONFIG_LPS_LCLK)
  36. struct pwrctrl_priv *pwrpriv = &dvobj->pwrctl_priv;
  37. u32 mac_reg_offset = 0;
  38. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
  39. return _TRUE;
  40. if (pwrpriv->lps_level == LPS_NORMAL)
  41. return _TRUE;
  42. if (pwrpriv->rpwm >= PS_STATE_S2)
  43. return _TRUE;
  44. if (offset & (WLAN_IOREG_DEVICE_ID << 13)) { /*WLAN_IOREG_OFFSET*/
  45. mac_reg_offset = offset & HALMAC_WLAN_MAC_REG_MSK;
  46. if (mac_reg_offset < 0x100) {
  47. RTW_ERR(FUNC_ADPT_FMT
  48. "access MAC REG -0x%04x in PS-mode:0x%02x (rpwm:0x%02x, lps_level:0x%02x)\n",
  49. FUNC_ADPT_ARG(dvobj_get_primary_adapter(dvobj)), mac_reg_offset,
  50. pwrpriv->pwr_mode, pwrpriv->rpwm, pwrpriv->lps_level);
  51. rtw_warn_on(1);
  52. return _FALSE;
  53. }
  54. }
  55. #endif
  56. return _TRUE;
  57. }
  58. static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
  59. {
  60. struct dvobj_priv *d;
  61. u8 val;
  62. u8 ret;
  63. d = (struct dvobj_priv *)p;
  64. _halmac_mac_reg_page0_chk(__func__, d, offset);
  65. ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
  66. if (_FAIL == ret) {
  67. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  68. return SDIO_ERR_VAL8;
  69. }
  70. return val;
  71. }
  72. static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
  73. {
  74. struct dvobj_priv *d;
  75. u8 ret;
  76. d = (struct dvobj_priv *)p;
  77. _halmac_mac_reg_page0_chk(__func__, d, offset);
  78. ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
  79. if (_FAIL == ret)
  80. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  81. }
  82. static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
  83. {
  84. struct dvobj_priv *d;
  85. u8 *pbuf;
  86. u8 val;
  87. int err;
  88. d = (struct dvobj_priv *)p;
  89. val = SDIO_ERR_VAL8;
  90. _halmac_mac_reg_page0_chk(__func__, d, offset);
  91. pbuf = rtw_zmalloc(1);
  92. if (!pbuf)
  93. return val;
  94. err = d->intf_ops->read(d, offset, pbuf, 1, 0);
  95. if (err) {
  96. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  97. goto exit;
  98. }
  99. val = *pbuf;
  100. exit:
  101. rtw_mfree(pbuf, 1);
  102. return val;
  103. }
  104. static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
  105. {
  106. struct dvobj_priv *d;
  107. u8 *pbuf;
  108. u16 val;
  109. int err;
  110. d = (struct dvobj_priv *)p;
  111. val = SDIO_ERR_VAL16;
  112. _halmac_mac_reg_page0_chk(__func__, d, offset);
  113. pbuf = rtw_zmalloc(2);
  114. if (!pbuf)
  115. return val;
  116. err = d->intf_ops->read(d, offset, pbuf, 2, 0);
  117. if (err) {
  118. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  119. goto exit;
  120. }
  121. val = le16_to_cpu(*(u16 *)pbuf);
  122. exit:
  123. rtw_mfree(pbuf, 2);
  124. return val;
  125. }
  126. static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
  127. {
  128. struct dvobj_priv *d;
  129. u8 *pbuf;
  130. u32 val;
  131. int err;
  132. d = (struct dvobj_priv *)p;
  133. val = SDIO_ERR_VAL32;
  134. _halmac_mac_reg_page0_chk(__func__, d, offset);
  135. pbuf = rtw_zmalloc(4);
  136. if (!pbuf)
  137. return val;
  138. err = d->intf_ops->read(d, offset, pbuf, 4, 0);
  139. if (err) {
  140. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  141. goto exit;
  142. }
  143. val = le32_to_cpu(*(u32 *)pbuf);
  144. exit:
  145. rtw_mfree(pbuf, 4);
  146. return val;
  147. }
  148. static u8 _halmac_sdio_reg_read_n(void *p, u32 offset, u32 size, u8 *data)
  149. {
  150. struct dvobj_priv *d = (struct dvobj_priv *)p;
  151. PSDIO_DATA psdio = &d->intf_data;
  152. u8 *pbuf;
  153. int err;
  154. u8 rst = _FALSE;
  155. u32 sdio_read_size;
  156. sdio_read_size = RND4(size);
  157. if (sdio_read_size > psdio->block_transfer_len)
  158. sdio_read_size = _RND(sdio_read_size, psdio->block_transfer_len);
  159. pbuf = rtw_zmalloc(sdio_read_size);
  160. if ((!pbuf) || (!data))
  161. return rst;
  162. err = d->intf_ops->read(d, offset, pbuf, sdio_read_size, 0);
  163. if (err) {
  164. RTW_ERR("%s: [ERROR] I/O FAIL!\n", __func__);
  165. goto exit;
  166. }
  167. _rtw_memcpy(data, pbuf, size);
  168. rst = _TRUE;
  169. exit:
  170. rtw_mfree(pbuf, sdio_read_size);
  171. return rst;
  172. }
  173. static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
  174. {
  175. struct dvobj_priv *d;
  176. u8 *pbuf;
  177. int err;
  178. d = (struct dvobj_priv *)p;
  179. _halmac_mac_reg_page0_chk(__func__, d, offset);
  180. pbuf = rtw_zmalloc(1);
  181. if (!pbuf)
  182. return;
  183. _rtw_memcpy(pbuf, &val, 1);
  184. err = d->intf_ops->write(d, offset, pbuf, 1, 0);
  185. if (err)
  186. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  187. rtw_mfree(pbuf, 1);
  188. }
  189. static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
  190. {
  191. struct dvobj_priv *d;
  192. u8 *pbuf;
  193. int err;
  194. d = (struct dvobj_priv *)p;
  195. _halmac_mac_reg_page0_chk(__func__, d, offset);
  196. val = cpu_to_le16(val);
  197. pbuf = rtw_zmalloc(2);
  198. if (!pbuf)
  199. return;
  200. _rtw_memcpy(pbuf, &val, 2);
  201. err = d->intf_ops->write(d, offset, pbuf, 2, 0);
  202. if (err)
  203. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  204. rtw_mfree(pbuf, 2);
  205. }
  206. static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
  207. {
  208. struct dvobj_priv *d;
  209. u8 *pbuf;
  210. int err;
  211. d = (struct dvobj_priv *)p;
  212. _halmac_mac_reg_page0_chk(__func__, d, offset);
  213. val = cpu_to_le32(val);
  214. pbuf = rtw_zmalloc(4);
  215. if (!pbuf)
  216. return;
  217. _rtw_memcpy(pbuf, &val, 4);
  218. err = d->intf_ops->write(d, offset, pbuf, 4, 0);
  219. if (err)
  220. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  221. rtw_mfree(pbuf, 4);
  222. }
  223. #else /* !CONFIG_SDIO_HCI */
  224. static u8 _halmac_reg_read_8(void *p, u32 offset)
  225. {
  226. struct dvobj_priv *d;
  227. PADAPTER adapter;
  228. d = (struct dvobj_priv *)p;
  229. adapter = dvobj_get_primary_adapter(d);
  230. return rtw_read8(adapter, offset);
  231. }
  232. static u16 _halmac_reg_read_16(void *p, u32 offset)
  233. {
  234. struct dvobj_priv *d;
  235. PADAPTER adapter;
  236. d = (struct dvobj_priv *)p;
  237. adapter = dvobj_get_primary_adapter(d);
  238. return rtw_read16(adapter, offset);
  239. }
  240. static u32 _halmac_reg_read_32(void *p, u32 offset)
  241. {
  242. struct dvobj_priv *d;
  243. PADAPTER adapter;
  244. d = (struct dvobj_priv *)p;
  245. adapter = dvobj_get_primary_adapter(d);
  246. return rtw_read32(adapter, offset);
  247. }
  248. static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
  249. {
  250. struct dvobj_priv *d;
  251. PADAPTER adapter;
  252. int err;
  253. d = (struct dvobj_priv *)p;
  254. adapter = dvobj_get_primary_adapter(d);
  255. err = rtw_write8(adapter, offset, val);
  256. if (err == _FAIL)
  257. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  258. }
  259. static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
  260. {
  261. struct dvobj_priv *d;
  262. PADAPTER adapter;
  263. int err;
  264. d = (struct dvobj_priv *)p;
  265. adapter = dvobj_get_primary_adapter(d);
  266. err = rtw_write16(adapter, offset, val);
  267. if (err == _FAIL)
  268. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  269. }
  270. static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
  271. {
  272. struct dvobj_priv *d;
  273. PADAPTER adapter;
  274. int err;
  275. d = (struct dvobj_priv *)p;
  276. adapter = dvobj_get_primary_adapter(d);
  277. err = rtw_write32(adapter, offset, val);
  278. if (err == _FAIL)
  279. RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
  280. }
  281. #endif /* !CONFIG_SDIO_HCI */
  282. static u8 _halmac_mfree(void *p, void *buffer, u32 size)
  283. {
  284. rtw_mfree(buffer, size);
  285. return _TRUE;
  286. }
  287. static void *_halmac_malloc(void *p, u32 size)
  288. {
  289. return rtw_zmalloc(size);
  290. }
  291. static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
  292. {
  293. _rtw_memcpy(dest, src, size);
  294. return _TRUE;
  295. }
  296. static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
  297. {
  298. _rtw_memset(addr, value, size);
  299. return _TRUE;
  300. }
  301. static void _halmac_udelay(void *p, u32 us)
  302. {
  303. rtw_udelay_os(us);
  304. }
  305. static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
  306. {
  307. _rtw_mutex_init(pMutex);
  308. return _TRUE;
  309. }
  310. static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
  311. {
  312. _rtw_mutex_free(pMutex);
  313. return _TRUE;
  314. }
  315. static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
  316. {
  317. int err;
  318. err = _enter_critical_mutex(pMutex, NULL);
  319. if (err)
  320. return _FALSE;
  321. return _TRUE;
  322. }
  323. static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
  324. {
  325. _exit_critical_mutex(pMutex, NULL);
  326. return _TRUE;
  327. }
  328. static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
  329. {
  330. #define MSG_LEN 100
  331. va_list args;
  332. u8 str[MSG_LEN] = {0};
  333. int err;
  334. u8 ret = _TRUE;
  335. str[0] = '\n';
  336. va_start(args, fmt);
  337. err = vsnprintf(str, MSG_LEN, fmt, args);
  338. va_end(args);
  339. /* An output error is encountered */
  340. if (err < 0)
  341. return _FALSE;
  342. /* Output may be truncated due to size limit */
  343. if ((err == (MSG_LEN - 1)) && (str[MSG_LEN - 2] != '\n'))
  344. ret = _FALSE;
  345. if (msg_level == HALMAC_DBG_ALWAYS)
  346. RTW_PRINT(MSG_PREFIX "%s", str);
  347. else if (msg_level <= HALMAC_DBG_ERR)
  348. RTW_ERR(MSG_PREFIX "%s", str);
  349. else if (msg_level <= HALMAC_DBG_WARN)
  350. RTW_WARN(MSG_PREFIX "%s", str);
  351. else
  352. RTW_DBG(MSG_PREFIX "%s", str);
  353. return ret;
  354. }
  355. static u8 _halmac_buff_print(void *p, u32 msg_type, u8 msg_level, s8 *buf, u32 size)
  356. {
  357. if (msg_level <= HALMAC_DBG_WARN)
  358. RTW_INFO_DUMP(MSG_PREFIX, buf, size);
  359. else
  360. RTW_DBG_DUMP(MSG_PREFIX, buf, size);
  361. return _TRUE;
  362. }
  363. const char *const RTW_HALMAC_FEATURE_NAME[] = {
  364. "HALMAC_FEATURE_CFG_PARA",
  365. "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
  366. "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
  367. "HALMAC_FEATURE_UPDATE_PACKET",
  368. "HALMAC_FEATURE_UPDATE_DATAPACK",
  369. "HALMAC_FEATURE_RUN_DATAPACK",
  370. "HALMAC_FEATURE_CHANNEL_SWITCH",
  371. "HALMAC_FEATURE_IQK",
  372. "HALMAC_FEATURE_POWER_TRACKING",
  373. "HALMAC_FEATURE_PSD",
  374. "HALMAC_FEATURE_ALL"
  375. };
  376. static inline u8 is_valid_id_status(HALMAC_FEATURE_ID id, HALMAC_CMD_PROCESS_STATUS status)
  377. {
  378. switch (id) {
  379. case HALMAC_FEATURE_CFG_PARA:
  380. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  381. break;
  382. case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
  383. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  384. if (HALMAC_CMD_PROCESS_DONE != status)
  385. RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
  386. __FUNCTION__, id, status);
  387. break;
  388. case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
  389. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  390. if (HALMAC_CMD_PROCESS_DONE != status)
  391. RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
  392. __FUNCTION__, id, status);
  393. break;
  394. case HALMAC_FEATURE_UPDATE_PACKET:
  395. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  396. break;
  397. case HALMAC_FEATURE_UPDATE_DATAPACK:
  398. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  399. break;
  400. case HALMAC_FEATURE_RUN_DATAPACK:
  401. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  402. break;
  403. case HALMAC_FEATURE_CHANNEL_SWITCH:
  404. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  405. break;
  406. case HALMAC_FEATURE_IQK:
  407. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  408. break;
  409. case HALMAC_FEATURE_POWER_TRACKING:
  410. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  411. break;
  412. case HALMAC_FEATURE_PSD:
  413. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  414. break;
  415. case HALMAC_FEATURE_ALL:
  416. RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
  417. break;
  418. default:
  419. RTW_ERR("%s: unknown feature id(%d)\n", __FUNCTION__, id);
  420. return _FALSE;
  421. }
  422. return _TRUE;
  423. }
  424. static int init_halmac_event_with_waittime(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size, u32 time)
  425. {
  426. struct submit_ctx *sctx;
  427. if (!d->hmpriv.indicator[id].sctx) {
  428. sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
  429. if (!sctx)
  430. return -1;
  431. } else {
  432. RTW_WARN("%s: id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
  433. sctx = d->hmpriv.indicator[id].sctx;
  434. d->hmpriv.indicator[id].sctx = NULL;
  435. }
  436. rtw_sctx_init(sctx, time);
  437. d->hmpriv.indicator[id].buffer = buf;
  438. d->hmpriv.indicator[id].buf_size = size;
  439. d->hmpriv.indicator[id].ret_size = 0;
  440. d->hmpriv.indicator[id].status = 0;
  441. /* fill sctx at least to sure other variables are all ready! */
  442. d->hmpriv.indicator[id].sctx = sctx;
  443. return 0;
  444. }
  445. static inline int init_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size)
  446. {
  447. return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
  448. }
  449. static void free_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
  450. {
  451. struct submit_ctx *sctx;
  452. if (!d->hmpriv.indicator[id].sctx)
  453. return;
  454. sctx = d->hmpriv.indicator[id].sctx;
  455. d->hmpriv.indicator[id].sctx = NULL;
  456. rtw_mfree((u8 *)sctx, sizeof(*sctx));
  457. }
  458. static int wait_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
  459. {
  460. PHALMAC_ADAPTER mac;
  461. PHALMAC_API api;
  462. struct submit_ctx *sctx;
  463. int ret;
  464. sctx = d->hmpriv.indicator[id].sctx;
  465. if (!sctx)
  466. return -1;
  467. ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
  468. free_halmac_event(d, id);
  469. if (_SUCCESS == ret)
  470. return 0;
  471. /* timeout! We have to reset halmac state */
  472. RTW_ERR("%s: Wait id(%d, %s) TIMEOUT! Reset HALMAC state!\n",
  473. __FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id]);
  474. mac = dvobj_to_halmac(d);
  475. api = HALMAC_GET_API(mac);
  476. api->halmac_reset_feature(mac, id);
  477. return -1;
  478. }
  479. /*
  480. * Return:
  481. * Always return _TRUE, HALMAC don't care the return value.
  482. */
  483. static u8 _halmac_event_indication(void *p, HALMAC_FEATURE_ID feature_id, HALMAC_CMD_PROCESS_STATUS process_status, u8 *buf, u32 size)
  484. {
  485. struct dvobj_priv *d;
  486. PADAPTER adapter;
  487. PHAL_DATA_TYPE hal;
  488. struct halmac_indicator *tbl, *indicator;
  489. struct submit_ctx *sctx;
  490. u32 cpsz;
  491. u8 ret;
  492. d = (struct dvobj_priv *)p;
  493. adapter = dvobj_get_primary_adapter(d);
  494. hal = GET_HAL_DATA(adapter);
  495. tbl = d->hmpriv.indicator;
  496. /* Filter(Skip) middle status indication */
  497. ret = is_valid_id_status(feature_id, process_status);
  498. if (_FALSE == ret)
  499. goto exit;
  500. indicator = &tbl[feature_id];
  501. indicator->status = process_status;
  502. indicator->ret_size = size;
  503. if (!indicator->sctx) {
  504. RTW_WARN("%s: No feature id(%d, %s) waiting!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
  505. goto exit;
  506. }
  507. sctx = indicator->sctx;
  508. if (HALMAC_CMD_PROCESS_ERROR == process_status) {
  509. RTW_ERR("%s: Something wrong id(%d, %s)!!\n", __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
  510. rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
  511. goto exit;
  512. }
  513. if (size > indicator->buf_size) {
  514. RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), data will be truncated!\n",
  515. __FUNCTION__, feature_id, RTW_HALMAC_FEATURE_NAME[feature_id], indicator->buf_size, size);
  516. cpsz = indicator->buf_size;
  517. } else {
  518. cpsz = size;
  519. }
  520. if (cpsz && indicator->buffer)
  521. _rtw_memcpy(indicator->buffer, buf, cpsz);
  522. rtw_sctx_done(&sctx);
  523. exit:
  524. return _TRUE;
  525. }
  526. HALMAC_PLATFORM_API rtw_halmac_platform_api = {
  527. /* R/W register */
  528. #ifdef CONFIG_SDIO_HCI
  529. .SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
  530. .SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
  531. .SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
  532. .SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
  533. .SDIO_CMD53_READ_N = _halmac_sdio_reg_read_n,
  534. .SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
  535. .SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
  536. .SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
  537. .SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
  538. #endif /* CONFIG_SDIO_HCI */
  539. #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCIE_HCI)
  540. .REG_READ_8 = _halmac_reg_read_8,
  541. .REG_READ_16 = _halmac_reg_read_16,
  542. .REG_READ_32 = _halmac_reg_read_32,
  543. .REG_WRITE_8 = _halmac_reg_write_8,
  544. .REG_WRITE_16 = _halmac_reg_write_16,
  545. .REG_WRITE_32 = _halmac_reg_write_32,
  546. #endif /* CONFIG_USB_HCI || CONFIG_PCIE_HCI */
  547. /* Write data */
  548. #if 0
  549. /* impletement in HAL-IC level */
  550. .SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
  551. .SEND_H2C_PKT = sdio_write_data_h2c,
  552. #endif
  553. /* Memory allocate */
  554. .RTL_FREE = _halmac_mfree,
  555. .RTL_MALLOC = _halmac_malloc,
  556. .RTL_MEMCPY = _halmac_memcpy,
  557. .RTL_MEMSET = _halmac_memset,
  558. /* Sleep */
  559. .RTL_DELAY_US = _halmac_udelay,
  560. /* Process Synchronization */
  561. .MUTEX_INIT = _halmac_mutex_init,
  562. .MUTEX_DEINIT = _halmac_mutex_deinit,
  563. .MUTEX_LOCK = _halmac_mutex_lock,
  564. .MUTEX_UNLOCK = _halmac_mutex_unlock,
  565. .MSG_PRINT = _halmac_msg_print,
  566. .BUFF_PRINT = _halmac_buff_print,
  567. .EVENT_INDICATION = _halmac_event_indication,
  568. };
  569. u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
  570. {
  571. PHALMAC_ADAPTER mac;
  572. PHALMAC_API api;
  573. /* WARNING: pintf_dev should not be null! */
  574. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  575. api = HALMAC_GET_API(mac);
  576. return api->halmac_reg_read_8(mac, addr);
  577. }
  578. u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
  579. {
  580. PHALMAC_ADAPTER mac;
  581. PHALMAC_API api;
  582. /* WARNING: pintf_dev should not be null! */
  583. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  584. api = HALMAC_GET_API(mac);
  585. return api->halmac_reg_read_16(mac, addr);
  586. }
  587. u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
  588. {
  589. PHALMAC_ADAPTER mac;
  590. PHALMAC_API api;
  591. /* WARNING: pintf_dev should not be null! */
  592. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  593. api = HALMAC_GET_API(mac);
  594. return api->halmac_reg_read_32(mac, addr);
  595. }
  596. void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem)
  597. {
  598. #if defined(CONFIG_SDIO_HCI)
  599. PHALMAC_ADAPTER mac;
  600. PHALMAC_API api;
  601. if (pmem == NULL) {
  602. RTW_ERR("pmem is NULL\n");
  603. return;
  604. }
  605. /* WARNING: pintf_dev should not be null! */
  606. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  607. api = HALMAC_GET_API(mac);
  608. api->halmac_reg_sdio_cmd53_read_n(mac, addr, cnt, pmem);
  609. #endif
  610. }
  611. #ifdef CONFIG_SDIO_INDIRECT_ACCESS
  612. u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr)
  613. {
  614. PHALMAC_ADAPTER mac;
  615. PHALMAC_API api;
  616. /* WARNING: pintf_dev should not be null! */
  617. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  618. api = HALMAC_GET_API(mac);
  619. /*return api->halmac_reg_read_indirect_8(mac, addr);*/
  620. return api->halmac_reg_read_8(mac, addr);
  621. }
  622. u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr)
  623. {
  624. PHALMAC_ADAPTER mac;
  625. PHALMAC_API api;
  626. u16 val16 = 0;
  627. /* WARNING: pintf_dev should not be null! */
  628. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  629. api = HALMAC_GET_API(mac);
  630. /*return api->halmac_reg_read_indirect_16(mac, addr);*/
  631. return api->halmac_reg_read_16(mac, addr);
  632. }
  633. u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr)
  634. {
  635. PHALMAC_ADAPTER mac;
  636. PHALMAC_API api;
  637. /* WARNING: pintf_dev should not be null! */
  638. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  639. api = HALMAC_GET_API(mac);
  640. return api->halmac_reg_read_indirect_32(mac, addr);
  641. }
  642. #endif
  643. int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
  644. {
  645. PHALMAC_ADAPTER mac;
  646. PHALMAC_API api;
  647. HALMAC_RET_STATUS status;
  648. /* WARNING: pintf_dev should not be null! */
  649. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  650. api = HALMAC_GET_API(mac);
  651. status = api->halmac_reg_write_8(mac, addr, value);
  652. if (status == HALMAC_RET_SUCCESS)
  653. return 0;
  654. return -1;
  655. }
  656. int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
  657. {
  658. PHALMAC_ADAPTER mac;
  659. PHALMAC_API api;
  660. HALMAC_RET_STATUS status;
  661. /* WARNING: pintf_dev should not be null! */
  662. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  663. api = HALMAC_GET_API(mac);
  664. status = api->halmac_reg_write_16(mac, addr, value);
  665. if (status == HALMAC_RET_SUCCESS)
  666. return 0;
  667. return -1;
  668. }
  669. int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
  670. {
  671. PHALMAC_ADAPTER mac;
  672. PHALMAC_API api;
  673. HALMAC_RET_STATUS status;
  674. /* WARNING: pintf_dev should not be null! */
  675. mac = dvobj_to_halmac(pintfhdl->pintf_dev);
  676. api = HALMAC_GET_API(mac);
  677. status = api->halmac_reg_write_32(mac, addr, value);
  678. if (status == HALMAC_RET_SUCCESS)
  679. return 0;
  680. return -1;
  681. }
  682. static int init_priv(struct halmacpriv *priv)
  683. {
  684. struct halmac_indicator *indicator;
  685. u32 count, size;
  686. size = sizeof(*priv);
  687. _rtw_memset(priv, 0, size);
  688. count = HALMAC_FEATURE_ALL + 1;
  689. size = sizeof(*indicator) * count;
  690. indicator = (struct halmac_indicator *)rtw_zmalloc(size);
  691. if (!indicator)
  692. return -1;
  693. priv->indicator = indicator;
  694. return 0;
  695. }
  696. static void deinit_priv(struct halmacpriv *priv)
  697. {
  698. struct halmac_indicator *indicator;
  699. indicator = priv->indicator;
  700. priv->indicator = NULL;
  701. if (indicator) {
  702. u32 count, size;
  703. count = HALMAC_FEATURE_ALL + 1;
  704. #ifdef CONFIG_RTW_DEBUG
  705. {
  706. struct submit_ctx *sctx;
  707. u32 i;
  708. for (i = 0; i < count; i++) {
  709. if (!indicator[i].sctx)
  710. continue;
  711. RTW_WARN("%s: %s id(%d) sctx still exist!!\n",
  712. __FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
  713. sctx = indicator[i].sctx;
  714. indicator[i].sctx = NULL;
  715. rtw_mfree((u8 *)sctx, sizeof(*sctx));
  716. }
  717. }
  718. #endif /* !CONFIG_RTW_DEBUG */
  719. size = sizeof(*indicator) * count;
  720. rtw_mfree((u8 *)indicator, size);
  721. }
  722. }
  723. #ifdef CONFIG_SDIO_HCI
  724. static enum _HALMAC_SDIO_SPEC_VER _sdio_ver_drv2halmac(struct dvobj_priv *d)
  725. {
  726. bool v3;
  727. enum _HALMAC_SDIO_SPEC_VER ver;
  728. v3 = rtw_is_sdio30(dvobj_get_primary_adapter(d));
  729. if (v3)
  730. ver = HALMAC_SDIO_SPEC_VER_3_00;
  731. else
  732. ver = HALMAC_SDIO_SPEC_VER_2_00;
  733. return ver;
  734. }
  735. #endif /* CONFIG_SDIO_HCI */
  736. void rtw_dump_halmac_info(void *sel)
  737. {
  738. HALMAC_RET_STATUS status;
  739. HALMAC_VER halmac_version;
  740. status = halmac_get_version(&halmac_version);
  741. if (status != HALMAC_RET_SUCCESS)
  742. return;
  743. RTW_PRINT_SEL(sel, "HALMAC VER -%x.%x.%x\n", halmac_version.major_ver, halmac_version.prototype_ver, halmac_version.minor_ver);
  744. }
  745. int rtw_halmac_init_adapter(struct dvobj_priv *d, PHALMAC_PLATFORM_API pf_api)
  746. {
  747. PHALMAC_ADAPTER halmac;
  748. PHALMAC_API api;
  749. HALMAC_INTERFACE intf;
  750. HALMAC_RET_STATUS status;
  751. int err = 0;
  752. #ifdef CONFIG_SDIO_HCI
  753. HALMAC_SDIO_HW_INFO info;
  754. #endif /* CONFIG_SDIO_HCI */
  755. halmac = dvobj_to_halmac(d);
  756. if (halmac) {
  757. err = 0;
  758. goto out;
  759. }
  760. err = init_priv(&d->hmpriv);
  761. if (err)
  762. goto out;
  763. #ifdef CONFIG_SDIO_HCI
  764. intf = HALMAC_INTERFACE_SDIO;
  765. #elif defined(CONFIG_USB_HCI)
  766. intf = HALMAC_INTERFACE_USB;
  767. #elif defined(CONFIG_PCIE_HCI)
  768. intf = HALMAC_INTERFACE_PCIE;
  769. #else
  770. #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
  771. intf = HALMAC_INTERFACE_UNDEFINE;
  772. #endif
  773. status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
  774. if (HALMAC_RET_SUCCESS != status) {
  775. RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
  776. err = -1;
  777. goto out;
  778. }
  779. dvobj_set_halmac(d, halmac);
  780. status = api->halmac_phy_cfg(halmac, HALMAC_INTF_PHY_PLATFORM_ALL);
  781. if (status != HALMAC_RET_SUCCESS) {
  782. RTW_ERR("%s: halmac_phy_cfg fail!(status=%d)\n", __FUNCTION__, status);
  783. err = -1;
  784. goto out;
  785. }
  786. #ifdef CONFIG_SDIO_HCI
  787. info.spec_ver = _sdio_ver_drv2halmac(d);
  788. /* clock unit is MHz */
  789. info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
  790. RTW_DBG("%s: SDIO clock=%uMHz ver=%u\n", __FUNCTION__, info.clock_speed, info.spec_ver+2);
  791. status = api->halmac_sdio_hw_info(halmac, &info);
  792. if (status != HALMAC_RET_SUCCESS) {
  793. RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n", __FUNCTION__, status);
  794. err = -1;
  795. goto out;
  796. }
  797. #endif /* CONFIG_SDIO_HCI */
  798. out:
  799. if (err)
  800. rtw_halmac_deinit_adapter(d);
  801. return err;
  802. }
  803. int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
  804. {
  805. PHALMAC_ADAPTER halmac;
  806. HALMAC_RET_STATUS status;
  807. int err = 0;
  808. halmac = dvobj_to_halmac(d);
  809. if (!halmac) {
  810. err = 0;
  811. goto out;
  812. }
  813. deinit_priv(&d->hmpriv);
  814. status = halmac_deinit_adapter(halmac);
  815. dvobj_set_halmac(d, NULL);
  816. if (status != HALMAC_RET_SUCCESS) {
  817. err = -1;
  818. goto out;
  819. }
  820. out:
  821. return err;
  822. }
  823. /*
  824. * Description:
  825. * Power on device hardware.
  826. * [Notice!] If device's power state is on before,
  827. * it would be power off first and turn on power again.
  828. *
  829. * Return:
  830. * 0 power on success
  831. * -1 power on fail
  832. * -2 power state unchange
  833. */
  834. int rtw_halmac_poweron(struct dvobj_priv *d)
  835. {
  836. PHALMAC_ADAPTER halmac;
  837. PHALMAC_API api;
  838. HALMAC_RET_STATUS status;
  839. int err = -1;
  840. halmac = dvobj_to_halmac(d);
  841. if (!halmac)
  842. goto out;
  843. api = HALMAC_GET_API(halmac);
  844. status = api->halmac_pre_init_system_cfg(halmac);
  845. if (status != HALMAC_RET_SUCCESS)
  846. goto out;
  847. #ifdef CONFIG_SDIO_HCI
  848. status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
  849. if (status != HALMAC_RET_SUCCESS)
  850. goto out;
  851. #endif /* CONFIG_SDIO_HCI */
  852. status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
  853. if (HALMAC_RET_PWR_UNCHANGE == status) {
  854. /*
  855. * Work around for warm reboot but device not power off,
  856. * but it would also fall into this case when auto power on is enabled.
  857. */
  858. api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
  859. status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
  860. RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
  861. __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
  862. }
  863. if (HALMAC_RET_SUCCESS != status) {
  864. if (HALMAC_RET_PWR_UNCHANGE == status)
  865. err = -2;
  866. goto out;
  867. }
  868. status = api->halmac_init_system_cfg(halmac);
  869. if (status != HALMAC_RET_SUCCESS)
  870. goto out;
  871. err = 0;
  872. out:
  873. return err;
  874. }
  875. /*
  876. * Description:
  877. * Power off device hardware.
  878. *
  879. * Return:
  880. * 0 Power off success
  881. * -1 Power off fail
  882. */
  883. int rtw_halmac_poweroff(struct dvobj_priv *d)
  884. {
  885. PHALMAC_ADAPTER halmac;
  886. PHALMAC_API api;
  887. HALMAC_RET_STATUS status;
  888. int err = -1;
  889. halmac = dvobj_to_halmac(d);
  890. if (!halmac)
  891. goto out;
  892. api = HALMAC_GET_API(halmac);
  893. status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
  894. if ((HALMAC_RET_SUCCESS != status)
  895. && (HALMAC_RET_PWR_UNCHANGE != status))
  896. goto out;
  897. err = 0;
  898. out:
  899. return err;
  900. }
  901. /*
  902. * Note:
  903. * When this function return, the register REG_RCR may be changed.
  904. */
  905. int rtw_halmac_config_rx_info(struct dvobj_priv *d, HALMAC_DRV_INFO info)
  906. {
  907. PHALMAC_ADAPTER halmac;
  908. PHALMAC_API api;
  909. HALMAC_RET_STATUS status;
  910. int err = -1;
  911. halmac = dvobj_to_halmac(d);
  912. api = HALMAC_GET_API(halmac);
  913. status = api->halmac_cfg_drv_info(halmac, info);
  914. if (status != HALMAC_RET_SUCCESS)
  915. goto out;
  916. err = 0;
  917. out:
  918. return err;
  919. }
  920. #ifdef CONFIG_SUPPORT_TRX_SHARED
  921. static inline HALMAC_RX_FIFO_EXPANDING_MODE _trx_share_mode_drv2halmac(u8 trx_share_mode)
  922. {
  923. if (0 == trx_share_mode)
  924. return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
  925. else if (1 == trx_share_mode)
  926. return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
  927. else if (2 == trx_share_mode)
  928. return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
  929. else if (3 == trx_share_mode)
  930. return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
  931. else
  932. return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
  933. }
  934. static HALMAC_RX_FIFO_EXPANDING_MODE _rtw_get_trx_share_mode(_adapter *adapter)
  935. {
  936. struct registry_priv *registry_par = &adapter->registrypriv;
  937. return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
  938. }
  939. void dump_trx_share_mode(void *sel, _adapter *adapter)
  940. {
  941. struct registry_priv *registry_par = &adapter->registrypriv;
  942. u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
  943. if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
  944. RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
  945. else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
  946. RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
  947. else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
  948. RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
  949. else
  950. RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
  951. }
  952. #endif
  953. static u8 _get_drv_rsvd_page(HALMAC_DRV_RSVD_PG_NUM rsvd_page_number)
  954. {
  955. if (HALMAC_RSVD_PG_NUM16 == rsvd_page_number)
  956. return 16;
  957. else if (HALMAC_RSVD_PG_NUM24 == rsvd_page_number)
  958. return 24;
  959. else if (HALMAC_RSVD_PG_NUM32 == rsvd_page_number)
  960. return 32;
  961. RTW_ERR("%s unknown HALMAC_RSVD_PG type :%d\n", __func__, rsvd_page_number);
  962. rtw_warn_on(1);
  963. return 0;
  964. }
  965. static HALMAC_TRX_MODE _choose_trx_mode(struct dvobj_priv *d)
  966. {
  967. PADAPTER p;
  968. p = dvobj_get_primary_adapter(d);
  969. if (p->registrypriv.wifi_spec)
  970. return HALMAC_TRX_MODE_WMM;
  971. #ifdef CONFIG_SUPPORT_TRX_SHARED
  972. if (_rtw_get_trx_share_mode(p))
  973. return HALMAC_TRX_MODE_TRXSHARE;
  974. #endif
  975. return HALMAC_TRX_MODE_NORMAL;
  976. }
  977. static inline HALMAC_RF_TYPE _rf_type_drv2halmac(RT_RF_TYPE_DEF_E rf_drv)
  978. {
  979. HALMAC_RF_TYPE rf_mac;
  980. switch (rf_drv) {
  981. case RF_1T2R:
  982. rf_mac = HALMAC_RF_1T2R;
  983. break;
  984. case RF_2T4R:
  985. rf_mac = HALMAC_RF_2T4R;
  986. break;
  987. case RF_2T2R:
  988. rf_mac = HALMAC_RF_2T2R;
  989. break;
  990. case RF_1T1R:
  991. rf_mac = HALMAC_RF_1T1R;
  992. break;
  993. case RF_2T2R_GREEN:
  994. rf_mac = HALMAC_RF_2T2R_GREEN;
  995. break;
  996. case RF_2T3R:
  997. rf_mac = HALMAC_RF_2T3R;
  998. break;
  999. case RF_3T3R:
  1000. rf_mac = HALMAC_RF_3T3R;
  1001. break;
  1002. case RF_3T4R:
  1003. rf_mac = HALMAC_RF_3T4R;
  1004. break;
  1005. case RF_4T4R:
  1006. rf_mac = HALMAC_RF_4T4R;
  1007. break;
  1008. default:
  1009. rf_mac = (HALMAC_RF_TYPE)rf_drv;
  1010. break;
  1011. }
  1012. return rf_mac;
  1013. }
  1014. static int _send_general_info(struct dvobj_priv *d)
  1015. {
  1016. PADAPTER adapter;
  1017. PHAL_DATA_TYPE hal;
  1018. PHALMAC_ADAPTER halmac;
  1019. PHALMAC_API api;
  1020. HALMAC_GENERAL_INFO info;
  1021. HALMAC_RET_STATUS status;
  1022. u8 val8;
  1023. adapter = dvobj_get_primary_adapter(d);
  1024. hal = GET_HAL_DATA(adapter);
  1025. halmac = dvobj_to_halmac(d);
  1026. if (!halmac)
  1027. return -1;
  1028. api = HALMAC_GET_API(halmac);
  1029. _rtw_memset(&info, 0, sizeof(info));
  1030. info.rfe_type = (u8)hal->rfe_type;
  1031. rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, &val8);
  1032. info.rf_type = _rf_type_drv2halmac(val8);
  1033. status = api->halmac_send_general_info(halmac, &info);
  1034. switch (status) {
  1035. case HALMAC_RET_SUCCESS:
  1036. break;
  1037. case HALMAC_RET_NO_DLFW:
  1038. RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
  1039. __FUNCTION__);
  1040. /* go through */
  1041. default:
  1042. return -1;
  1043. }
  1044. return 0;
  1045. }
  1046. /*
  1047. * Description:
  1048. * Downlaod Firmware Flow
  1049. *
  1050. * Parameters:
  1051. * d pointer of struct dvobj_priv
  1052. * fw firmware array
  1053. * fwsize firmware size
  1054. * re_dl re-download firmware or not
  1055. * 0: run in init hal flow, not re-download
  1056. * 1: it is a stand alone operation, not in init hal flow
  1057. *
  1058. * Return:
  1059. * 0 Success
  1060. * others Fail
  1061. */
  1062. static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
  1063. {
  1064. PHALMAC_ADAPTER mac;
  1065. PHALMAC_API api;
  1066. HALMAC_RET_STATUS status;
  1067. int err = 0;
  1068. PHAL_DATA_TYPE hal;
  1069. HALMAC_FW_VERSION fw_vesion;
  1070. mac = dvobj_to_halmac(d);
  1071. api = HALMAC_GET_API(mac);
  1072. hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
  1073. if ((!fw) || (!fwsize))
  1074. return -1;
  1075. /* 1. Driver Stop Tx */
  1076. /* ToDo */
  1077. /* 2. Driver Check Tx FIFO is empty */
  1078. /* ToDo */
  1079. /* 3. Config MAX download size */
  1080. #ifdef CONFIG_USB_HCI
  1081. /* for USB do not exceed MAX_CMDBUF_SZ */
  1082. api->halmac_cfg_max_dl_size(mac, 0x1000);
  1083. #elif defined CONFIG_PCIE_HCI
  1084. /* required a even length from u32 */
  1085. api->halmac_cfg_max_dl_size(mac, (MAX_CMDBUF_SZ - TXDESC_OFFSET) & 0xFFFFFFFE);
  1086. #endif
  1087. /* 4. Download Firmware */
  1088. status = api->halmac_download_firmware(mac, fw, fwsize);
  1089. if (HALMAC_RET_SUCCESS != status)
  1090. return -1;
  1091. /* 5. Driver resume TX if needed */
  1092. /* ToDo */
  1093. if (re_dl) {
  1094. HALMAC_TRX_MODE mode;
  1095. /* 6. Init TRX Configuration */
  1096. mode = _choose_trx_mode(d);
  1097. status = api->halmac_init_trx_cfg(mac, mode);
  1098. if (HALMAC_RET_SUCCESS != status)
  1099. return -1;
  1100. /* 7. Config RX Aggregation */
  1101. err = rtw_halmac_rx_agg_switch(d, _TRUE);
  1102. if (err)
  1103. return -1;
  1104. /* 8. Send General Info */
  1105. err = _send_general_info(d);
  1106. if (err)
  1107. return -1;
  1108. }
  1109. /* 9. Reset driver variables if needed */
  1110. hal->LastHMEBoxNum = 0;
  1111. /* 10. Get FW version */
  1112. status = api->halmac_get_fw_version(mac, &fw_vesion);
  1113. if (status == HALMAC_RET_SUCCESS) {
  1114. hal->firmware_version = fw_vesion.version;
  1115. hal->firmware_sub_version = fw_vesion.sub_version;
  1116. hal->firmware_size = fwsize;
  1117. }
  1118. return err;
  1119. }
  1120. static HALMAC_RET_STATUS init_mac_flow(struct dvobj_priv *d)
  1121. {
  1122. PADAPTER p;
  1123. PHALMAC_ADAPTER halmac;
  1124. PHALMAC_API api;
  1125. HALMAC_WLAN_ADDR hwa;
  1126. HALMAC_TRX_MODE trx_mode;
  1127. HALMAC_RET_STATUS status;
  1128. u8 nettype;
  1129. int err;
  1130. PHAL_DATA_TYPE hal;
  1131. HALMAC_DRV_RSVD_PG_NUM rsvd_page_number = HALMAC_RSVD_PG_NUM16;/*HALMAC_RSVD_PG_NUM24/HALMAC_RSVD_PG_NUM32*/
  1132. p = dvobj_get_primary_adapter(d);
  1133. hal = GET_HAL_DATA(p);
  1134. halmac = dvobj_to_halmac(d);
  1135. api = HALMAC_GET_API(halmac);
  1136. #ifdef CONFIG_SUPPORT_TRX_SHARED
  1137. status = api->halmac_cfg_rx_fifo_expanding_mode(halmac, _rtw_get_trx_share_mode(p));
  1138. if (status != HALMAC_RET_SUCCESS)
  1139. goto out;
  1140. #endif
  1141. #ifdef CONFIG_PNO_SUPPORT
  1142. rsvd_page_number = HALMAC_RSVD_PG_NUM32;
  1143. #endif
  1144. status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
  1145. if (status != HALMAC_RET_SUCCESS)
  1146. goto out;
  1147. hal->drv_rsvd_page_number = _get_drv_rsvd_page(rsvd_page_number);
  1148. #ifdef CONFIG_USB_HCI
  1149. status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
  1150. if (status != HALMAC_RET_SUCCESS)
  1151. goto out;
  1152. #endif /* CONFIG_USB_HCI */
  1153. trx_mode = _choose_trx_mode(d);
  1154. status = api->halmac_init_mac_cfg(halmac, trx_mode);
  1155. if (status != HALMAC_RET_SUCCESS)
  1156. goto out;
  1157. err = rtw_halmac_rx_agg_switch(d, _TRUE);
  1158. if (err)
  1159. goto out;
  1160. nettype = dvobj_to_regsty(d)->wireless_mode;
  1161. if (is_supported_vht(nettype) == _TRUE)
  1162. status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
  1163. else if (is_supported_ht(nettype) == _TRUE)
  1164. status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
  1165. else if (IsSupportedTxOFDM(nettype) == _TRUE)
  1166. status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
  1167. else
  1168. status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
  1169. if (status != HALMAC_RET_SUCCESS)
  1170. goto out;
  1171. out:
  1172. return status;
  1173. }
  1174. /*
  1175. * Notices:
  1176. * Make sure
  1177. * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
  1178. * 2. HAL_DATA_TYPE.rfe_type
  1179. * already ready for use before calling this function.
  1180. */
  1181. static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
  1182. {
  1183. PADAPTER adapter;
  1184. PHALMAC_ADAPTER halmac;
  1185. PHALMAC_API api;
  1186. HALMAC_RET_STATUS status;
  1187. u32 ok = _TRUE;
  1188. u8 fw_ok = _FALSE;
  1189. int err, err_ret = -1;
  1190. adapter = dvobj_get_primary_adapter(d);
  1191. halmac = dvobj_to_halmac(d);
  1192. if (!halmac)
  1193. goto out;
  1194. api = HALMAC_GET_API(halmac);
  1195. /* StatePowerOff */
  1196. /* SKIP: halmac_init_adapter (Already done before) */
  1197. /* halmac_pre_Init_system_cfg */
  1198. /* halmac_mac_power_switch(on) */
  1199. /* halmac_Init_system_cfg */
  1200. ok = rtw_hal_power_on(adapter);
  1201. if (_FAIL == ok)
  1202. goto out;
  1203. /* StatePowerOn */
  1204. /* DownloadFW */
  1205. if (fw && fwsize) {
  1206. err = download_fw(d, fw, fwsize, 0);
  1207. if (err)
  1208. goto out;
  1209. fw_ok = _TRUE;
  1210. }
  1211. /* InitMACFlow */
  1212. status = init_mac_flow(d);
  1213. if (status != HALMAC_RET_SUCCESS)
  1214. goto out;
  1215. /* halmac_send_general_info */
  1216. if (_TRUE == fw_ok) {
  1217. err = _send_general_info(d);
  1218. if (err)
  1219. goto out;
  1220. }
  1221. /* Init Phy parameter-MAC */
  1222. ok = rtw_hal_init_mac_register(adapter);
  1223. if (_FALSE == ok)
  1224. goto out;
  1225. /* StateMacInitialized */
  1226. /* halmac_cfg_drv_info */
  1227. err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
  1228. if (err)
  1229. goto out;
  1230. /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
  1231. /* Init BB, RF */
  1232. ok = rtw_hal_init_phy(adapter);
  1233. if (_FALSE == ok)
  1234. goto out;
  1235. status = api->halmac_init_interface_cfg(halmac);
  1236. if (status != HALMAC_RET_SUCCESS)
  1237. goto out;
  1238. /* SKIP: halmac_verify_platform_api */
  1239. /* SKIP: halmac_h2c_lb */
  1240. /* StateRxIdle */
  1241. err_ret = 0;
  1242. out:
  1243. return err_ret;
  1244. }
  1245. int rtw_halmac_init_hal(struct dvobj_priv *d)
  1246. {
  1247. return _halmac_init_hal(d, NULL, 0);
  1248. }
  1249. /*
  1250. * Notices:
  1251. * Make sure
  1252. * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
  1253. * 2. HAL_DATA_TYPE.rfe_type
  1254. * already ready for use before calling this function.
  1255. */
  1256. int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
  1257. {
  1258. return _halmac_init_hal(d, fw, fwsize);
  1259. }
  1260. /*
  1261. * Notices:
  1262. * Make sure
  1263. * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
  1264. * 2. HAL_DATA_TYPE.rfe_type
  1265. * already ready for use before calling this function.
  1266. */
  1267. int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
  1268. {
  1269. u8 *fw = NULL;
  1270. u32 fwmaxsize, size = 0;
  1271. int err = 0;
  1272. fwmaxsize = FIRMWARE_MAX_SIZE;
  1273. fw = rtw_zmalloc(fwmaxsize);
  1274. if (!fw)
  1275. return -1;
  1276. size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
  1277. if (!size) {
  1278. err = -1;
  1279. goto exit;
  1280. }
  1281. err = _halmac_init_hal(d, fw, size);
  1282. exit:
  1283. rtw_mfree(fw, fwmaxsize);
  1284. fw = NULL;
  1285. return err;
  1286. }
  1287. int rtw_halmac_deinit_hal(struct dvobj_priv *d)
  1288. {
  1289. PADAPTER adapter;
  1290. PHALMAC_ADAPTER halmac;
  1291. PHALMAC_API api;
  1292. HALMAC_RET_STATUS status;
  1293. int err = -1;
  1294. adapter = dvobj_get_primary_adapter(d);
  1295. halmac = dvobj_to_halmac(d);
  1296. if (!halmac)
  1297. goto out;
  1298. api = HALMAC_GET_API(halmac);
  1299. status = api->halmac_deinit_interface_cfg(halmac);
  1300. if (status != HALMAC_RET_SUCCESS)
  1301. goto out;
  1302. rtw_hal_power_off(adapter);
  1303. err = 0;
  1304. out:
  1305. return err;
  1306. }
  1307. int rtw_halmac_self_verify(struct dvobj_priv *d)
  1308. {
  1309. PHALMAC_ADAPTER mac;
  1310. PHALMAC_API api;
  1311. HALMAC_RET_STATUS status;
  1312. int err = -1;
  1313. mac = dvobj_to_halmac(d);
  1314. api = HALMAC_GET_API(mac);
  1315. status = api->halmac_verify_platform_api(mac);
  1316. if (status != HALMAC_RET_SUCCESS)
  1317. goto out;
  1318. status = api->halmac_h2c_lb(mac);
  1319. if (status != HALMAC_RET_SUCCESS)
  1320. goto out;
  1321. err = 0;
  1322. out:
  1323. return err;
  1324. }
  1325. u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
  1326. {
  1327. PHALMAC_ADAPTER mac;
  1328. PHALMAC_API api;
  1329. u8 rst = _TRUE;
  1330. mac = dvobj_to_halmac(d);
  1331. api = HALMAC_GET_API(mac);
  1332. if (HALMAC_RET_TXFIFO_NO_EMPTY == api->halmac_txfifo_is_empty(mac, 10))
  1333. rst = _FALSE;
  1334. return rst;
  1335. }
  1336. static HALMAC_DLFW_MEM _get_halmac_fw_mem(enum fw_mem mem)
  1337. {
  1338. if (FW_EMEM == mem)
  1339. return HALMAC_DLFW_MEM_EMEM;
  1340. else if (FW_IMEM == mem)
  1341. return HALMAC_DLFW_MEM_UNDEFINE;
  1342. else if (FW_DMEM == mem)
  1343. return HALMAC_DLFW_MEM_UNDEFINE;
  1344. else
  1345. return HALMAC_DLFW_MEM_UNDEFINE;
  1346. }
  1347. #define DBG_DL_FW_MEM
  1348. int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
  1349. {
  1350. PHALMAC_ADAPTER mac;
  1351. PHALMAC_API api;
  1352. HALMAC_RET_STATUS status;
  1353. int err = 0;
  1354. u8 chk_cnt = 0;
  1355. bool txfifo_empty = _FALSE;
  1356. mac = dvobj_to_halmac(d);
  1357. api = HALMAC_GET_API(mac);
  1358. if ((!fw) || (!fwsize))
  1359. return -1;
  1360. /* 1. Driver Stop Tx */
  1361. /* ToDo */
  1362. /* 2. Driver Check Tx FIFO is empty */
  1363. do {
  1364. txfifo_empty = rtw_halmac_txfifo_is_empty(d);
  1365. chk_cnt++;
  1366. #ifdef DBG_DL_FW_MEM
  1367. RTW_INFO("polling txfifo empty chk_cnt:%d\n", chk_cnt);
  1368. #endif
  1369. rtw_msleep_os(2);
  1370. } while ((!txfifo_empty) && (chk_cnt < 100));
  1371. if (_FALSE == txfifo_empty) {
  1372. #ifdef DBG_DL_FW_MEM
  1373. {
  1374. PADAPTER adapter = dvobj_get_primary_adapter(d);
  1375. RTW_ERR("%s => polling txfifo empty failed\n", __func__);
  1376. RTW_ERR("REG_210:0x%08x\n", rtw_read32(adapter, 0x210));
  1377. RTW_ERR("REG_230:0x%08x\n", rtw_read32(adapter, 0x230));
  1378. RTW_ERR("REG_234:0x%08x\n", rtw_read32(adapter, 0x234));
  1379. RTW_ERR("REG_238:0x%08x\n", rtw_read32(adapter, 0x238));
  1380. RTW_ERR("REG_23C:0x%08x\n", rtw_read32(adapter, 0x23C));
  1381. RTW_ERR("REG_240:0x%08x\n", rtw_read32(adapter, 0x240));
  1382. RTW_ERR("REG_41A:0x%08x\n", rtw_read32(adapter, 0x41A));
  1383. RTW_ERR("REG_10FC:0x%08x\n", rtw_read32(adapter, 0x10FC));
  1384. RTW_ERR("REG_10F8:0x%08x\n", rtw_read32(adapter, 0x10F8));
  1385. RTW_ERR("REG_11F4:0x%08x\n", rtw_read32(adapter, 0x11F4));
  1386. RTW_ERR("REG_11F8:0x%08x\n", rtw_read32(adapter, 0x11F8));
  1387. }
  1388. #endif
  1389. return -1;
  1390. }
  1391. /* 3. Download Firmware MEM */
  1392. status = api->halmac_free_download_firmware(mac, _get_halmac_fw_mem(mem), fw, fwsize);
  1393. if (HALMAC_RET_SUCCESS != status) {
  1394. #ifdef DBG_DL_FW_MEM
  1395. RTW_ERR("%s => halmac_free_download_firmware failed\n", __func__);
  1396. #endif
  1397. return -1;
  1398. }
  1399. /* 4. Driver resume TX if needed */
  1400. /* ToDo */
  1401. return err;
  1402. }
  1403. int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
  1404. {
  1405. u8 *fw = NULL;
  1406. u32 fwmaxsize, size = 0;
  1407. int err = 0;
  1408. fwmaxsize = FIRMWARE_MAX_SIZE;
  1409. fw = rtw_zmalloc(fwmaxsize);
  1410. if (!fw)
  1411. return -1;
  1412. size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
  1413. if (size)
  1414. err = rtw_halmac_dlfw_mem(d, fw, size, mem);
  1415. else
  1416. err = -1;
  1417. rtw_mfree(fw, fwmaxsize);
  1418. fw = NULL;
  1419. return err;
  1420. }
  1421. /*
  1422. * Return:
  1423. * 0 Success
  1424. * -22 Invalid arguemnt
  1425. */
  1426. int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
  1427. {
  1428. PADAPTER adapter;
  1429. HALMAC_RET_STATUS status;
  1430. u32 ok = _TRUE;
  1431. int err, err_ret = -1;
  1432. if (!fw || !fwsize)
  1433. return -22;
  1434. adapter = dvobj_get_primary_adapter(d);
  1435. /* re-download firmware */
  1436. if (rtw_is_hw_init_completed(adapter))
  1437. return download_fw(d, fw, fwsize, 1);
  1438. /* Download firmware before hal init */
  1439. /* Power on, download firmware and init mac */
  1440. ok = rtw_hal_power_on(adapter);
  1441. if (_FAIL == ok)
  1442. goto out;
  1443. err = download_fw(d, fw, fwsize, 0);
  1444. if (err) {
  1445. err_ret = err;
  1446. goto out;
  1447. }
  1448. status = init_mac_flow(d);
  1449. if (status != HALMAC_RET_SUCCESS)
  1450. goto out;
  1451. err = _send_general_info(d);
  1452. if (err)
  1453. goto out;
  1454. err_ret = 0;
  1455. out:
  1456. return err_ret;
  1457. }
  1458. int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
  1459. {
  1460. u8 *fw = NULL;
  1461. u32 fwmaxsize, size = 0;
  1462. int err = 0;
  1463. fwmaxsize = FIRMWARE_MAX_SIZE;
  1464. fw = rtw_zmalloc(fwmaxsize);
  1465. if (!fw)
  1466. return -1;
  1467. size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
  1468. if (size)
  1469. err = rtw_halmac_dlfw(d, fw, size);
  1470. else
  1471. err = -1;
  1472. rtw_mfree(fw, fwmaxsize);
  1473. fw = NULL;
  1474. return err;
  1475. }
  1476. /*
  1477. * Description:
  1478. * Power on/off BB/RF domain.
  1479. *
  1480. * Parameters:
  1481. * enable _TRUE/_FALSE for power on/off
  1482. *
  1483. * Return:
  1484. * 0 Success
  1485. * others Fail
  1486. */
  1487. int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
  1488. {
  1489. PADAPTER adapter;
  1490. PHALMAC_ADAPTER halmac;
  1491. PHALMAC_API api;
  1492. HALMAC_RET_STATUS status;
  1493. adapter = dvobj_get_primary_adapter(d);
  1494. halmac = dvobj_to_halmac(d);
  1495. if (!halmac)
  1496. return -1;
  1497. api = HALMAC_GET_API(halmac);
  1498. status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
  1499. if (status != HALMAC_RET_SUCCESS)
  1500. return -1;
  1501. return 0;
  1502. }
  1503. static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
  1504. {
  1505. u8 read_down = _FALSE;
  1506. int retry_cnts = 100;
  1507. u8 valid;
  1508. do {
  1509. valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
  1510. if (0 == valid)
  1511. read_down = _TRUE;
  1512. else
  1513. rtw_msleep_os(1);
  1514. } while ((!read_down) && (retry_cnts--));
  1515. if (_FALSE == read_down)
  1516. RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
  1517. return read_down;
  1518. }
  1519. int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
  1520. {
  1521. PADAPTER adapter = dvobj_get_primary_adapter(d);
  1522. PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
  1523. u8 h2c_box_num = 0;
  1524. u32 msgbox_addr = 0;
  1525. u32 msgbox_ex_addr = 0;
  1526. u32 h2c_cmd = 0;
  1527. u32 h2c_cmd_ex = 0;
  1528. s32 ret = _FAIL;
  1529. if (adapter->bFWReady == _FALSE) {
  1530. RTW_WARN("%s: return H2C cmd because fw is not ready\n", __FUNCTION__);
  1531. return ret;
  1532. }
  1533. if (!h2c) {
  1534. RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
  1535. return ret;
  1536. }
  1537. if (rtw_is_surprise_removed(adapter)) {
  1538. RTW_WARN("%s: surprise removed\n", __FUNCTION__);
  1539. return ret;
  1540. }
  1541. _enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
  1542. /* pay attention to if race condition happened in H2C cmd setting */
  1543. h2c_box_num = hal->LastHMEBoxNum;
  1544. if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
  1545. RTW_WARN(" fw read cmd failed...\n");
  1546. goto exit;
  1547. }
  1548. /* Write Ext command(byte 4 -7) */
  1549. msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
  1550. _rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
  1551. h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
  1552. rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
  1553. /* Write command (byte 0 -3 ) */
  1554. msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
  1555. _rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
  1556. h2c_cmd = le32_to_cpu(h2c_cmd);
  1557. rtw_write32(adapter, msgbox_addr, h2c_cmd);
  1558. /* update last msg box number */
  1559. hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
  1560. ret = _SUCCESS;
  1561. #ifdef DBG_H2C_CONTENT
  1562. RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
  1563. #endif
  1564. exit:
  1565. _exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
  1566. return ret;
  1567. }
  1568. int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
  1569. {
  1570. PHALMAC_ADAPTER mac;
  1571. PHALMAC_API api;
  1572. HALMAC_RET_STATUS status;
  1573. mac = dvobj_to_halmac(d);
  1574. api = HALMAC_GET_API(mac);
  1575. status = api->halmac_get_c2h_info(mac, c2h, size);
  1576. if (HALMAC_RET_SUCCESS != status)
  1577. return -1;
  1578. return 0;
  1579. }
  1580. int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
  1581. {
  1582. PHALMAC_ADAPTER mac;
  1583. PHALMAC_API api;
  1584. HALMAC_RET_STATUS status;
  1585. u32 val;
  1586. mac = dvobj_to_halmac(d);
  1587. api = HALMAC_GET_API(mac);
  1588. status = api->halmac_get_efuse_available_size(mac, &val);
  1589. if (HALMAC_RET_SUCCESS != status)
  1590. return -1;
  1591. *size = val;
  1592. return 0;
  1593. }
  1594. int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
  1595. {
  1596. PHALMAC_ADAPTER mac;
  1597. PHALMAC_API api;
  1598. HALMAC_RET_STATUS status;
  1599. u32 val;
  1600. mac = dvobj_to_halmac(d);
  1601. api = HALMAC_GET_API(mac);
  1602. status = api->halmac_get_efuse_size(mac, &val);
  1603. if (HALMAC_RET_SUCCESS != status)
  1604. return -1;
  1605. *size = val;
  1606. return 0;
  1607. }
  1608. int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
  1609. {
  1610. PHALMAC_ADAPTER mac;
  1611. PHALMAC_API api;
  1612. HALMAC_RET_STATUS status;
  1613. HALMAC_FEATURE_ID id;
  1614. int ret;
  1615. mac = dvobj_to_halmac(d);
  1616. api = HALMAC_GET_API(mac);
  1617. id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
  1618. ret = init_halmac_event(d, id, map, size);
  1619. if (ret)
  1620. return -1;
  1621. status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
  1622. if (HALMAC_RET_SUCCESS != status) {
  1623. free_halmac_event(d, id);
  1624. return -1;
  1625. }
  1626. ret = wait_halmac_event(d, id);
  1627. if (ret)
  1628. return -1;
  1629. return 0;
  1630. }
  1631. int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
  1632. {
  1633. PHALMAC_ADAPTER mac;
  1634. PHALMAC_API api;
  1635. HALMAC_RET_STATUS status;
  1636. u8 v;
  1637. u32 i;
  1638. u8 *efuse = NULL;
  1639. u32 size = 0;
  1640. int err = 0;
  1641. mac = dvobj_to_halmac(d);
  1642. api = HALMAC_GET_API(mac);
  1643. if (api->halmac_read_efuse) {
  1644. for (i = 0; i < cnt; i++) {
  1645. status = api->halmac_read_efuse(mac, offset + i, &v);
  1646. if (HALMAC_RET_SUCCESS != status)
  1647. return -1;
  1648. data[i] = v;
  1649. }
  1650. } else {
  1651. err = rtw_halmac_get_physical_efuse_size(d, &size);
  1652. if (err)
  1653. return -1;
  1654. efuse = rtw_zmalloc(size);
  1655. if (!efuse)
  1656. return -1;
  1657. err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
  1658. if (err)
  1659. err = -1;
  1660. else
  1661. _rtw_memcpy(data, efuse + offset, cnt);
  1662. rtw_mfree(efuse, size);
  1663. }
  1664. return err;
  1665. }
  1666. int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
  1667. {
  1668. PHALMAC_ADAPTER mac;
  1669. PHALMAC_API api;
  1670. HALMAC_RET_STATUS status;
  1671. u32 i;
  1672. mac = dvobj_to_halmac(d);
  1673. api = HALMAC_GET_API(mac);
  1674. if (api->halmac_write_efuse == NULL)
  1675. return -1;
  1676. for (i = 0; i < cnt; i++) {
  1677. status = api->halmac_write_efuse(mac, offset + i, data[i]);
  1678. if (HALMAC_RET_SUCCESS != status)
  1679. return -1;
  1680. }
  1681. return 0;
  1682. }
  1683. int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
  1684. {
  1685. PHALMAC_ADAPTER mac;
  1686. PHALMAC_API api;
  1687. HALMAC_RET_STATUS status;
  1688. u32 val;
  1689. mac = dvobj_to_halmac(d);
  1690. api = HALMAC_GET_API(mac);
  1691. status = api->halmac_get_logical_efuse_size(mac, &val);
  1692. if (HALMAC_RET_SUCCESS != status)
  1693. return -1;
  1694. *size = val;
  1695. return 0;
  1696. }
  1697. int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
  1698. {
  1699. PHALMAC_ADAPTER mac;
  1700. PHALMAC_API api;
  1701. HALMAC_RET_STATUS status;
  1702. HALMAC_FEATURE_ID id;
  1703. int ret;
  1704. mac = dvobj_to_halmac(d);
  1705. api = HALMAC_GET_API(mac);
  1706. id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
  1707. ret = init_halmac_event(d, id, map, size);
  1708. if (ret)
  1709. return -1;
  1710. status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
  1711. if (HALMAC_RET_SUCCESS != status) {
  1712. free_halmac_event(d, id);
  1713. return -1;
  1714. }
  1715. ret = wait_halmac_event(d, id);
  1716. if (ret)
  1717. return -1;
  1718. return 0;
  1719. }
  1720. int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
  1721. {
  1722. PHALMAC_ADAPTER mac;
  1723. PHALMAC_API api;
  1724. HALMAC_PG_EFUSE_INFO pginfo;
  1725. HALMAC_RET_STATUS status;
  1726. mac = dvobj_to_halmac(d);
  1727. api = HALMAC_GET_API(mac);
  1728. pginfo.pEfuse_map = map;
  1729. pginfo.efuse_map_size = size;
  1730. pginfo.pEfuse_mask = maskmap;
  1731. pginfo.efuse_mask_size = masksize;
  1732. status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
  1733. if (HALMAC_RET_SUCCESS != status)
  1734. return -1;
  1735. return 0;
  1736. }
  1737. int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
  1738. {
  1739. PHALMAC_ADAPTER mac;
  1740. PHALMAC_API api;
  1741. HALMAC_RET_STATUS status;
  1742. u8 v;
  1743. u32 i;
  1744. mac = dvobj_to_halmac(d);
  1745. api = HALMAC_GET_API(mac);
  1746. for (i = 0; i < cnt; i++) {
  1747. status = api->halmac_read_logical_efuse(mac, offset + i, &v);
  1748. if (HALMAC_RET_SUCCESS != status)
  1749. return -1;
  1750. data[i] = v;
  1751. }
  1752. return 0;
  1753. }
  1754. int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
  1755. {
  1756. PHALMAC_ADAPTER mac;
  1757. PHALMAC_API api;
  1758. HALMAC_RET_STATUS status;
  1759. u32 i;
  1760. mac = dvobj_to_halmac(d);
  1761. api = HALMAC_GET_API(mac);
  1762. for (i = 0; i < cnt; i++) {
  1763. status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
  1764. if (HALMAC_RET_SUCCESS != status)
  1765. return -1;
  1766. }
  1767. return 0;
  1768. }
  1769. int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
  1770. {
  1771. PHALMAC_ADAPTER mac;
  1772. PHALMAC_API api;
  1773. HALMAC_RET_STATUS status;
  1774. u32 i;
  1775. u8 bank = 1;
  1776. mac = dvobj_to_halmac(d);
  1777. api = HALMAC_GET_API(mac);
  1778. for (i = 0; i < cnt; i++) {
  1779. status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
  1780. if (HALMAC_RET_SUCCESS != status) {
  1781. printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
  1782. return -1;
  1783. }
  1784. }
  1785. printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
  1786. return 0;
  1787. }
  1788. int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
  1789. {
  1790. PHALMAC_ADAPTER mac;
  1791. PHALMAC_API api;
  1792. HALMAC_RET_STATUS status;
  1793. HALMAC_FEATURE_ID id;
  1794. int ret;
  1795. int bank = 1;
  1796. mac = dvobj_to_halmac(d);
  1797. api = HALMAC_GET_API(mac);
  1798. status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
  1799. if (HALMAC_RET_SUCCESS != status) {
  1800. printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
  1801. return -1;
  1802. }
  1803. printk("%s: OK!\n", __FUNCTION__);
  1804. return 0;
  1805. }
  1806. static inline u8 _hw_port_drv2halmac(enum _hw_port hwport)
  1807. {
  1808. u8 port = 0;
  1809. switch (hwport) {
  1810. case HW_PORT0:
  1811. port = 0;
  1812. break;
  1813. case HW_PORT1:
  1814. port = 1;
  1815. break;
  1816. case HW_PORT2:
  1817. port = 2;
  1818. break;
  1819. case HW_PORT3:
  1820. port = 3;
  1821. break;
  1822. case HW_PORT4:
  1823. port = 4;
  1824. break;
  1825. default:
  1826. port = hwport;
  1827. break;
  1828. }
  1829. return port;
  1830. }
  1831. int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
  1832. {
  1833. PHALMAC_ADAPTER halmac;
  1834. PHALMAC_API api;
  1835. u8 port;
  1836. HALMAC_WLAN_ADDR hwa;
  1837. HALMAC_RET_STATUS status;
  1838. int err = -1;
  1839. halmac = dvobj_to_halmac(d);
  1840. api = HALMAC_GET_API(halmac);
  1841. port = _hw_port_drv2halmac(hwport);
  1842. _rtw_memset(&hwa, 0, sizeof(hwa));
  1843. _rtw_memcpy(hwa.Address, addr, 6);
  1844. status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
  1845. if (status != HALMAC_RET_SUCCESS)
  1846. goto out;
  1847. err = 0;
  1848. out:
  1849. return err;
  1850. }
  1851. int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
  1852. {
  1853. PHALMAC_ADAPTER halmac;
  1854. PHALMAC_API api;
  1855. u8 port;
  1856. HALMAC_WLAN_ADDR hwa;
  1857. HALMAC_RET_STATUS status;
  1858. int err = -1;
  1859. halmac = dvobj_to_halmac(d);
  1860. api = HALMAC_GET_API(halmac);
  1861. port = _hw_port_drv2halmac(hwport);
  1862. _rtw_memset(&hwa, 0, sizeof(HALMAC_WLAN_ADDR));
  1863. _rtw_memcpy(hwa.Address, addr, 6);
  1864. status = api->halmac_cfg_bssid(halmac, port, &hwa);
  1865. if (status != HALMAC_RET_SUCCESS)
  1866. goto out;
  1867. err = 0;
  1868. out:
  1869. return err;
  1870. }
  1871. int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
  1872. {
  1873. PHALMAC_ADAPTER mac;
  1874. PHALMAC_API api;
  1875. HALMAC_RET_STATUS status;
  1876. mac = dvobj_to_halmac(d);
  1877. api = HALMAC_GET_API(mac);
  1878. status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
  1879. if (HALMAC_RET_SUCCESS != status)
  1880. return -1;
  1881. return 0;
  1882. }
  1883. int rtw_halmac_get_hw_value(struct dvobj_priv *d, HALMAC_HW_ID hw_id, VOID *pvalue)
  1884. {
  1885. PHALMAC_ADAPTER mac;
  1886. PHALMAC_API api;
  1887. HALMAC_RET_STATUS status;
  1888. mac = dvobj_to_halmac(d);
  1889. api = HALMAC_GET_API(mac);
  1890. status = api->halmac_get_hw_value(mac, hw_id, pvalue);
  1891. if (HALMAC_RET_SUCCESS != status)
  1892. return -1;
  1893. return 0;
  1894. }
  1895. static HAL_FIFO_SEL _fifo_sel_drv2halmac(u8 fifo_sel)
  1896. {
  1897. if (0 == fifo_sel)
  1898. return HAL_FIFO_SEL_TX;
  1899. else if (1 == fifo_sel)
  1900. return HAL_FIFO_SEL_RX;
  1901. else if (2 == fifo_sel)
  1902. return HAL_FIFO_SEL_RSVD_PAGE;
  1903. else if (3 == fifo_sel)
  1904. return HAL_FIFO_SEL_REPORT;
  1905. else if (4 == fifo_sel)
  1906. return HAL_FIFO_SEL_LLT;
  1907. else
  1908. return HAL_FIFO_SEL_RSVD_PAGE;
  1909. }
  1910. #define CONFIG_HALMAC_FIFO_DUMP
  1911. int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
  1912. {
  1913. PHALMAC_ADAPTER mac;
  1914. PHALMAC_API api;
  1915. HALMAC_RET_STATUS status;
  1916. u8 *pfifo_map = NULL;
  1917. u32 fifo_size = 0;
  1918. s8 ret = 0;/* 0:success, -1:error */
  1919. u8 mem_created = _FALSE;
  1920. HAL_FIFO_SEL halmac_fifo_sel;
  1921. mac = dvobj_to_halmac(d);
  1922. api = HALMAC_GET_API(mac);
  1923. if ((size != 0) && (buffer == NULL))
  1924. return -1;
  1925. halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
  1926. if ((size) && (buffer)) {
  1927. pfifo_map = buffer;
  1928. fifo_size = size;
  1929. } else {
  1930. fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
  1931. if (fifo_size)
  1932. pfifo_map = rtw_zvmalloc(fifo_size);
  1933. if (pfifo_map == NULL)
  1934. return -1;
  1935. mem_created = _TRUE;
  1936. }
  1937. status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
  1938. if (HALMAC_RET_SUCCESS != status) {
  1939. ret = -1;
  1940. goto _exit;
  1941. }
  1942. #ifdef CONFIG_HALMAC_FIFO_DUMP
  1943. {
  1944. static const char * const fifo_sel_str[] = {
  1945. "TX", "RX", "RSVD_PAGE", "REPORT", "LLT"
  1946. };
  1947. RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
  1948. RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
  1949. RTW_INFO(" ==================================================\n");
  1950. }
  1951. #endif
  1952. _exit:
  1953. if (mem_created && pfifo_map)
  1954. rtw_vmfree(pfifo_map, fifo_size);
  1955. return ret;
  1956. }
  1957. int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
  1958. {
  1959. PADAPTER adapter;
  1960. PHAL_DATA_TYPE hal;
  1961. PHALMAC_ADAPTER halmac;
  1962. PHALMAC_API api;
  1963. HALMAC_RXAGG_CFG rxaggcfg;
  1964. HALMAC_RET_STATUS status;
  1965. int err = -1;
  1966. adapter = dvobj_get_primary_adapter(d);
  1967. hal = GET_HAL_DATA(adapter);
  1968. halmac = dvobj_to_halmac(d);
  1969. api = HALMAC_GET_API(halmac);
  1970. _rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
  1971. if (_TRUE == enable) {
  1972. #ifdef CONFIG_SDIO_HCI
  1973. rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
  1974. rxaggcfg.threshold.drv_define = 0;
  1975. #elif defined(CONFIG_USB_HCI) && defined(CONFIG_USB_RX_AGGREGATION)
  1976. switch (hal->rxagg_mode) {
  1977. case RX_AGG_DISABLE:
  1978. rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
  1979. break;
  1980. case RX_AGG_DMA:
  1981. rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
  1982. if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
  1983. rxaggcfg.threshold.drv_define = 1;
  1984. rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
  1985. rxaggcfg.threshold.size = hal->rxagg_dma_size;
  1986. }
  1987. break;
  1988. case RX_AGG_USB:
  1989. case RX_AGG_MIX:
  1990. rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
  1991. if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
  1992. rxaggcfg.threshold.drv_define = 1;
  1993. rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
  1994. rxaggcfg.threshold.size = hal->rxagg_usb_size;
  1995. }
  1996. break;
  1997. }
  1998. #endif /* CONFIG_USB_HCI */
  1999. } else
  2000. rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
  2001. status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
  2002. if (status != HALMAC_RET_SUCCESS)
  2003. goto out;
  2004. err = 0;
  2005. out:
  2006. return err;
  2007. }
  2008. /*
  2009. * Description:
  2010. * Get RX driver info size. RX driver info is a small memory space between
  2011. * scriptor and RX payload.
  2012. *
  2013. * +-------------------------+
  2014. * | RX descriptor |
  2015. * | usually 24 bytes |
  2016. * +-------------------------+
  2017. * | RX driver info |
  2018. * | depends on driver cfg |
  2019. * +-------------------------+
  2020. * | RX paylad |
  2021. * | |
  2022. * +-------------------------+
  2023. *
  2024. * Parameter:
  2025. * d pointer to struct dvobj_priv of driver
  2026. * sz rx driver info size in bytes.
  2027. *
  2028. * Rteurn:
  2029. * 0 Success
  2030. * other Fail
  2031. */
  2032. int rtw_halmac_get_drv_info_sz(struct dvobj_priv *d, u8 *sz)
  2033. {
  2034. HALMAC_RET_STATUS status;
  2035. PHALMAC_ADAPTER halmac = dvobj_to_halmac(d);
  2036. PHALMAC_API api = HALMAC_GET_API(halmac);
  2037. u8 dw = 0;
  2038. status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
  2039. if (status != HALMAC_RET_SUCCESS)
  2040. return -1;
  2041. *sz = dw * 8;
  2042. return 0;
  2043. }
  2044. int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *dvobj, u16 *drv_pg)
  2045. {
  2046. HALMAC_RET_STATUS status;
  2047. PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
  2048. PHALMAC_API api = HALMAC_GET_API(halmac);
  2049. status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, drv_pg);
  2050. if (status != HALMAC_RET_SUCCESS)
  2051. return -1;
  2052. return 0;
  2053. }
  2054. int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
  2055. {
  2056. HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
  2057. PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
  2058. PHALMAC_API api = HALMAC_GET_API(halmac);
  2059. status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
  2060. if (status != HALMAC_RET_SUCCESS)
  2061. return -1;
  2062. return 0;
  2063. }
  2064. /*
  2065. * Description
  2066. * Fill following spec info from HALMAC API:
  2067. * sec_cam_ent_num
  2068. *
  2069. * Return
  2070. * 0 Success
  2071. * others Fail
  2072. */
  2073. int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
  2074. {
  2075. HALMAC_RET_STATUS status;
  2076. PHALMAC_ADAPTER halmac;
  2077. PHALMAC_API api;
  2078. u8 cam = 0; /* Security Cam Entry Number */
  2079. halmac = dvobj_to_halmac(dvobj);
  2080. api = HALMAC_GET_API(halmac);
  2081. /* Prepare data from HALMAC */
  2082. status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
  2083. if (status != HALMAC_RET_SUCCESS)
  2084. return -1;
  2085. /* Fill data to hal_spec_t */
  2086. spec->sec_cam_ent_num = cam;
  2087. return 0;
  2088. }
  2089. int rtw_halmac_p2pps(struct dvobj_priv *dvobj, PHAL_P2P_PS_PARA pp2p_ps_para)
  2090. {
  2091. HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
  2092. PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
  2093. PHALMAC_API api = HALMAC_GET_API(halmac);
  2094. HALMAC_P2PPS halmac_p2p_ps;
  2095. (&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
  2096. (&halmac_p2p_ps)->role = pp2p_ps_para->role;
  2097. (&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
  2098. (&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
  2099. (&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
  2100. (&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
  2101. (&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
  2102. (&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
  2103. (&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
  2104. (&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
  2105. (&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
  2106. (&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
  2107. (&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
  2108. (&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
  2109. (&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
  2110. status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
  2111. if (status != HALMAC_RET_SUCCESS)
  2112. return -1;
  2113. return 0;
  2114. }
  2115. #ifdef CONFIG_SDIO_HCI
  2116. /*
  2117. * Description:
  2118. * Update queue allocated page number to driver
  2119. *
  2120. * Parameter:
  2121. * d pointer to struct dvobj_priv of driver
  2122. *
  2123. * Rteurn:
  2124. * 0 Success, "page" is valid.
  2125. * others Fail, "page" is invalid.
  2126. */
  2127. int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
  2128. {
  2129. PADAPTER adapter;
  2130. struct halmacpriv *hmpriv;
  2131. PHALMAC_ADAPTER halmac;
  2132. PHALMAC_API api;
  2133. HALMAC_RQPN_MAP rqpn;
  2134. HALMAC_DMA_MAPPING dmaqueue;
  2135. HALMAC_TXFF_ALLOCATION fifosize;
  2136. HALMAC_RET_STATUS status;
  2137. u8 i;
  2138. adapter = dvobj_get_primary_adapter(d);
  2139. hmpriv = &d->hmpriv;
  2140. halmac = dvobj_to_halmac(d);
  2141. api = HALMAC_GET_API(halmac);
  2142. _rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
  2143. _rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
  2144. status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
  2145. if (status != HALMAC_RET_SUCCESS)
  2146. return -1;
  2147. status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
  2148. if (status != HALMAC_RET_SUCCESS)
  2149. return -1;
  2150. for (i = 0; i < HW_QUEUE_ENTRY; i++) {
  2151. hmpriv->txpage[i] = 0;
  2152. /* Driver index mapping to HALMAC DMA queue */
  2153. dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
  2154. switch (i) {
  2155. case VO_QUEUE_INX:
  2156. dmaqueue = rqpn.dma_map_vo;
  2157. break;
  2158. case VI_QUEUE_INX:
  2159. dmaqueue = rqpn.dma_map_vi;
  2160. break;
  2161. case BE_QUEUE_INX:
  2162. dmaqueue = rqpn.dma_map_be;
  2163. break;
  2164. case BK_QUEUE_INX:
  2165. dmaqueue = rqpn.dma_map_bk;
  2166. break;
  2167. case MGT_QUEUE_INX:
  2168. dmaqueue = rqpn.dma_map_mg;
  2169. break;
  2170. case HIGH_QUEUE_INX:
  2171. dmaqueue = rqpn.dma_map_hi;
  2172. break;
  2173. case BCN_QUEUE_INX:
  2174. case TXCMD_QUEUE_INX:
  2175. /* Unlimited */
  2176. hmpriv->txpage[i] = 0xFFFF;
  2177. continue;
  2178. }
  2179. switch (dmaqueue) {
  2180. case HALMAC_DMA_MAPPING_EXTRA:
  2181. hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
  2182. break;
  2183. case HALMAC_DMA_MAPPING_LOW:
  2184. hmpriv->txpage[i] = fifosize.low_queue_pg_num;
  2185. break;
  2186. case HALMAC_DMA_MAPPING_NORMAL:
  2187. hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
  2188. break;
  2189. case HALMAC_DMA_MAPPING_HIGH:
  2190. hmpriv->txpage[i] = fifosize.high_queue_pg_num;
  2191. break;
  2192. case HALMAC_DMA_MAPPING_UNDEFINE:
  2193. break;
  2194. }
  2195. hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
  2196. }
  2197. return 0;
  2198. }
  2199. /*
  2200. * Description:
  2201. * Get specific queue allocated page number
  2202. *
  2203. * Parameter:
  2204. * d pointer to struct dvobj_priv of driver
  2205. * queue target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
  2206. * page return allocated page number
  2207. *
  2208. * Rteurn:
  2209. * 0 Success, "page" is valid.
  2210. * others Fail, "page" is invalid.
  2211. */
  2212. int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
  2213. {
  2214. *page = 0;
  2215. if (queue < HW_QUEUE_ENTRY)
  2216. *page = d->hmpriv.txpage[queue];
  2217. return 0;
  2218. }
  2219. /*
  2220. * Return:
  2221. * address for SDIO command
  2222. */
  2223. u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
  2224. {
  2225. PHALMAC_ADAPTER mac;
  2226. PHALMAC_API api;
  2227. HALMAC_RET_STATUS status;
  2228. u32 addr;
  2229. mac = dvobj_to_halmac(d);
  2230. api = HALMAC_GET_API(mac);
  2231. status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
  2232. if (HALMAC_RET_SUCCESS != status)
  2233. return 0;
  2234. return addr;
  2235. }
  2236. int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
  2237. {
  2238. PHALMAC_ADAPTER mac;
  2239. PHALMAC_API api;
  2240. HALMAC_RET_STATUS status;
  2241. mac = dvobj_to_halmac(d);
  2242. api = HALMAC_GET_API(mac);
  2243. status = api->halmac_tx_allowed_sdio(mac, buf, size);
  2244. if (HALMAC_RET_SUCCESS != status)
  2245. return -1;
  2246. return 0;
  2247. }
  2248. u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
  2249. {
  2250. u8 id;
  2251. #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX 0x0E000
  2252. #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a) (RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
  2253. id = *seq;
  2254. (*seq)++;
  2255. return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
  2256. }
  2257. #endif /* CONFIG_SDIO_HCI */
  2258. #ifdef CONFIG_USB_HCI
  2259. u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
  2260. {
  2261. PHALMAC_ADAPTER mac;
  2262. PHALMAC_API api;
  2263. HALMAC_RET_STATUS status;
  2264. u8 bulkout_id;
  2265. mac = dvobj_to_halmac(d);
  2266. api = HALMAC_GET_API(mac);
  2267. status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
  2268. if (HALMAC_RET_SUCCESS != status)
  2269. return 0;
  2270. return bulkout_id;
  2271. }
  2272. static inline HALMAC_USB_MODE _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
  2273. {
  2274. HALMAC_USB_MODE halmac_usb_mode = HALMAC_USB_MODE_U2;
  2275. switch (usb_mode) {
  2276. case RTW_USB_SPEED_2:
  2277. halmac_usb_mode = HALMAC_USB_MODE_U2;
  2278. break;
  2279. case RTW_USB_SPEED_3:
  2280. halmac_usb_mode = HALMAC_USB_MODE_U3;
  2281. break;
  2282. default:
  2283. halmac_usb_mode = HALMAC_USB_MODE_U2;
  2284. break;
  2285. }
  2286. return halmac_usb_mode;
  2287. }
  2288. u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
  2289. {
  2290. PHALMAC_ADAPTER mac;
  2291. PHALMAC_API api;
  2292. HALMAC_RET_STATUS status;
  2293. PADAPTER adapter;
  2294. HALMAC_USB_MODE halmac_usb_mode;
  2295. adapter = dvobj_get_primary_adapter(d);
  2296. mac = dvobj_to_halmac(d);
  2297. api = HALMAC_GET_API(mac);
  2298. halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
  2299. status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
  2300. if (HALMAC_RET_SUCCESS != status)
  2301. return _FAIL;
  2302. return _SUCCESS;
  2303. }
  2304. #endif /* CONFIG_USB_HCI */