rtw_pwrctrl.c 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2012 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 _RTW_PWRCTRL_C_
  21. #include <drv_types.h>
  22. #include <hal_data.h>
  23. #include <hal_com_h2c.h>
  24. int rtw_fw_ps_state(PADAPTER padapter)
  25. {
  26. struct dvobj_priv *psdpriv = padapter->dvobj;
  27. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  28. int ret = _FAIL, dont_care = 0;
  29. u16 fw_ps_state = 0;
  30. u32 start_time;
  31. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  32. struct registry_priv *registry_par = &padapter->registrypriv;
  33. if (registry_par->check_fw_ps != 1)
  34. return _SUCCESS;
  35. _enter_pwrlock(&pwrpriv->check_32k_lock);
  36. if (RTW_CANNOT_RUN(padapter)) {
  37. RTW_INFO("%s: bSurpriseRemoved=%s , hw_init_completed=%d, bDriverStopped=%s\n", __func__
  38. , rtw_is_surprise_removed(padapter) ? "True" : "False"
  39. , rtw_get_hw_init_completed(padapter)
  40. , rtw_is_drv_stopped(padapter) ? "True" : "False");
  41. goto exit_fw_ps_state;
  42. }
  43. rtw_hal_set_hwreg(padapter, HW_VAR_SET_REQ_FW_PS, (u8 *)&dont_care);
  44. {
  45. /* 4. if 0x88[7]=1, driver set cmd to leave LPS/IPS. */
  46. /* Else, hw will keep in active mode. */
  47. /* debug info: */
  48. /* 0x88[7] = 32kpermission, */
  49. /* 0x88[6:0] = current_ps_state */
  50. /* 0x89[7:0] = last_rpwm */
  51. rtw_hal_get_hwreg(padapter, HW_VAR_FW_PS_STATE, (u8 *)&fw_ps_state);
  52. if ((fw_ps_state & 0x80) == 0)
  53. ret = _SUCCESS;
  54. else {
  55. pdbgpriv->dbg_poll_fail_cnt++;
  56. RTW_INFO("%s: fw_ps_state=%04x\n", __FUNCTION__, fw_ps_state);
  57. }
  58. }
  59. exit_fw_ps_state:
  60. _exit_pwrlock(&pwrpriv->check_32k_lock);
  61. return ret;
  62. }
  63. #ifdef CONFIG_IPS
  64. void _ips_enter(_adapter *padapter)
  65. {
  66. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  67. pwrpriv->bips_processing = _TRUE;
  68. /* syn ips_mode with request */
  69. pwrpriv->ips_mode = pwrpriv->ips_mode_req;
  70. pwrpriv->ips_enter_cnts++;
  71. RTW_INFO("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
  72. if (rf_off == pwrpriv->change_rfpwrstate) {
  73. pwrpriv->bpower_saving = _TRUE;
  74. RTW_PRINT("nolinked power save enter\n");
  75. if (pwrpriv->ips_mode == IPS_LEVEL_2)
  76. pwrpriv->bkeepfwalive = _TRUE;
  77. rtw_ips_pwr_down(padapter);
  78. pwrpriv->rf_pwrstate = rf_off;
  79. }
  80. pwrpriv->bips_processing = _FALSE;
  81. }
  82. void ips_enter(_adapter *padapter)
  83. {
  84. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  85. #ifdef CONFIG_BT_COEXIST
  86. rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
  87. #endif /* CONFIG_BT_COEXIST */
  88. _enter_pwrlock(&pwrpriv->lock);
  89. _ips_enter(padapter);
  90. _exit_pwrlock(&pwrpriv->lock);
  91. }
  92. int _ips_leave(_adapter *padapter)
  93. {
  94. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  95. int result = _SUCCESS;
  96. if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
  97. pwrpriv->bips_processing = _TRUE;
  98. pwrpriv->change_rfpwrstate = rf_on;
  99. pwrpriv->ips_leave_cnts++;
  100. RTW_INFO("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
  101. result = rtw_ips_pwr_up(padapter);
  102. if (result == _SUCCESS)
  103. pwrpriv->rf_pwrstate = rf_on;
  104. RTW_PRINT("nolinked power save leave\n");
  105. RTW_INFO("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
  106. pwrpriv->bips_processing = _FALSE;
  107. pwrpriv->bkeepfwalive = _FALSE;
  108. pwrpriv->bpower_saving = _FALSE;
  109. }
  110. return result;
  111. }
  112. int ips_leave(_adapter *padapter)
  113. {
  114. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  115. struct dvobj_priv *psdpriv = padapter->dvobj;
  116. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  117. int ret;
  118. if (!is_primary_adapter(padapter))
  119. return _SUCCESS;
  120. _enter_pwrlock(&pwrpriv->lock);
  121. ret = _ips_leave(padapter);
  122. #ifdef DBG_CHECK_FW_PS_STATE
  123. if (rtw_fw_ps_state(padapter) == _FAIL) {
  124. RTW_INFO("ips leave doesn't leave 32k\n");
  125. pdbgpriv->dbg_leave_ips_fail_cnt++;
  126. }
  127. #endif /* DBG_CHECK_FW_PS_STATE */
  128. _exit_pwrlock(&pwrpriv->lock);
  129. if (_SUCCESS == ret)
  130. odm_dm_reset(&GET_HAL_DATA(padapter)->odmpriv);
  131. #ifdef CONFIG_BT_COEXIST
  132. if (_SUCCESS == ret)
  133. rtw_btcoex_IpsNotify(padapter, IPS_NONE);
  134. #endif /* CONFIG_BT_COEXIST */
  135. return ret;
  136. }
  137. #endif /* CONFIG_IPS */
  138. #ifdef CONFIG_AUTOSUSPEND
  139. extern void autosuspend_enter(_adapter *padapter);
  140. extern int autoresume_enter(_adapter *padapter);
  141. #endif
  142. #ifdef SUPPORT_HW_RFOFF_DETECTED
  143. int rtw_hw_suspend(_adapter *padapter);
  144. int rtw_hw_resume(_adapter *padapter);
  145. #endif
  146. bool rtw_pwr_unassociated_idle(_adapter *adapter)
  147. {
  148. u8 i;
  149. _adapter *iface;
  150. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  151. struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
  152. struct mlme_priv *pmlmepriv;
  153. #ifdef CONFIG_P2P
  154. struct wifidirect_info *pwdinfo;
  155. #ifdef CONFIG_IOCTL_CFG80211
  156. struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
  157. #endif
  158. #endif
  159. bool ret = _FALSE;
  160. if (adapter_to_pwrctl(adapter)->bpower_saving == _TRUE) {
  161. /* RTW_INFO("%s: already in LPS or IPS mode\n", __func__); */
  162. goto exit;
  163. }
  164. if (adapter_to_pwrctl(adapter)->ips_deny_time >= rtw_get_current_time()) {
  165. /* RTW_INFO("%s ips_deny_time\n", __func__); */
  166. goto exit;
  167. }
  168. for (i = 0; i < dvobj->iface_nums; i++) {
  169. iface = dvobj->padapters[i];
  170. if ((iface) && rtw_is_adapter_up(iface)) {
  171. pmlmepriv = &(iface->mlmepriv);
  172. #ifdef CONFIG_P2P
  173. pwdinfo = &(iface->wdinfo);
  174. #ifdef CONFIG_IOCTL_CFG80211
  175. pcfg80211_wdinfo = &iface->cfg80211_wdinfo;
  176. #endif
  177. #endif
  178. if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR)
  179. || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
  180. || check_fwstate(pmlmepriv, WIFI_AP_STATE)
  181. || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
  182. #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
  183. || rtw_cfg80211_get_is_roch(iface) == _TRUE
  184. #elif defined(CONFIG_P2P)
  185. || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)
  186. || rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)
  187. #endif
  188. #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
  189. || rtw_get_passing_time_ms(pcfg80211_wdinfo->last_ro_ch_time) < 3000
  190. #endif
  191. )
  192. goto exit;
  193. }
  194. }
  195. #if (MP_DRIVER == 1)
  196. if (adapter->registrypriv.mp_mode == 1)
  197. goto exit;
  198. #endif
  199. #ifdef CONFIG_INTEL_PROXIM
  200. if (adapter->proximity.proxim_on == _TRUE)
  201. return;
  202. #endif
  203. if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
  204. pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
  205. RTW_PRINT("There are some pkts to transmit\n");
  206. RTW_PRINT("free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
  207. pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
  208. goto exit;
  209. }
  210. ret = _TRUE;
  211. exit:
  212. return ret;
  213. }
  214. /*
  215. * ATTENTION:
  216. * rtw_ps_processor() doesn't handle LPS.
  217. */
  218. void rtw_ps_processor(_adapter *padapter)
  219. {
  220. #ifdef CONFIG_P2P
  221. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  222. #endif /* CONFIG_P2P */
  223. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  224. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  225. struct dvobj_priv *psdpriv = padapter->dvobj;
  226. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  227. #ifdef SUPPORT_HW_RFOFF_DETECTED
  228. rt_rf_power_state rfpwrstate;
  229. #endif /* SUPPORT_HW_RFOFF_DETECTED */
  230. u32 ps_deny = 0;
  231. _enter_pwrlock(&adapter_to_pwrctl(padapter)->lock);
  232. ps_deny = rtw_ps_deny_get(padapter);
  233. _exit_pwrlock(&adapter_to_pwrctl(padapter)->lock);
  234. if (ps_deny != 0) {
  235. RTW_INFO(FUNC_ADPT_FMT ": ps_deny=0x%08X, skip power save!\n",
  236. FUNC_ADPT_ARG(padapter), ps_deny);
  237. goto exit;
  238. }
  239. if (pwrpriv->bInSuspend == _TRUE) { /* system suspend or autosuspend */
  240. pdbgpriv->dbg_ps_insuspend_cnt++;
  241. RTW_INFO("%s, pwrpriv->bInSuspend == _TRUE ignore this process\n", __FUNCTION__);
  242. return;
  243. }
  244. pwrpriv->ps_processing = _TRUE;
  245. #ifdef SUPPORT_HW_RFOFF_DETECTED
  246. if (pwrpriv->bips_processing == _TRUE)
  247. goto exit;
  248. /* RTW_INFO("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca)); */
  249. if (pwrpriv->bHWPwrPindetect) {
  250. #ifdef CONFIG_AUTOSUSPEND
  251. if (padapter->registrypriv.usbss_enable) {
  252. if (pwrpriv->rf_pwrstate == rf_on) {
  253. if (padapter->net_closed == _TRUE)
  254. pwrpriv->ps_flag = _TRUE;
  255. rfpwrstate = RfOnOffDetect(padapter);
  256. RTW_INFO("@@@@- #1 %s==> rfstate:%s\n", __FUNCTION__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off");
  257. if (rfpwrstate != pwrpriv->rf_pwrstate) {
  258. if (rfpwrstate == rf_off) {
  259. pwrpriv->change_rfpwrstate = rf_off;
  260. pwrpriv->bkeepfwalive = _TRUE;
  261. pwrpriv->brfoffbyhw = _TRUE;
  262. autosuspend_enter(padapter);
  263. }
  264. }
  265. }
  266. } else
  267. #endif /* CONFIG_AUTOSUSPEND */
  268. {
  269. rfpwrstate = RfOnOffDetect(padapter);
  270. RTW_INFO("@@@@- #2 %s==> rfstate:%s\n", __FUNCTION__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off");
  271. if (rfpwrstate != pwrpriv->rf_pwrstate) {
  272. if (rfpwrstate == rf_off) {
  273. pwrpriv->change_rfpwrstate = rf_off;
  274. pwrpriv->brfoffbyhw = _TRUE;
  275. rtw_hw_suspend(padapter);
  276. } else {
  277. pwrpriv->change_rfpwrstate = rf_on;
  278. rtw_hw_resume(padapter);
  279. }
  280. RTW_INFO("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on");
  281. }
  282. }
  283. pwrpriv->pwr_state_check_cnts++;
  284. }
  285. #endif /* SUPPORT_HW_RFOFF_DETECTED */
  286. if (pwrpriv->ips_mode_req == IPS_NONE)
  287. goto exit;
  288. if (rtw_pwr_unassociated_idle(padapter) == _FALSE)
  289. goto exit;
  290. if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) {
  291. RTW_INFO("==>%s .fw_state(%x)\n", __FUNCTION__, get_fwstate(pmlmepriv));
  292. #if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND)
  293. #else
  294. pwrpriv->change_rfpwrstate = rf_off;
  295. #endif
  296. #ifdef CONFIG_AUTOSUSPEND
  297. if (padapter->registrypriv.usbss_enable) {
  298. if (pwrpriv->bHWPwrPindetect)
  299. pwrpriv->bkeepfwalive = _TRUE;
  300. if (padapter->net_closed == _TRUE)
  301. pwrpriv->ps_flag = _TRUE;
  302. #if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND)
  303. if (_TRUE == pwrpriv->bInternalAutoSuspend)
  304. RTW_INFO("<==%s .pwrpriv->bInternalAutoSuspend)(%x)\n", __FUNCTION__, pwrpriv->bInternalAutoSuspend);
  305. else {
  306. pwrpriv->change_rfpwrstate = rf_off;
  307. RTW_INFO("<==%s .pwrpriv->bInternalAutoSuspend)(%x) call autosuspend_enter\n", __FUNCTION__, pwrpriv->bInternalAutoSuspend);
  308. autosuspend_enter(padapter);
  309. }
  310. #else
  311. autosuspend_enter(padapter);
  312. #endif /* if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) */
  313. } else if (pwrpriv->bHWPwrPindetect) {
  314. } else
  315. #endif /* CONFIG_AUTOSUSPEND */
  316. {
  317. #if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND)
  318. pwrpriv->change_rfpwrstate = rf_off;
  319. #endif /* defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) */
  320. #ifdef CONFIG_IPS
  321. ips_enter(padapter);
  322. #endif
  323. }
  324. }
  325. exit:
  326. #ifndef CONFIG_IPS_CHECK_IN_WD
  327. rtw_set_pwr_state_check_timer(pwrpriv);
  328. #endif
  329. pwrpriv->ps_processing = _FALSE;
  330. return;
  331. }
  332. void pwr_state_check_handler(struct timer_list *t)
  333. {
  334. struct pwrctrl_priv *pwrpriv = from_timer(pwrpriv, t, pwr_state_check_timer);
  335. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  336. _adapter *padapter = dvobj_get_primary_adapter(dvobj);
  337. rtw_ps_cmd(padapter);
  338. }
  339. #ifdef CONFIG_LPS
  340. void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets)
  341. {
  342. #ifdef CONFIG_CHECK_LEAVE_LPS
  343. static u32 start_time = 0;
  344. static u32 xmit_cnt = 0;
  345. u8 bLeaveLPS = _FALSE;
  346. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  347. if (tx) { /* from tx */
  348. xmit_cnt += tx_packets;
  349. if (start_time == 0)
  350. start_time = rtw_get_current_time();
  351. if (rtw_get_passing_time_ms(start_time) > 2000) { /* 2 sec == watch dog timer */
  352. if (xmit_cnt > 8) {
  353. if ((adapter_to_pwrctl(padapter)->bLeisurePs)
  354. && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
  355. #ifdef CONFIG_BT_COEXIST
  356. && (rtw_btcoex_IsBtControlLps(padapter) == _FALSE)
  357. #endif
  358. ) {
  359. /* RTW_INFO("leave lps via Tx = %d\n", xmit_cnt); */
  360. bLeaveLPS = _TRUE;
  361. }
  362. }
  363. start_time = rtw_get_current_time();
  364. xmit_cnt = 0;
  365. }
  366. } else { /* from rx path */
  367. if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) {
  368. if ((adapter_to_pwrctl(padapter)->bLeisurePs)
  369. && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE)
  370. #ifdef CONFIG_BT_COEXIST
  371. && (rtw_btcoex_IsBtControlLps(padapter) == _FALSE)
  372. #endif
  373. ) {
  374. /* RTW_INFO("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */
  375. bLeaveLPS = _TRUE;
  376. }
  377. }
  378. }
  379. if (bLeaveLPS) {
  380. /* RTW_INFO("leave lps via %s, Tx = %d, Rx = %d\n", tx?"Tx":"Rx", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */
  381. /* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); */
  382. rtw_lps_ctrl_wk_cmd(padapter, tx ? LPS_CTRL_TX_TRAFFIC_LEAVE : LPS_CTRL_RX_TRAFFIC_LEAVE, tx ? 0 : 1);
  383. }
  384. #endif /* CONFIG_CHECK_LEAVE_LPS */
  385. }
  386. #ifdef CONFIG_LPS_LCLK
  387. u8 rtw_cpwm_polling(_adapter *adapter, u8 cpwm_orig)
  388. {
  389. u8 result = _FAIL;
  390. u8 cpwm_now;
  391. u8 poll_cnt = 0;
  392. u32 start_time;
  393. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
  394. struct debug_priv *pdbgpriv = &(adapter_to_dvobj(adapter)->drv_dbg);
  395. /*RTW_INFO("%s.....\n", __func__);*/
  396. start_time = rtw_get_current_time();
  397. /* polling cpwm */
  398. do {
  399. rtw_msleep_os(1);
  400. poll_cnt++;
  401. cpwm_now = 0;
  402. rtw_hal_get_hwreg(adapter, HW_VAR_CPWM, &cpwm_now);
  403. if ((cpwm_orig ^ cpwm_now) & 0x80) {
  404. pwrpriv->cpwm = PS_STATE_S4;
  405. pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
  406. #ifdef DBG_CHECK_FW_PS_STATE
  407. RTW_INFO("%s: polling cpwm OK! poll_cnt=%d, cpwm_orig=%02x, cpwm_now=%02x , 0x100=0x%x\n"
  408. , __func__, poll_cnt, cpwm_orig, cpwm_now, rtw_read8(adapter, REG_CR));
  409. if (rtw_fw_ps_state(adapter) == _FAIL) {
  410. RTW_INFO("leave 32k but fw state in 32k\n");
  411. pdbgpriv->dbg_rpwm_toogle_cnt++;
  412. }
  413. #endif /* DBG_CHECK_FW_PS_STATE */
  414. result = _SUCCESS;
  415. break;
  416. }
  417. if (rtw_get_passing_time_ms(start_time) > LPS_RPWM_WAIT_MS) {
  418. RTW_ERR("%s: polling cpwm timeout! poll_cnt=%d, cpwm_orig=%02x, cpwm_now=%02x\n"
  419. , __func__, poll_cnt, cpwm_orig, cpwm_now);
  420. #ifdef DBG_CHECK_FW_PS_STATE
  421. if (rtw_fw_ps_state(adapter) == _FAIL) {
  422. RTW_INFO("rpwm timeout and fw ps state in 32k\n");
  423. pdbgpriv->dbg_rpwm_timeout_fail_cnt++;
  424. }
  425. #endif /* DBG_CHECK_FW_PS_STATE */
  426. #ifdef CONFIG_LPS_RPWM_TIMER
  427. _set_timer(&pwrpriv->pwr_rpwm_timer, 1);
  428. #endif /* CONFIG_LPS_RPWM_TIMER */
  429. break;
  430. }
  431. } while (1);
  432. return result;
  433. }
  434. #endif
  435. /*
  436. * Description:
  437. * This function MUST be called under power lock protect
  438. *
  439. * Parameters
  440. * padapter
  441. * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
  442. *
  443. */
  444. void rtw_set_rpwm(PADAPTER padapter, u8 pslv)
  445. {
  446. u8 rpwm;
  447. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  448. #ifdef CONFIG_LPS_LCLK
  449. u8 cpwm_orig;
  450. #endif
  451. struct dvobj_priv *psdpriv = padapter->dvobj;
  452. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  453. pslv = PS_STATE(pslv);
  454. #ifdef CONFIG_LPS_RPWM_TIMER
  455. if (pwrpriv->brpwmtimeout == _TRUE)
  456. RTW_INFO("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __FUNCTION__, pslv);
  457. else
  458. #endif /* CONFIG_LPS_RPWM_TIMER */
  459. {
  460. if ((pwrpriv->rpwm == pslv)
  461. #ifdef CONFIG_LPS_LCLK
  462. || ((pwrpriv->rpwm >= PS_STATE_S2) && (pslv >= PS_STATE_S2))
  463. #endif
  464. || (pwrpriv->lps_level == LPS_NORMAL)
  465. ) {
  466. return;
  467. }
  468. }
  469. if (rtw_is_surprise_removed(padapter) ||
  470. (!rtw_is_hw_init_completed(padapter))) {
  471. pwrpriv->cpwm = PS_STATE_S4;
  472. return;
  473. }
  474. if (rtw_is_drv_stopped(padapter))
  475. if (pslv < PS_STATE_S2)
  476. return;
  477. rpwm = pslv | pwrpriv->tog;
  478. #ifdef CONFIG_LPS_LCLK
  479. /* only when from PS_STATE S0/S1 to S2 and higher needs ACK */
  480. if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
  481. rpwm |= PS_ACK;
  482. #endif
  483. pwrpriv->rpwm = pslv;
  484. #ifdef CONFIG_LPS_LCLK
  485. cpwm_orig = 0;
  486. if (rpwm & PS_ACK)
  487. rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
  488. #endif
  489. #if defined(CONFIG_LPS_RPWM_TIMER) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
  490. if (rpwm & PS_ACK)
  491. _set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
  492. #endif /* CONFIG_LPS_RPWM_TIMER & !CONFIG_DETECT_CPWM_BY_POLLING */
  493. rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
  494. pwrpriv->tog += 0x80;
  495. #ifdef CONFIG_LPS_LCLK
  496. /* No LPS 32K, No Ack */
  497. if (rpwm & PS_ACK) {
  498. #ifdef CONFIG_DETECT_CPWM_BY_POLLING
  499. rtw_cpwm_polling(padapter, cpwm_orig);
  500. #else
  501. #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
  502. if (pwrpriv->wowlan_mode == _TRUE ||
  503. pwrpriv->wowlan_ap_mode == _TRUE ||
  504. pwrpriv->wowlan_p2p_mode == _TRUE)
  505. rtw_cpwm_polling(padapter, cpwm_orig);
  506. #endif /*#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)*/
  507. #endif /*#ifdef CONFIG_DETECT_CPWM_BY_POLLING*/
  508. } else
  509. #endif /* CONFIG_LPS_LCLK */
  510. {
  511. pwrpriv->cpwm = pslv;
  512. }
  513. }
  514. u8 PS_RDY_CHECK(_adapter *padapter)
  515. {
  516. u32 curr_time, delta_time;
  517. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  518. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  519. #ifdef CONFIG_P2P
  520. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  521. #ifdef CONFIG_IOCTL_CFG80211
  522. struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
  523. #endif /* CONFIG_IOCTL_CFG80211 */
  524. #endif /* CONFIG_P2P */
  525. #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
  526. if (_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
  527. return _TRUE;
  528. else if (_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode)
  529. return _TRUE;
  530. else if (_TRUE == pwrpriv->bInSuspend)
  531. return _FALSE;
  532. #else
  533. if (_TRUE == pwrpriv->bInSuspend)
  534. return _FALSE;
  535. #endif
  536. curr_time = rtw_get_current_time();
  537. delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
  538. if (delta_time < LPS_DELAY_TIME)
  539. return _FALSE;
  540. if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)
  541. || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
  542. || check_fwstate(pmlmepriv, WIFI_AP_STATE)
  543. || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
  544. #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
  545. || rtw_cfg80211_get_is_roch(padapter) == _TRUE
  546. #endif
  547. || rtw_is_scan_deny(padapter)
  548. #ifdef CONFIG_TDLS
  549. /* TDLS link is established. */
  550. || (padapter->tdlsinfo.link_established == _TRUE)
  551. #endif /* CONFIG_TDLS */
  552. )
  553. return _FALSE;
  554. if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == _FALSE)) {
  555. RTW_INFO("Group handshake still in progress !!!\n");
  556. return _FALSE;
  557. }
  558. #ifdef CONFIG_IOCTL_CFG80211
  559. if (!rtw_cfg80211_pwr_mgmt(padapter))
  560. return _FALSE;
  561. #endif
  562. return _TRUE;
  563. }
  564. #if defined(CONFIG_FWLPS_IN_IPS)
  565. void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable)
  566. {
  567. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  568. int cnt = 0;
  569. u32 start_time;
  570. u8 val8 = 0;
  571. u8 cpwm_orig = 0, cpwm_now = 0;
  572. u8 parm[H2C_INACTIVE_PS_LEN] = {0};
  573. if (padapter->netif_up == _FALSE) {
  574. RTW_INFO("%s: ERROR, netif is down\n", __func__);
  575. return;
  576. }
  577. /* u8 cmd_param; */ /* BIT0:enable, BIT1:NoConnect32k */
  578. if (enable) {
  579. #ifdef CONFIG_BT_COEXIST
  580. rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
  581. #endif
  582. /* Enter IPS */
  583. RTW_INFO("%s: issue H2C to FW when entering IPS\n", __func__);
  584. parm[0] = 0x1;/* suggest by Isaac.Hsu*/
  585. #ifdef CONFIG_PNO_SUPPORT
  586. if (pwrpriv->pno_inited) {
  587. parm[1] = pwrpriv->pnlo_info->fast_scan_iterations;
  588. parm[2] = pwrpriv->pnlo_info->slow_scan_period;
  589. }
  590. #endif
  591. rtw_hal_fill_h2c_cmd(padapter, /* H2C_FWLPS_IN_IPS_, */
  592. H2C_INACTIVE_PS_,
  593. H2C_INACTIVE_PS_LEN, parm);
  594. /* poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc=0 means H2C done by FW. */
  595. do {
  596. val8 = rtw_read8(padapter, REG_HMETFR);
  597. cnt++;
  598. RTW_INFO("%s polling REG_HMETFR=0x%x, cnt=%d\n",
  599. __func__, val8, cnt);
  600. rtw_mdelay_os(10);
  601. } while (cnt < 100 && (val8 != 0));
  602. #ifdef CONFIG_LPS_LCLK
  603. /* H2C done, enter 32k */
  604. if (val8 == 0) {
  605. /* ser rpwm to enter 32k */
  606. rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
  607. RTW_INFO("%s: read rpwm=%02x\n", __FUNCTION__, val8);
  608. val8 += 0x80;
  609. val8 |= BIT(0);
  610. rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
  611. RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
  612. adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
  613. cnt = val8 = 0;
  614. if (parm[1] == 0 || parm[2] == 0) {
  615. do {
  616. val8 = rtw_read8(padapter, REG_CR);
  617. cnt++;
  618. RTW_INFO("%s polling 0x100=0x%x, cnt=%d\n",
  619. __func__, val8, cnt);
  620. RTW_INFO("%s 0x08:%02x, 0x03:%02x\n",
  621. __func__,
  622. rtw_read8(padapter, 0x08),
  623. rtw_read8(padapter, 0x03));
  624. rtw_mdelay_os(10);
  625. } while (cnt < 20 && (val8 != 0xEA));
  626. }
  627. }
  628. #endif
  629. } else {
  630. /* Leave IPS */
  631. RTW_INFO("%s: Leaving IPS in FWLPS state\n", __func__);
  632. #ifdef CONFIG_LPS_LCLK
  633. /* for polling cpwm */
  634. cpwm_orig = 0;
  635. rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
  636. /* ser rpwm */
  637. rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
  638. val8 += 0x80;
  639. val8 |= BIT(6);
  640. rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
  641. RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
  642. adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
  643. /* do polling cpwm */
  644. start_time = rtw_get_current_time();
  645. do {
  646. rtw_mdelay_os(1);
  647. rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
  648. if ((cpwm_orig ^ cpwm_now) & 0x80)
  649. break;
  650. if (rtw_get_passing_time_ms(start_time) > 100) {
  651. RTW_INFO("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__);
  652. break;
  653. }
  654. } while (1);
  655. #endif
  656. parm[0] = 0x0;
  657. parm[1] = 0x0;
  658. parm[2] = 0x0;
  659. rtw_hal_fill_h2c_cmd(padapter, H2C_INACTIVE_PS_,
  660. H2C_INACTIVE_PS_LEN, parm);
  661. #ifdef CONFIG_BT_COEXIST
  662. rtw_btcoex_IpsNotify(padapter, IPS_NONE);
  663. #endif
  664. }
  665. }
  666. #endif /* CONFIG_PNO_SUPPORT */
  667. void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
  668. {
  669. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  670. struct dvobj_priv *psdpriv = padapter->dvobj;
  671. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  672. #ifdef CONFIG_P2P
  673. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  674. #endif /* CONFIG_P2P */
  675. #ifdef CONFIG_TDLS
  676. struct sta_priv *pstapriv = &padapter->stapriv;
  677. _irqL irqL;
  678. int i, j;
  679. _list *plist, *phead;
  680. struct sta_info *ptdls_sta;
  681. #endif /* CONFIG_TDLS */
  682. #ifdef CONFIG_LPS_PG
  683. u8 lps_pg_hdl_id = 0;
  684. #endif
  685. if (ps_mode > PM_Card_Disable) {
  686. return;
  687. }
  688. if (pwrpriv->pwr_mode == ps_mode) {
  689. if (PS_MODE_ACTIVE == ps_mode)
  690. return;
  691. #ifndef CONFIG_BT_COEXIST
  692. if ((pwrpriv->smart_ps == smart_ps) &&
  693. (pwrpriv->bcn_ant_mode == bcn_ant_mode))
  694. return;
  695. #endif /* !CONFIG_BT_COEXIST */
  696. }
  697. #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
  698. if (PS_MODE_ACTIVE != ps_mode) {
  699. rtw_set_ps_rsvd_page(padapter);
  700. rtw_set_default_port_id(padapter);
  701. }
  702. #endif
  703. #ifdef CONFIG_LPS_PG
  704. if ((PS_MODE_ACTIVE != ps_mode) && (pwrpriv->blpspg_info_up)) {
  705. /*rtw_hal_set_lps_pg_info(padapter);*/
  706. lps_pg_hdl_id = LPS_PG_INFO_CFG;
  707. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
  708. }
  709. #endif
  710. #ifdef CONFIG_LPS_LCLK
  711. _enter_pwrlock(&pwrpriv->lock);
  712. #endif
  713. /* if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
  714. if (ps_mode == PS_MODE_ACTIVE) {
  715. if (1
  716. #ifdef CONFIG_BT_COEXIST
  717. && (((rtw_btcoex_IsBtControlLps(padapter) == _FALSE)
  718. #ifdef CONFIG_P2P_PS
  719. && (pwdinfo->opp_ps == 0)
  720. #endif /* CONFIG_P2P_PS */
  721. )
  722. || ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
  723. && (rtw_btcoex_IsLpsOn(padapter) == _FALSE))
  724. )
  725. #else /* !CONFIG_BT_COEXIST */
  726. #ifdef CONFIG_P2P_PS
  727. && (pwdinfo->opp_ps == 0)
  728. #endif /* CONFIG_P2P_PS */
  729. #endif /* !CONFIG_BT_COEXIST */
  730. ) {
  731. RTW_INFO(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n",
  732. FUNC_ADPT_ARG(padapter), msg);
  733. if (pwrpriv->lps_leave_cnts < UINT_MAX)
  734. pwrpriv->lps_leave_cnts++;
  735. else
  736. pwrpriv->lps_leave_cnts = 0;
  737. #ifdef CONFIG_TDLS
  738. for (i = 0; i < NUM_STA; i++) {
  739. phead = &(pstapriv->sta_hash[i]);
  740. plist = get_next(phead);
  741. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
  742. ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
  743. if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
  744. issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0);
  745. plist = get_next(plist);
  746. }
  747. }
  748. #endif /* CONFIG_TDLS */
  749. pwrpriv->pwr_mode = ps_mode;
  750. rtw_set_rpwm(padapter, PS_STATE_S4);
  751. #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN)
  752. if (pwrpriv->wowlan_mode == _TRUE ||
  753. pwrpriv->wowlan_ap_mode == _TRUE ||
  754. pwrpriv->wowlan_p2p_mode == _TRUE) {
  755. u32 start_time, delay_ms;
  756. u8 val8;
  757. delay_ms = 20;
  758. start_time = rtw_get_current_time();
  759. do {
  760. rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8);
  761. if (!(val8 & BIT(4))) { /* 0x08 bit4 =1 --> in 32k, bit4 = 0 --> leave 32k */
  762. pwrpriv->cpwm = PS_STATE_S4;
  763. break;
  764. }
  765. if (rtw_get_passing_time_ms(start_time) > delay_ms) {
  766. RTW_INFO("%s: Wait for FW 32K leave more than %u ms!!!\n",
  767. __FUNCTION__, delay_ms);
  768. pdbgpriv->dbg_wow_leave_ps_fail_cnt++;
  769. break;
  770. }
  771. rtw_usleep_os(100);
  772. } while (1);
  773. }
  774. #endif
  775. #ifdef CONFIG_LPS_PG
  776. if (pwrpriv->lps_level == LPS_PG) {
  777. lps_pg_hdl_id = LPS_PG_REDLEMEM;
  778. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
  779. }
  780. #endif
  781. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
  782. #ifdef CONFIG_LPS_PG
  783. if (pwrpriv->lps_level == LPS_PG) {
  784. lps_pg_hdl_id = LPS_PG_RESEND_H2C;
  785. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
  786. }
  787. #endif
  788. #ifdef CONFIG_LPS_POFF
  789. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_POFF_SET_MODE,
  790. (u8 *)(&ps_mode));
  791. #endif /*CONFIG_LPS_POFF*/
  792. pwrpriv->bFwCurrentInPSMode = _FALSE;
  793. #ifdef CONFIG_BT_COEXIST
  794. rtw_btcoex_LpsNotify(padapter, ps_mode);
  795. #endif /* CONFIG_BT_COEXIST */
  796. }
  797. } else {
  798. if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
  799. #ifdef CONFIG_BT_COEXIST
  800. || ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
  801. && (rtw_btcoex_IsLpsOn(padapter) == _TRUE))
  802. #endif
  803. #ifdef CONFIG_P2P_WOWLAN
  804. || (_TRUE == pwrpriv->wowlan_p2p_mode)
  805. #endif /* CONFIG_P2P_WOWLAN */
  806. ) {
  807. u8 pslv;
  808. RTW_INFO(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n",
  809. FUNC_ADPT_ARG(padapter), msg);
  810. if (pwrpriv->lps_enter_cnts < UINT_MAX)
  811. pwrpriv->lps_enter_cnts++;
  812. else
  813. pwrpriv->lps_enter_cnts = 0;
  814. #ifdef CONFIG_TDLS
  815. for (i = 0; i < NUM_STA; i++) {
  816. phead = &(pstapriv->sta_hash[i]);
  817. plist = get_next(phead);
  818. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
  819. ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
  820. if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
  821. issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 0, 0);
  822. plist = get_next(plist);
  823. }
  824. }
  825. #endif /* CONFIG_TDLS */
  826. #ifdef CONFIG_BT_COEXIST
  827. rtw_btcoex_LpsNotify(padapter, ps_mode);
  828. #endif /* CONFIG_BT_COEXIST */
  829. #ifdef CONFIG_LPS_POFF
  830. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_POFF_SET_MODE,
  831. (u8 *)(&ps_mode));
  832. #endif /*CONFIG_LPS_POFF*/
  833. pwrpriv->bFwCurrentInPSMode = _TRUE;
  834. pwrpriv->pwr_mode = ps_mode;
  835. pwrpriv->smart_ps = smart_ps;
  836. pwrpriv->bcn_ant_mode = bcn_ant_mode;
  837. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
  838. #ifdef CONFIG_P2P_PS
  839. /* Set CTWindow after LPS */
  840. if (pwdinfo->opp_ps == 1)
  841. p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
  842. #endif /* CONFIG_P2P_PS */
  843. pslv = PS_STATE_S2;
  844. #ifdef CONFIG_LPS_LCLK
  845. if (pwrpriv->alives == 0)
  846. pslv = PS_STATE_S0;
  847. #endif /* CONFIG_LPS_LCLK */
  848. #ifdef CONFIG_BT_COEXIST
  849. if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE)
  850. && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) {
  851. u8 val8;
  852. val8 = rtw_btcoex_LpsVal(padapter);
  853. if (val8 & BIT(4))
  854. pslv = PS_STATE_S2;
  855. }
  856. #endif /* CONFIG_BT_COEXIST */
  857. rtw_set_rpwm(padapter, pslv);
  858. }
  859. }
  860. #ifdef CONFIG_LPS_LCLK
  861. _exit_pwrlock(&pwrpriv->lock);
  862. #endif
  863. }
  864. /*
  865. * Return:
  866. * 0: Leave OK
  867. * -1: Timeout
  868. * -2: Other error
  869. */
  870. s32 LPS_RF_ON_check(PADAPTER padapter, u32 delay_ms)
  871. {
  872. u32 start_time;
  873. u8 bAwake = _FALSE;
  874. s32 err = 0;
  875. start_time = rtw_get_current_time();
  876. while (1) {
  877. rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
  878. if (_TRUE == bAwake)
  879. break;
  880. if (rtw_is_surprise_removed(padapter)) {
  881. err = -2;
  882. RTW_INFO("%s: device surprise removed!!\n", __FUNCTION__);
  883. break;
  884. }
  885. if (rtw_get_passing_time_ms(start_time) > delay_ms) {
  886. err = -1;
  887. RTW_INFO("%s: Wait for FW LPS leave more than %u ms!!!\n", __FUNCTION__, delay_ms);
  888. break;
  889. }
  890. rtw_usleep_os(100);
  891. }
  892. return err;
  893. }
  894. /*
  895. * Description:
  896. * Enter the leisure power save mode.
  897. * */
  898. void LPS_Enter(PADAPTER padapter, const char *msg)
  899. {
  900. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  901. struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
  902. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  903. int n_assoc_iface = 0;
  904. int i;
  905. char buf[32] = {0};
  906. /* RTW_INFO("+LeisurePSEnter\n"); */
  907. if (_FALSE == padapter->bFWReady)
  908. return;
  909. #ifdef CONFIG_BT_COEXIST
  910. if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
  911. return;
  912. #endif
  913. /* Skip lps enter request if number of assocated adapters is not 1 */
  914. for (i = 0; i < dvobj->iface_nums; i++) {
  915. if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))
  916. n_assoc_iface++;
  917. }
  918. if (n_assoc_iface != 1)
  919. return;
  920. #ifndef CONFIG_FW_MULTI_PORT_SUPPORT
  921. /* Skip lps enter request for adapter not port0 */
  922. if (get_hw_port(padapter) != HW_PORT0)
  923. return;
  924. #endif
  925. for (i = 0; i < dvobj->iface_nums; i++) {
  926. if (PS_RDY_CHECK(dvobj->padapters[i]) == _FALSE)
  927. return;
  928. }
  929. #ifdef CONFIG_P2P_PS
  930. if (padapter->wdinfo.p2p_ps_mode == P2P_PS_NOA) {
  931. return;/* supporting p2p client ps NOA via H2C_8723B_P2P_PS_OFFLOAD */
  932. }
  933. #endif /* CONFIG_P2P_PS */
  934. if (pwrpriv->bLeisurePs) {
  935. /* Idle for a while if we connect to AP a while ago. */
  936. if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
  937. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
  938. sprintf(buf, "WIFI-%s", msg);
  939. pwrpriv->bpower_saving = _TRUE;
  940. rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf);
  941. }
  942. } else
  943. pwrpriv->LpsIdleCount++;
  944. }
  945. /* RTW_INFO("-LeisurePSEnter\n"); */
  946. }
  947. /*
  948. * Description:
  949. * Leave the leisure power save mode.
  950. * */
  951. void LPS_Leave(PADAPTER padapter, const char *msg)
  952. {
  953. #define LPS_LEAVE_TIMEOUT_MS 100
  954. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  955. struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
  956. u32 start_time;
  957. u8 bAwake = _FALSE;
  958. char buf[32] = {0};
  959. struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
  960. /* RTW_INFO("+LeisurePSLeave\n"); */
  961. #ifdef CONFIG_BT_COEXIST
  962. if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
  963. return;
  964. #endif
  965. if (pwrpriv->bLeisurePs) {
  966. if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
  967. sprintf(buf, "WIFI-%s", msg);
  968. rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf);
  969. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
  970. LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS);
  971. }
  972. }
  973. pwrpriv->bpower_saving = _FALSE;
  974. #ifdef DBG_CHECK_FW_PS_STATE
  975. if (rtw_fw_ps_state(padapter) == _FAIL) {
  976. RTW_INFO("leave lps, fw in 32k\n");
  977. pdbgpriv->dbg_leave_lps_fail_cnt++;
  978. }
  979. #endif /* DBG_CHECK_FW_PS_STATE
  980. * RTW_INFO("-LeisurePSLeave\n"); */
  981. }
  982. #endif
  983. void LeaveAllPowerSaveModeDirect(PADAPTER Adapter)
  984. {
  985. PADAPTER pri_padapter = GET_PRIMARY_ADAPTER(Adapter);
  986. struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
  987. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
  988. struct dvobj_priv *psdpriv = Adapter->dvobj;
  989. struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
  990. #ifndef CONFIG_DETECT_CPWM_BY_POLLING
  991. u8 cpwm_orig, cpwm_now;
  992. u32 start_time;
  993. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  994. RTW_INFO("%s.....\n", __FUNCTION__);
  995. if (rtw_is_surprise_removed(Adapter)) {
  996. RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(Adapter));
  997. return;
  998. }
  999. if (rtw_mi_check_status(Adapter, MI_LINKED)) { /*connect*/
  1000. if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
  1001. RTW_INFO("%s: Driver Already Leave LPS\n", __FUNCTION__);
  1002. return;
  1003. }
  1004. #ifdef CONFIG_LPS_LCLK
  1005. _enter_pwrlock(&pwrpriv->lock);
  1006. #ifndef CONFIG_DETECT_CPWM_BY_POLLING
  1007. cpwm_orig = 0;
  1008. rtw_hal_get_hwreg(Adapter, HW_VAR_CPWM, &cpwm_orig);
  1009. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  1010. rtw_set_rpwm(Adapter, PS_STATE_S4);
  1011. #ifndef CONFIG_DETECT_CPWM_BY_POLLING
  1012. start_time = rtw_get_current_time();
  1013. /* polling cpwm */
  1014. do {
  1015. rtw_mdelay_os(1);
  1016. rtw_hal_get_hwreg(Adapter, HW_VAR_CPWM, &cpwm_now);
  1017. if ((cpwm_orig ^ cpwm_now) & 0x80) {
  1018. pwrpriv->cpwm = PS_STATE_S4;
  1019. pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
  1020. #ifdef DBG_CHECK_FW_PS_STATE
  1021. RTW_INFO("%s: polling cpwm OK! cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x\n"
  1022. , __FUNCTION__, cpwm_orig, cpwm_now, rtw_read8(Adapter, REG_CR));
  1023. if (rtw_fw_ps_state(Adapter) == _FAIL) {
  1024. RTW_INFO("%s: leave 32k but fw state in 32k\n", __FUNCTION__);
  1025. pdbgpriv->dbg_rpwm_toogle_cnt++;
  1026. }
  1027. #endif /* DBG_CHECK_FW_PS_STATE */
  1028. break;
  1029. }
  1030. if (rtw_get_passing_time_ms(start_time) > LPS_RPWM_WAIT_MS) {
  1031. RTW_INFO("%s: polling cpwm timeout! cpwm_orig=%02x, cpwm_now=%02x\n", __FUNCTION__, cpwm_orig, cpwm_now);
  1032. #ifdef DBG_CHECK_FW_PS_STATE
  1033. if (rtw_fw_ps_state(Adapter) == _FAIL) {
  1034. RTW_INFO("rpwm timeout and fw ps state in 32k\n");
  1035. pdbgpriv->dbg_rpwm_timeout_fail_cnt++;
  1036. }
  1037. #endif /* DBG_CHECK_FW_PS_STATE */
  1038. break;
  1039. }
  1040. } while (1);
  1041. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  1042. _exit_pwrlock(&pwrpriv->lock);
  1043. #endif
  1044. #ifdef CONFIG_P2P_PS
  1045. p2p_ps_wk_cmd(pri_padapter, P2P_PS_DISABLE, 0);
  1046. #endif /* CONFIG_P2P_PS */
  1047. #ifdef CONFIG_LPS
  1048. rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0);
  1049. #endif
  1050. } else {
  1051. if (pwrpriv->rf_pwrstate == rf_off) {
  1052. #ifdef CONFIG_AUTOSUSPEND
  1053. if (Adapter->registrypriv.usbss_enable) {
  1054. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
  1055. usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev);
  1056. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34))
  1057. adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;/* autosuspend disabled by the user */
  1058. #endif
  1059. } else
  1060. #endif
  1061. {
  1062. #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_RTL8188E)
  1063. #ifdef CONFIG_IPS
  1064. if (_FALSE == ips_leave(pri_padapter))
  1065. RTW_INFO("======> ips_leave fail.............\n");
  1066. #endif
  1067. #endif /* CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) */
  1068. }
  1069. }
  1070. }
  1071. }
  1072. /*
  1073. * Description: Leave all power save mode: LPS, FwLPS, IPS if needed.
  1074. * Move code to function by tynli. 2010.03.26.
  1075. * */
  1076. void LeaveAllPowerSaveMode(IN PADAPTER Adapter)
  1077. {
  1078. struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
  1079. struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
  1080. u8 enqueue = 0;
  1081. int n_assoc_iface = 0;
  1082. int i;
  1083. /* RTW_INFO("%s.....\n",__FUNCTION__); */
  1084. if (_FALSE == Adapter->bup) {
  1085. RTW_INFO(FUNC_ADPT_FMT ": bup=%d Skip!\n",
  1086. FUNC_ADPT_ARG(Adapter), Adapter->bup);
  1087. return;
  1088. }
  1089. if (rtw_is_surprise_removed(Adapter)) {
  1090. RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(Adapter));
  1091. return;
  1092. }
  1093. for (i = 0; i < dvobj->iface_nums; i++) {
  1094. if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))
  1095. n_assoc_iface++;
  1096. }
  1097. if (n_assoc_iface) {
  1098. /* connect */
  1099. #ifdef CONFIG_LPS_LCLK
  1100. enqueue = 1;
  1101. #endif
  1102. #ifdef CONFIG_P2P_PS
  1103. p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue);
  1104. #endif /* CONFIG_P2P_PS */
  1105. #ifdef CONFIG_LPS
  1106. rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
  1107. #endif
  1108. #ifdef CONFIG_LPS_LCLK
  1109. LPS_Leave_check(Adapter);
  1110. #endif
  1111. } else {
  1112. if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) {
  1113. #ifdef CONFIG_AUTOSUSPEND
  1114. if (Adapter->registrypriv.usbss_enable) {
  1115. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
  1116. usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev);
  1117. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34))
  1118. adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;/* autosuspend disabled by the user */
  1119. #endif
  1120. } else
  1121. #endif
  1122. {
  1123. #if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || (defined(CONFIG_PLATFORM_SPRD) && defined(CONFIG_RTL8188E))
  1124. #ifdef CONFIG_IPS
  1125. if (_FALSE == ips_leave(Adapter))
  1126. RTW_INFO("======> ips_leave fail.............\n");
  1127. #endif
  1128. #endif /* CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) */
  1129. }
  1130. }
  1131. }
  1132. }
  1133. #ifdef CONFIG_LPS_LCLK
  1134. void LPS_Leave_check(
  1135. PADAPTER padapter)
  1136. {
  1137. struct pwrctrl_priv *pwrpriv;
  1138. u32 start_time;
  1139. u8 bReady;
  1140. pwrpriv = adapter_to_pwrctl(padapter);
  1141. bReady = _FALSE;
  1142. start_time = rtw_get_current_time();
  1143. rtw_yield_os();
  1144. while (1) {
  1145. _enter_pwrlock(&pwrpriv->lock);
  1146. if (rtw_is_surprise_removed(padapter)
  1147. || (!rtw_is_hw_init_completed(padapter))
  1148. #ifdef CONFIG_USB_HCI
  1149. || rtw_is_drv_stopped(padapter)
  1150. #endif
  1151. || (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
  1152. )
  1153. bReady = _TRUE;
  1154. _exit_pwrlock(&pwrpriv->lock);
  1155. if (_TRUE == bReady)
  1156. break;
  1157. if (rtw_get_passing_time_ms(start_time) > 100) {
  1158. RTW_INFO("Wait for cpwm event than 100 ms!!!\n");
  1159. break;
  1160. }
  1161. rtw_msleep_os(1);
  1162. }
  1163. }
  1164. /*
  1165. * Caller:ISR handler...
  1166. *
  1167. * This will be called when CPWM interrupt is up.
  1168. *
  1169. * using to update cpwn of drv; and drv willl make a decision to up or down pwr level
  1170. */
  1171. void cpwm_int_hdl(
  1172. PADAPTER padapter,
  1173. struct reportpwrstate_parm *preportpwrstate)
  1174. {
  1175. struct pwrctrl_priv *pwrpriv;
  1176. if (!padapter)
  1177. goto exit;
  1178. if (RTW_CANNOT_RUN(padapter))
  1179. goto exit;
  1180. pwrpriv = adapter_to_pwrctl(padapter);
  1181. #if 0
  1182. if (pwrpriv->cpwm_tog == (preportpwrstate->state & PS_TOGGLE)) {
  1183. goto exit;
  1184. }
  1185. #endif
  1186. _enter_pwrlock(&pwrpriv->lock);
  1187. #ifdef CONFIG_LPS_RPWM_TIMER
  1188. if (pwrpriv->rpwm < PS_STATE_S2) {
  1189. RTW_INFO("%s: Redundant CPWM Int. RPWM=0x%02X CPWM=0x%02x\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
  1190. _exit_pwrlock(&pwrpriv->lock);
  1191. goto exit;
  1192. }
  1193. #endif /* CONFIG_LPS_RPWM_TIMER */
  1194. pwrpriv->cpwm = PS_STATE(preportpwrstate->state);
  1195. pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE;
  1196. if (pwrpriv->cpwm >= PS_STATE_S2) {
  1197. if (pwrpriv->alives & CMD_ALIVE)
  1198. _rtw_up_sema(&padapter->cmdpriv.cmd_queue_sema);
  1199. if (pwrpriv->alives & XMIT_ALIVE)
  1200. _rtw_up_sema(&padapter->xmitpriv.xmit_sema);
  1201. }
  1202. _exit_pwrlock(&pwrpriv->lock);
  1203. exit:
  1204. return;
  1205. }
  1206. static void cpwm_event_callback(struct work_struct *work)
  1207. {
  1208. struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
  1209. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  1210. _adapter *adapter = dvobj_get_primary_adapter(dvobj);
  1211. struct reportpwrstate_parm report;
  1212. /* RTW_INFO("%s\n",__FUNCTION__); */
  1213. report.state = PS_STATE_S2;
  1214. cpwm_int_hdl(adapter, &report);
  1215. }
  1216. static void dma_event_callback(struct work_struct *work)
  1217. {
  1218. struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, dma_event);
  1219. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  1220. _adapter *adapter = dvobj_get_primary_adapter(dvobj);
  1221. rtw_unregister_tx_alive(adapter);
  1222. }
  1223. #ifdef CONFIG_LPS_RPWM_TIMER
  1224. static void rpwmtimeout_workitem_callback(struct work_struct *work)
  1225. {
  1226. PADAPTER padapter;
  1227. struct dvobj_priv *dvobj;
  1228. struct pwrctrl_priv *pwrpriv;
  1229. pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
  1230. dvobj = pwrctl_to_dvobj(pwrpriv);
  1231. padapter = dvobj_get_primary_adapter(dvobj);
  1232. /* RTW_INFO("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); */
  1233. if (!padapter)
  1234. return;
  1235. if (RTW_CANNOT_RUN(padapter))
  1236. return;
  1237. _enter_pwrlock(&pwrpriv->lock);
  1238. if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
  1239. RTW_INFO("%s: rpwm=0x%02X cpwm=0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
  1240. goto exit;
  1241. }
  1242. _exit_pwrlock(&pwrpriv->lock);
  1243. if (rtw_read8(padapter, 0x100) != 0xEA) {
  1244. #if 1
  1245. struct reportpwrstate_parm report;
  1246. report.state = PS_STATE_S2;
  1247. RTW_INFO("\n%s: FW already leave 32K!\n\n", __func__);
  1248. cpwm_int_hdl(padapter, &report);
  1249. #else
  1250. RTW_INFO("\n%s: FW already leave 32K!\n\n", __func__);
  1251. cpwm_event_callback(&pwrpriv->cpwm_event);
  1252. #endif
  1253. return;
  1254. }
  1255. _enter_pwrlock(&pwrpriv->lock);
  1256. if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
  1257. RTW_INFO("%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm);
  1258. goto exit;
  1259. }
  1260. pwrpriv->brpwmtimeout = _TRUE;
  1261. rtw_set_rpwm(padapter, pwrpriv->rpwm);
  1262. pwrpriv->brpwmtimeout = _FALSE;
  1263. exit:
  1264. _exit_pwrlock(&pwrpriv->lock);
  1265. }
  1266. /*
  1267. * This function is a timer handler, can't do any IO in it.
  1268. */
  1269. static void pwr_rpwm_timeout_handler(void *FunctionContext)
  1270. {
  1271. PADAPTER padapter;
  1272. struct pwrctrl_priv *pwrpriv;
  1273. padapter = (PADAPTER)FunctionContext;
  1274. pwrpriv = adapter_to_pwrctl(padapter);
  1275. if (!padapter)
  1276. return;
  1277. if (RTW_CANNOT_RUN(padapter))
  1278. return;
  1279. RTW_INFO("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
  1280. if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) {
  1281. RTW_INFO("+%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm);
  1282. return;
  1283. }
  1284. _set_workitem(&pwrpriv->rpwmtimeoutwi);
  1285. }
  1286. #endif /* CONFIG_LPS_RPWM_TIMER */
  1287. __inline static void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
  1288. {
  1289. pwrctrl->alives |= tag;
  1290. }
  1291. __inline static void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag)
  1292. {
  1293. pwrctrl->alives &= ~tag;
  1294. }
  1295. /*
  1296. * Description:
  1297. * Check if the fw_pwrstate is okay for I/O.
  1298. * If not (cpwm is less than S2), then the sub-routine
  1299. * will raise the cpwm to be greater than or equal to S2.
  1300. *
  1301. * Calling Context: Passive
  1302. *
  1303. * Constraint:
  1304. * 1. this function will request pwrctrl->lock
  1305. *
  1306. * Return Value:
  1307. * _SUCCESS hardware is ready for I/O
  1308. * _FAIL can't I/O right now
  1309. */
  1310. s32 rtw_register_task_alive(PADAPTER padapter, u32 task)
  1311. {
  1312. s32 res;
  1313. struct pwrctrl_priv *pwrctrl;
  1314. u8 pslv;
  1315. res = _SUCCESS;
  1316. pwrctrl = adapter_to_pwrctl(padapter);
  1317. pslv = PS_STATE_S2;
  1318. _enter_pwrlock(&pwrctrl->lock);
  1319. register_task_alive(pwrctrl, task);
  1320. if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
  1321. if (pwrctrl->cpwm < pslv) {
  1322. if (pwrctrl->cpwm < PS_STATE_S2)
  1323. res = _FAIL;
  1324. if (pwrctrl->rpwm < pslv)
  1325. rtw_set_rpwm(padapter, pslv);
  1326. }
  1327. }
  1328. _exit_pwrlock(&pwrctrl->lock);
  1329. #ifdef CONFIG_DETECT_CPWM_BY_POLLING
  1330. if (_FAIL == res) {
  1331. if (pwrctrl->cpwm >= PS_STATE_S2)
  1332. res = _SUCCESS;
  1333. }
  1334. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  1335. return res;
  1336. }
  1337. /*
  1338. * Description:
  1339. * If task is done, call this func. to power down firmware again.
  1340. *
  1341. * Constraint:
  1342. * 1. this function will request pwrctrl->lock
  1343. *
  1344. * Return Value:
  1345. * none
  1346. */
  1347. void rtw_unregister_task_alive(PADAPTER padapter, u32 task)
  1348. {
  1349. struct pwrctrl_priv *pwrctrl;
  1350. u8 pslv;
  1351. pwrctrl = adapter_to_pwrctl(padapter);
  1352. pslv = PS_STATE_S0;
  1353. #ifdef CONFIG_BT_COEXIST
  1354. if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE)
  1355. && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) {
  1356. u8 val8;
  1357. val8 = rtw_btcoex_LpsVal(padapter);
  1358. if (val8 & BIT(4))
  1359. pslv = PS_STATE_S2;
  1360. }
  1361. #endif /* CONFIG_BT_COEXIST */
  1362. _enter_pwrlock(&pwrctrl->lock);
  1363. unregister_task_alive(pwrctrl, task);
  1364. if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
  1365. && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
  1366. if (pwrctrl->cpwm > pslv) {
  1367. if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
  1368. rtw_set_rpwm(padapter, pslv);
  1369. }
  1370. }
  1371. _exit_pwrlock(&pwrctrl->lock);
  1372. }
  1373. /*
  1374. * Caller: rtw_xmit_thread
  1375. *
  1376. * Check if the fw_pwrstate is okay for xmit.
  1377. * If not (cpwm is less than S3), then the sub-routine
  1378. * will raise the cpwm to be greater than or equal to S3.
  1379. *
  1380. * Calling Context: Passive
  1381. *
  1382. * Return Value:
  1383. * _SUCCESS rtw_xmit_thread can write fifo/txcmd afterwards.
  1384. * _FAIL rtw_xmit_thread can not do anything.
  1385. */
  1386. s32 rtw_register_tx_alive(PADAPTER padapter)
  1387. {
  1388. s32 res;
  1389. struct pwrctrl_priv *pwrctrl;
  1390. u8 pslv;
  1391. res = _SUCCESS;
  1392. pwrctrl = adapter_to_pwrctl(padapter);
  1393. pslv = PS_STATE_S2;
  1394. _enter_pwrlock(&pwrctrl->lock);
  1395. register_task_alive(pwrctrl, XMIT_ALIVE);
  1396. if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
  1397. if (pwrctrl->cpwm < pslv) {
  1398. if (pwrctrl->cpwm < PS_STATE_S2)
  1399. res = _FAIL;
  1400. if (pwrctrl->rpwm < pslv)
  1401. rtw_set_rpwm(padapter, pslv);
  1402. }
  1403. }
  1404. _exit_pwrlock(&pwrctrl->lock);
  1405. #ifdef CONFIG_DETECT_CPWM_BY_POLLING
  1406. if (_FAIL == res) {
  1407. if (pwrctrl->cpwm >= PS_STATE_S2)
  1408. res = _SUCCESS;
  1409. }
  1410. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  1411. return res;
  1412. }
  1413. /*
  1414. * Caller: rtw_cmd_thread
  1415. *
  1416. * Check if the fw_pwrstate is okay for issuing cmd.
  1417. * If not (cpwm should be is less than S2), then the sub-routine
  1418. * will raise the cpwm to be greater than or equal to S2.
  1419. *
  1420. * Calling Context: Passive
  1421. *
  1422. * Return Value:
  1423. * _SUCCESS rtw_cmd_thread can issue cmds to firmware afterwards.
  1424. * _FAIL rtw_cmd_thread can not do anything.
  1425. */
  1426. s32 rtw_register_cmd_alive(PADAPTER padapter)
  1427. {
  1428. s32 res;
  1429. struct pwrctrl_priv *pwrctrl;
  1430. u8 pslv;
  1431. res = _SUCCESS;
  1432. pwrctrl = adapter_to_pwrctl(padapter);
  1433. pslv = PS_STATE_S2;
  1434. _enter_pwrlock(&pwrctrl->lock);
  1435. register_task_alive(pwrctrl, CMD_ALIVE);
  1436. if (pwrctrl->bFwCurrentInPSMode == _TRUE) {
  1437. if (pwrctrl->cpwm < pslv) {
  1438. if (pwrctrl->cpwm < PS_STATE_S2)
  1439. res = _FAIL;
  1440. if (pwrctrl->rpwm < pslv)
  1441. rtw_set_rpwm(padapter, pslv);
  1442. }
  1443. }
  1444. _exit_pwrlock(&pwrctrl->lock);
  1445. #ifdef CONFIG_DETECT_CPWM_BY_POLLING
  1446. if (_FAIL == res) {
  1447. if (pwrctrl->cpwm >= PS_STATE_S2)
  1448. res = _SUCCESS;
  1449. }
  1450. #endif /* CONFIG_DETECT_CPWM_BY_POLLING */
  1451. return res;
  1452. }
  1453. /*
  1454. * Caller: rx_isr
  1455. *
  1456. * Calling Context: Dispatch/ISR
  1457. *
  1458. * Return Value:
  1459. * _SUCCESS
  1460. * _FAIL
  1461. */
  1462. s32 rtw_register_rx_alive(PADAPTER padapter)
  1463. {
  1464. struct pwrctrl_priv *pwrctrl;
  1465. pwrctrl = adapter_to_pwrctl(padapter);
  1466. _enter_pwrlock(&pwrctrl->lock);
  1467. register_task_alive(pwrctrl, RECV_ALIVE);
  1468. _exit_pwrlock(&pwrctrl->lock);
  1469. return _SUCCESS;
  1470. }
  1471. /*
  1472. * Caller: evt_isr or evt_thread
  1473. *
  1474. * Calling Context: Dispatch/ISR or Passive
  1475. *
  1476. * Return Value:
  1477. * _SUCCESS
  1478. * _FAIL
  1479. */
  1480. s32 rtw_register_evt_alive(PADAPTER padapter)
  1481. {
  1482. struct pwrctrl_priv *pwrctrl;
  1483. pwrctrl = adapter_to_pwrctl(padapter);
  1484. _enter_pwrlock(&pwrctrl->lock);
  1485. register_task_alive(pwrctrl, EVT_ALIVE);
  1486. _exit_pwrlock(&pwrctrl->lock);
  1487. return _SUCCESS;
  1488. }
  1489. /*
  1490. * Caller: ISR
  1491. *
  1492. * If ISR's txdone,
  1493. * No more pkts for TX,
  1494. * Then driver shall call this fun. to power down firmware again.
  1495. */
  1496. void rtw_unregister_tx_alive(PADAPTER padapter)
  1497. {
  1498. struct pwrctrl_priv *pwrctrl;
  1499. _adapter *iface;
  1500. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1501. u8 pslv, i;
  1502. pwrctrl = adapter_to_pwrctl(padapter);
  1503. pslv = PS_STATE_S0;
  1504. #ifdef CONFIG_BT_COEXIST
  1505. if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE)
  1506. && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) {
  1507. u8 val8;
  1508. val8 = rtw_btcoex_LpsVal(padapter);
  1509. if (val8 & BIT(4))
  1510. pslv = PS_STATE_S2;
  1511. }
  1512. #endif /* CONFIG_BT_COEXIST */
  1513. #ifdef CONFIG_P2P_PS
  1514. for (i = 0; i < dvobj->iface_nums; i++) {
  1515. iface = dvobj->padapters[i];
  1516. if ((iface) && rtw_is_adapter_up(iface)) {
  1517. if (iface->wdinfo.p2p_ps_mode > P2P_PS_NONE) {
  1518. pslv = PS_STATE_S2;
  1519. break;
  1520. }
  1521. }
  1522. }
  1523. #endif
  1524. _enter_pwrlock(&pwrctrl->lock);
  1525. unregister_task_alive(pwrctrl, XMIT_ALIVE);
  1526. if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
  1527. && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
  1528. if (pwrctrl->cpwm > pslv) {
  1529. if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
  1530. rtw_set_rpwm(padapter, pslv);
  1531. }
  1532. }
  1533. _exit_pwrlock(&pwrctrl->lock);
  1534. }
  1535. /*
  1536. * Caller: ISR
  1537. *
  1538. * If all commands have been done,
  1539. * and no more command to do,
  1540. * then driver shall call this fun. to power down firmware again.
  1541. */
  1542. void rtw_unregister_cmd_alive(PADAPTER padapter)
  1543. {
  1544. _adapter *iface;
  1545. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1546. struct pwrctrl_priv *pwrctrl;
  1547. u8 pslv, i;
  1548. pwrctrl = adapter_to_pwrctl(padapter);
  1549. pslv = PS_STATE_S0;
  1550. #ifdef CONFIG_BT_COEXIST
  1551. if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE)
  1552. && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) {
  1553. u8 val8;
  1554. val8 = rtw_btcoex_LpsVal(padapter);
  1555. if (val8 & BIT(4))
  1556. pslv = PS_STATE_S2;
  1557. }
  1558. #endif /* CONFIG_BT_COEXIST */
  1559. #ifdef CONFIG_P2P_PS
  1560. for (i = 0; i < dvobj->iface_nums; i++) {
  1561. iface = dvobj->padapters[i];
  1562. if ((iface) && rtw_is_adapter_up(iface)) {
  1563. if (iface->wdinfo.p2p_ps_mode > P2P_PS_NONE) {
  1564. pslv = PS_STATE_S2;
  1565. break;
  1566. }
  1567. }
  1568. }
  1569. #endif
  1570. _enter_pwrlock(&pwrctrl->lock);
  1571. unregister_task_alive(pwrctrl, CMD_ALIVE);
  1572. if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE)
  1573. && (pwrctrl->bFwCurrentInPSMode == _TRUE)) {
  1574. if (pwrctrl->cpwm > pslv) {
  1575. if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0))
  1576. rtw_set_rpwm(padapter, pslv);
  1577. }
  1578. }
  1579. _exit_pwrlock(&pwrctrl->lock);
  1580. }
  1581. /*
  1582. * Caller: ISR
  1583. */
  1584. void rtw_unregister_rx_alive(PADAPTER padapter)
  1585. {
  1586. struct pwrctrl_priv *pwrctrl;
  1587. pwrctrl = adapter_to_pwrctl(padapter);
  1588. _enter_pwrlock(&pwrctrl->lock);
  1589. unregister_task_alive(pwrctrl, RECV_ALIVE);
  1590. _exit_pwrlock(&pwrctrl->lock);
  1591. }
  1592. void rtw_unregister_evt_alive(PADAPTER padapter)
  1593. {
  1594. struct pwrctrl_priv *pwrctrl;
  1595. pwrctrl = adapter_to_pwrctl(padapter);
  1596. unregister_task_alive(pwrctrl, EVT_ALIVE);
  1597. _exit_pwrlock(&pwrctrl->lock);
  1598. }
  1599. #endif /* CONFIG_LPS_LCLK */
  1600. #ifdef CONFIG_RESUME_IN_WORKQUEUE
  1601. static void resume_workitem_callback(struct work_struct *work);
  1602. #endif /* CONFIG_RESUME_IN_WORKQUEUE */
  1603. void rtw_init_pwrctrl_priv(PADAPTER padapter)
  1604. {
  1605. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
  1606. u8 val8 = 0;
  1607. #if defined(CONFIG_CONCURRENT_MODE)
  1608. if (padapter->adapter_type != PRIMARY_ADAPTER)
  1609. return;
  1610. #endif
  1611. #ifdef PLATFORM_WINDOWS
  1612. pwrctrlpriv->pnp_current_pwr_state = NdisDeviceStateD0;
  1613. #endif
  1614. _init_pwrlock(&pwrctrlpriv->lock);
  1615. _init_pwrlock(&pwrctrlpriv->check_32k_lock);
  1616. pwrctrlpriv->adapter = padapter;
  1617. pwrctrlpriv->rf_pwrstate = rf_on;
  1618. pwrctrlpriv->ips_enter_cnts = 0;
  1619. pwrctrlpriv->ips_leave_cnts = 0;
  1620. pwrctrlpriv->lps_enter_cnts = 0;
  1621. pwrctrlpriv->lps_leave_cnts = 0;
  1622. pwrctrlpriv->bips_processing = _FALSE;
  1623. pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
  1624. pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
  1625. pwrctrlpriv->lps_level = padapter->registrypriv.lps_level;
  1626. pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
  1627. pwrctrlpriv->pwr_state_check_cnts = 0;
  1628. pwrctrlpriv->bInternalAutoSuspend = _FALSE;
  1629. pwrctrlpriv->bInSuspend = _FALSE;
  1630. pwrctrlpriv->bkeepfwalive = _FALSE;
  1631. #ifdef CONFIG_AUTOSUSPEND
  1632. #ifdef SUPPORT_HW_RFOFF_DETECTED
  1633. pwrctrlpriv->pwr_state_check_interval = (pwrctrlpriv->bHWPwrPindetect) ? 1000 : 2000;
  1634. #endif
  1635. #endif
  1636. pwrctrlpriv->LpsIdleCount = 0;
  1637. #ifdef CONFIG_LPS_PG
  1638. pwrctrlpriv->lpspg_rsvd_page_locate = 0;
  1639. #endif
  1640. /* pwrctrlpriv->FWCtrlPSMode =padapter->registrypriv.power_mgnt; */ /* PS_MODE_MIN; */
  1641. if (padapter->registrypriv.mp_mode == 1)
  1642. pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ;
  1643. else
  1644. pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt; /* PS_MODE_MIN; */
  1645. pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? _TRUE : _FALSE;
  1646. pwrctrlpriv->bFwCurrentInPSMode = _FALSE;
  1647. pwrctrlpriv->rpwm = 0;
  1648. pwrctrlpriv->cpwm = PS_STATE_S4;
  1649. pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
  1650. pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
  1651. pwrctrlpriv->bcn_ant_mode = 0;
  1652. pwrctrlpriv->dtim = 0;
  1653. pwrctrlpriv->tog = 0x80;
  1654. #ifdef CONFIG_LPS_LCLK
  1655. rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm));
  1656. _init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL);
  1657. _init_workitem(&pwrctrlpriv->dma_event, dma_event_callback, NULL);
  1658. #ifdef CONFIG_LPS_RPWM_TIMER
  1659. pwrctrlpriv->brpwmtimeout = _FALSE;
  1660. _init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL);
  1661. rtw_init_timer(&pwrctrlpriv->pwr_rpwm_timer, padapter, pwr_rpwm_timeout_handler, padapter);
  1662. #endif /* CONFIG_LPS_RPWM_TIMER */
  1663. #endif /* CONFIG_LPS_LCLK */
  1664. rtw_init_timer(&pwrctrlpriv->pwr_state_check_timer, padapter, pwr_state_check_handler);
  1665. pwrctrlpriv->wowlan_mode = _FALSE;
  1666. pwrctrlpriv->wowlan_ap_mode = _FALSE;
  1667. pwrctrlpriv->wowlan_p2p_mode = _FALSE;
  1668. pwrctrlpriv->wowlan_last_wake_reason = 0;
  1669. #ifdef CONFIG_RESUME_IN_WORKQUEUE
  1670. _init_workitem(&pwrctrlpriv->resume_work, resume_workitem_callback, NULL);
  1671. pwrctrlpriv->rtw_workqueue = create_singlethread_workqueue("rtw_workqueue");
  1672. #endif /* CONFIG_RESUME_IN_WORKQUEUE */
  1673. #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
  1674. pwrctrlpriv->early_suspend.suspend = NULL;
  1675. rtw_register_early_suspend(pwrctrlpriv);
  1676. #endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */
  1677. #ifdef CONFIG_GPIO_WAKEUP
  1678. /*default low active*/
  1679. pwrctrlpriv->is_high_active = HIGH_ACTIVE;
  1680. #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
  1681. if (pwrctrlpriv->is_high_active == 0)
  1682. rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
  1683. else
  1684. rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);
  1685. #else
  1686. val8 = (pwrctrlpriv->is_high_active == 0) ? 1 : 0;
  1687. rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
  1688. rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
  1689. RTW_INFO("%s: set GPIO_%d %d as default.\n",
  1690. __func__, WAKEUP_GPIO_IDX, val8);
  1691. #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
  1692. #endif /* CONFIG_GPIO_WAKEUP */
  1693. #ifdef CONFIG_WOWLAN
  1694. rtw_wow_pattern_sw_reset(padapter);
  1695. pwrctrlpriv->wowlan_in_resume = _FALSE;
  1696. #ifdef CONFIG_PNO_SUPPORT
  1697. pwrctrlpriv->pno_inited = _FALSE;
  1698. pwrctrlpriv->pnlo_info = NULL;
  1699. pwrctrlpriv->pscan_info = NULL;
  1700. pwrctrlpriv->pno_ssid_list = NULL;
  1701. #endif /* CONFIG_PNO_SUPPORT */
  1702. #ifdef CONFIG_WOW_PATTERN_HW_CAM
  1703. _rtw_mutex_init(&pwrctrlpriv->wowlan_pattern_cam_mutex);
  1704. #endif
  1705. pwrctrlpriv->wowlan_aoac_rpt_loc = 0;
  1706. #endif /* CONFIG_WOWLAN */
  1707. #ifdef CONFIG_LPS_POFF
  1708. rtw_hal_set_hwreg(padapter, HW_VAR_LPS_POFF_INIT, 0);
  1709. #endif
  1710. }
  1711. void rtw_free_pwrctrl_priv(PADAPTER adapter)
  1712. {
  1713. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter);
  1714. #if defined(CONFIG_CONCURRENT_MODE)
  1715. if (adapter->adapter_type != PRIMARY_ADAPTER)
  1716. return;
  1717. #endif
  1718. /* _rtw_memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); */
  1719. #ifdef CONFIG_RESUME_IN_WORKQUEUE
  1720. if (pwrctrlpriv->rtw_workqueue) {
  1721. flush_workqueue(pwrctrlpriv->rtw_workqueue);
  1722. destroy_workqueue(pwrctrlpriv->rtw_workqueue);
  1723. }
  1724. #endif
  1725. #ifdef CONFIG_LPS_POFF
  1726. rtw_hal_set_hwreg(adapter, HW_VAR_LPS_POFF_DEINIT, 0);
  1727. #endif
  1728. #ifdef CONFIG_WOWLAN
  1729. #ifdef CONFIG_PNO_SUPPORT
  1730. if (pwrctrlpriv->pnlo_info != NULL)
  1731. printk("****** pnlo_info memory leak********\n");
  1732. if (pwrctrlpriv->pscan_info != NULL)
  1733. printk("****** pscan_info memory leak********\n");
  1734. if (pwrctrlpriv->pno_ssid_list != NULL)
  1735. printk("****** pno_ssid_list memory leak********\n");
  1736. #endif
  1737. #ifdef CONFIG_WOW_PATTERN_HW_CAM
  1738. _rtw_mutex_free(&pwrctrlpriv->wowlan_pattern_cam_mutex);
  1739. #endif
  1740. #endif /* CONFIG_WOWLAN */
  1741. #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
  1742. rtw_unregister_early_suspend(pwrctrlpriv);
  1743. #endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */
  1744. _free_pwrlock(&pwrctrlpriv->lock);
  1745. _free_pwrlock(&pwrctrlpriv->check_32k_lock);
  1746. }
  1747. #ifdef CONFIG_RESUME_IN_WORKQUEUE
  1748. extern int rtw_resume_process(_adapter *padapter);
  1749. static void resume_workitem_callback(struct work_struct *work)
  1750. {
  1751. struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, resume_work);
  1752. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  1753. _adapter *adapter = dvobj_get_primary_adapter(dvobj);
  1754. RTW_INFO("%s\n", __FUNCTION__);
  1755. rtw_resume_process(adapter);
  1756. rtw_resume_unlock_suspend();
  1757. }
  1758. void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv)
  1759. {
  1760. /* accquire system's suspend lock preventing from falliing asleep while resume in workqueue */
  1761. /* rtw_lock_suspend(); */
  1762. rtw_resume_lock_suspend();
  1763. #if 1
  1764. queue_work(pwrpriv->rtw_workqueue, &pwrpriv->resume_work);
  1765. #else
  1766. _set_workitem(&pwrpriv->resume_work);
  1767. #endif
  1768. }
  1769. #endif /* CONFIG_RESUME_IN_WORKQUEUE */
  1770. #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
  1771. inline bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv)
  1772. {
  1773. return (pwrpriv->early_suspend.suspend) ? _TRUE : _FALSE;
  1774. }
  1775. inline bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv)
  1776. {
  1777. return (pwrpriv->do_late_resume) ? _TRUE : _FALSE;
  1778. }
  1779. inline void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable)
  1780. {
  1781. pwrpriv->do_late_resume = enable;
  1782. }
  1783. #endif
  1784. #ifdef CONFIG_HAS_EARLYSUSPEND
  1785. extern int rtw_resume_process(_adapter *padapter);
  1786. static void rtw_early_suspend(struct early_suspend *h)
  1787. {
  1788. struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
  1789. RTW_INFO("%s\n", __FUNCTION__);
  1790. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1791. }
  1792. static void rtw_late_resume(struct early_suspend *h)
  1793. {
  1794. struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
  1795. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  1796. _adapter *adapter = dvobj_get_primary_adapter(dvobj);
  1797. RTW_INFO("%s\n", __FUNCTION__);
  1798. if (pwrpriv->do_late_resume) {
  1799. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1800. rtw_resume_process(adapter);
  1801. }
  1802. }
  1803. void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv)
  1804. {
  1805. RTW_INFO("%s\n", __FUNCTION__);
  1806. /* jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit */
  1807. pwrpriv->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
  1808. pwrpriv->early_suspend.suspend = rtw_early_suspend;
  1809. pwrpriv->early_suspend.resume = rtw_late_resume;
  1810. register_early_suspend(&pwrpriv->early_suspend);
  1811. }
  1812. void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv)
  1813. {
  1814. RTW_INFO("%s\n", __FUNCTION__);
  1815. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1816. if (pwrpriv->early_suspend.suspend)
  1817. unregister_early_suspend(&pwrpriv->early_suspend);
  1818. pwrpriv->early_suspend.suspend = NULL;
  1819. pwrpriv->early_suspend.resume = NULL;
  1820. }
  1821. #endif /* CONFIG_HAS_EARLYSUSPEND */
  1822. #ifdef CONFIG_ANDROID_POWER
  1823. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  1824. extern int rtw_resume_process(PADAPTER padapter);
  1825. #endif
  1826. static void rtw_early_suspend(android_early_suspend_t *h)
  1827. {
  1828. struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
  1829. RTW_INFO("%s\n", __FUNCTION__);
  1830. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1831. }
  1832. static void rtw_late_resume(android_early_suspend_t *h)
  1833. {
  1834. struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
  1835. struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
  1836. _adapter *adapter = dvobj_get_primary_adapter(dvobj);
  1837. RTW_INFO("%s\n", __FUNCTION__);
  1838. if (pwrpriv->do_late_resume) {
  1839. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  1840. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1841. rtw_resume_process(adapter);
  1842. #endif
  1843. }
  1844. }
  1845. void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv)
  1846. {
  1847. RTW_INFO("%s\n", __FUNCTION__);
  1848. /* jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit */
  1849. pwrpriv->early_suspend.level = ANDROID_EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
  1850. pwrpriv->early_suspend.suspend = rtw_early_suspend;
  1851. pwrpriv->early_suspend.resume = rtw_late_resume;
  1852. android_register_early_suspend(&pwrpriv->early_suspend);
  1853. }
  1854. void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv)
  1855. {
  1856. RTW_INFO("%s\n", __FUNCTION__);
  1857. rtw_set_do_late_resume(pwrpriv, _FALSE);
  1858. if (pwrpriv->early_suspend.suspend)
  1859. android_unregister_early_suspend(&pwrpriv->early_suspend);
  1860. pwrpriv->early_suspend.suspend = NULL;
  1861. pwrpriv->early_suspend.resume = NULL;
  1862. }
  1863. #endif /* CONFIG_ANDROID_POWER */
  1864. u8 rtw_interface_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val)
  1865. {
  1866. u8 bResult = _TRUE;
  1867. rtw_hal_intf_ps_func(padapter, efunc_id, val);
  1868. return bResult;
  1869. }
  1870. inline void rtw_set_ips_deny(_adapter *padapter, u32 ms)
  1871. {
  1872. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
  1873. pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
  1874. }
  1875. /*
  1876. * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
  1877. * @adapter: pointer to _adapter structure
  1878. * @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
  1879. * Return _SUCCESS or _FAIL
  1880. */
  1881. int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller)
  1882. {
  1883. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1884. struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
  1885. struct mlme_priv *pmlmepriv;
  1886. int ret = _SUCCESS;
  1887. int i;
  1888. u32 start = rtw_get_current_time();
  1889. /* for LPS */
  1890. LeaveAllPowerSaveMode(padapter);
  1891. /* IPS still bound with primary adapter */
  1892. padapter = GET_PRIMARY_ADAPTER(padapter);
  1893. pmlmepriv = &padapter->mlmepriv;
  1894. if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms))
  1895. pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms);
  1896. if (pwrpriv->ps_processing) {
  1897. RTW_INFO("%s wait ps_processing...\n", __func__);
  1898. while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000)
  1899. rtw_msleep_os(10);
  1900. if (pwrpriv->ps_processing)
  1901. RTW_INFO("%s wait ps_processing timeout\n", __func__);
  1902. else
  1903. RTW_INFO("%s wait ps_processing done\n", __func__);
  1904. }
  1905. #ifdef DBG_CONFIG_ERROR_DETECT
  1906. if (rtw_hal_sreset_inprogress(padapter)) {
  1907. RTW_INFO("%s wait sreset_inprogress...\n", __func__);
  1908. while (rtw_hal_sreset_inprogress(padapter) && rtw_get_passing_time_ms(start) <= 4000)
  1909. rtw_msleep_os(10);
  1910. if (rtw_hal_sreset_inprogress(padapter))
  1911. RTW_INFO("%s wait sreset_inprogress timeout\n", __func__);
  1912. else
  1913. RTW_INFO("%s wait sreset_inprogress done\n", __func__);
  1914. }
  1915. #endif
  1916. if (pwrpriv->bInternalAutoSuspend == _FALSE && pwrpriv->bInSuspend) {
  1917. RTW_INFO("%s wait bInSuspend...\n", __func__);
  1918. while (pwrpriv->bInSuspend
  1919. && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv))
  1920. || (rtw_get_passing_time_ms(start) <= 500 && rtw_is_do_late_resume(pwrpriv)))
  1921. )
  1922. rtw_msleep_os(10);
  1923. if (pwrpriv->bInSuspend)
  1924. RTW_INFO("%s wait bInSuspend timeout\n", __func__);
  1925. else
  1926. RTW_INFO("%s wait bInSuspend done\n", __func__);
  1927. }
  1928. /* System suspend is not allowed to wakeup */
  1929. if ((pwrpriv->bInternalAutoSuspend == _FALSE) && (_TRUE == pwrpriv->bInSuspend)) {
  1930. ret = _FAIL;
  1931. goto exit;
  1932. }
  1933. /* block??? */
  1934. if ((pwrpriv->bInternalAutoSuspend == _TRUE) && (padapter->net_closed == _TRUE)) {
  1935. ret = _FAIL;
  1936. goto exit;
  1937. }
  1938. /* I think this should be check in IPS, LPS, autosuspend functions... */
  1939. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
  1940. #if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND)
  1941. if (_TRUE == pwrpriv->bInternalAutoSuspend) {
  1942. if (0 == pwrpriv->autopm_cnt) {
  1943. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
  1944. if (usb_autopm_get_interface(adapter_to_dvobj(padapter)->pusbintf) < 0)
  1945. RTW_INFO("can't get autopm:\n");
  1946. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
  1947. usb_autopm_disable(adapter_to_dvobj(padapter)->pusbintf);
  1948. #else
  1949. usb_autoresume_device(adapter_to_dvobj(padapter)->pusbdev, 1);
  1950. #endif
  1951. pwrpriv->autopm_cnt++;
  1952. }
  1953. #endif /* #if defined (CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) */
  1954. ret = _SUCCESS;
  1955. goto exit;
  1956. #if defined(CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND)
  1957. }
  1958. #endif /* #if defined (CONFIG_BT_COEXIST) && defined (CONFIG_AUTOSUSPEND) */
  1959. }
  1960. if (rf_off == pwrpriv->rf_pwrstate) {
  1961. #ifdef CONFIG_USB_HCI
  1962. #ifdef CONFIG_AUTOSUSPEND
  1963. if (pwrpriv->brfoffbyhw == _TRUE) {
  1964. RTW_INFO("hw still in rf_off state ...........\n");
  1965. ret = _FAIL;
  1966. goto exit;
  1967. } else if (padapter->registrypriv.usbss_enable) {
  1968. RTW_INFO("%s call autoresume_enter....\n", __FUNCTION__);
  1969. if (_FAIL == autoresume_enter(padapter)) {
  1970. RTW_INFO("======> autoresume fail.............\n");
  1971. ret = _FAIL;
  1972. goto exit;
  1973. }
  1974. } else
  1975. #endif
  1976. #endif
  1977. {
  1978. #ifdef CONFIG_IPS
  1979. RTW_INFO("%s call ips_leave....\n", __FUNCTION__);
  1980. if (_FAIL == ips_leave(padapter)) {
  1981. RTW_INFO("======> ips_leave fail.............\n");
  1982. ret = _FAIL;
  1983. goto exit;
  1984. }
  1985. #endif
  1986. }
  1987. }
  1988. /* TODO: the following checking need to be merged... */
  1989. if (rtw_is_drv_stopped(padapter)
  1990. || !padapter->bup
  1991. || !rtw_is_hw_init_completed(padapter)
  1992. ) {
  1993. RTW_INFO("%s: bDriverStopped=%s, bup=%d, hw_init_completed=%u\n"
  1994. , caller
  1995. , rtw_is_drv_stopped(padapter) ? "True" : "False"
  1996. , padapter->bup
  1997. , rtw_get_hw_init_completed(padapter));
  1998. ret = _FALSE;
  1999. goto exit;
  2000. }
  2001. exit:
  2002. if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms))
  2003. pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms);
  2004. return ret;
  2005. }
  2006. int rtw_pm_set_lps(_adapter *padapter, u8 mode)
  2007. {
  2008. int ret = 0;
  2009. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
  2010. if (mode < PS_MODE_NUM) {
  2011. if (pwrctrlpriv->power_mgnt != mode) {
  2012. if (PS_MODE_ACTIVE == mode)
  2013. LeaveAllPowerSaveMode(padapter);
  2014. else
  2015. pwrctrlpriv->LpsIdleCount = 2;
  2016. pwrctrlpriv->power_mgnt = mode;
  2017. pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? _TRUE : _FALSE;
  2018. }
  2019. } else
  2020. ret = -EINVAL;
  2021. return ret;
  2022. }
  2023. int rtw_pm_set_lps_level(_adapter *padapter, u8 level)
  2024. {
  2025. int ret = 0;
  2026. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
  2027. if (level < LPS_LEVEL_MAX)
  2028. pwrctrlpriv->lps_level = level;
  2029. else
  2030. ret = -EINVAL;
  2031. return ret;
  2032. }
  2033. int rtw_pm_set_ips(_adapter *padapter, u8 mode)
  2034. {
  2035. struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
  2036. if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
  2037. rtw_ips_mode_req(pwrctrlpriv, mode);
  2038. RTW_INFO("%s %s\n", __FUNCTION__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2");
  2039. return 0;
  2040. } else if (mode == IPS_NONE) {
  2041. rtw_ips_mode_req(pwrctrlpriv, mode);
  2042. RTW_INFO("%s %s\n", __FUNCTION__, "IPS_NONE");
  2043. if (!rtw_is_surprise_removed(padapter) && (_FAIL == rtw_pwr_wakeup(padapter)))
  2044. return -EFAULT;
  2045. } else
  2046. return -EINVAL;
  2047. return 0;
  2048. }
  2049. /*
  2050. * ATTENTION:
  2051. * This function will request pwrctrl LOCK!
  2052. */
  2053. void rtw_ps_deny(PADAPTER padapter, PS_DENY_REASON reason)
  2054. {
  2055. struct pwrctrl_priv *pwrpriv;
  2056. s32 ret;
  2057. /* RTW_INFO("+" FUNC_ADPT_FMT ": Request PS deny for %d (0x%08X)\n",
  2058. * FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
  2059. pwrpriv = adapter_to_pwrctl(padapter);
  2060. _enter_pwrlock(&pwrpriv->lock);
  2061. if (pwrpriv->ps_deny & BIT(reason)) {
  2062. RTW_INFO(FUNC_ADPT_FMT ": [WARNING] Reason %d had been set before!!\n",
  2063. FUNC_ADPT_ARG(padapter), reason);
  2064. }
  2065. pwrpriv->ps_deny |= BIT(reason);
  2066. _exit_pwrlock(&pwrpriv->lock);
  2067. /* RTW_INFO("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n",
  2068. * FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
  2069. }
  2070. /*
  2071. * ATTENTION:
  2072. * This function will request pwrctrl LOCK!
  2073. */
  2074. void rtw_ps_deny_cancel(PADAPTER padapter, PS_DENY_REASON reason)
  2075. {
  2076. struct pwrctrl_priv *pwrpriv;
  2077. /* RTW_INFO("+" FUNC_ADPT_FMT ": Cancel PS deny for %d(0x%08X)\n",
  2078. * FUNC_ADPT_ARG(padapter), reason, BIT(reason)); */
  2079. pwrpriv = adapter_to_pwrctl(padapter);
  2080. _enter_pwrlock(&pwrpriv->lock);
  2081. if ((pwrpriv->ps_deny & BIT(reason)) == 0) {
  2082. RTW_INFO(FUNC_ADPT_FMT ": [ERROR] Reason %d had been canceled before!!\n",
  2083. FUNC_ADPT_ARG(padapter), reason);
  2084. }
  2085. pwrpriv->ps_deny &= ~BIT(reason);
  2086. _exit_pwrlock(&pwrpriv->lock);
  2087. /* RTW_INFO("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n",
  2088. * FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); */
  2089. }
  2090. /*
  2091. * ATTENTION:
  2092. * Before calling this function pwrctrl lock should be occupied already,
  2093. * otherwise it may return incorrect value.
  2094. */
  2095. u32 rtw_ps_deny_get(PADAPTER padapter)
  2096. {
  2097. u32 deny;
  2098. deny = adapter_to_pwrctl(padapter)->ps_deny;
  2099. return deny;
  2100. }