rtw_pwrctrl.c 73 KB

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