phy.c 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2014 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. * The full GNU General Public License is included in this distribution in the
  15. * file called LICENSE.
  16. *
  17. * Contact Information:
  18. * wlanfae <wlanfae@realtek.com>
  19. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20. * Hsinchu 300, Taiwan.
  21. *
  22. * Larry Finger <Larry.Finger@lwfinger.net>
  23. *
  24. *****************************************************************************/
  25. #include "../wifi.h"
  26. #include "../pci.h"
  27. #include "../ps.h"
  28. #include "../core.h"
  29. #include "reg.h"
  30. #include "def.h"
  31. #include "phy.h"
  32. #include "../rtl8723com/phy_common.h"
  33. #include "rf.h"
  34. #include "dm.h"
  35. #include "table.h"
  36. #include "trx.h"
  37. static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
  38. static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  39. u8 configtype);
  40. static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
  41. u8 channel, u8 *stage,
  42. u8 *step, u32 *delay);
  43. static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
  44. const u32 condition)
  45. {
  46. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  47. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  48. u32 _board = rtlefuse->board_type; /*need efuse define*/
  49. u32 _interface = rtlhal->interface;
  50. u32 _platform = 0x08;/*SupportPlatform */
  51. u32 cond = condition;
  52. if (condition == 0xCDCDCDCD)
  53. return true;
  54. cond = condition & 0xFF;
  55. if ((_board & cond) == 0 && cond != 0x1F)
  56. return false;
  57. cond = condition & 0xFF00;
  58. cond = cond >> 8;
  59. if ((_interface & cond) == 0 && cond != 0x07)
  60. return false;
  61. cond = condition & 0xFF0000;
  62. cond = cond >> 16;
  63. if ((_platform & cond) == 0 && cond != 0x0F)
  64. return false;
  65. return true;
  66. }
  67. static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
  68. {
  69. struct rtl_priv *rtlpriv = rtl_priv(hw);
  70. u32 i;
  71. u32 arraylength;
  72. u32 *ptrarray;
  73. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
  74. arraylength = RTL8723BEMAC_1T_ARRAYLEN;
  75. ptrarray = RTL8723BEMAC_1T_ARRAY;
  76. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  77. "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
  78. for (i = 0; i < arraylength; i = i + 2)
  79. rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
  80. return true;
  81. }
  82. static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  83. u8 configtype)
  84. {
  85. #define READ_NEXT_PAIR(v1, v2, i) \
  86. do { \
  87. i += 2; \
  88. v1 = array_table[i];\
  89. v2 = array_table[i+1]; \
  90. } while (0)
  91. int i;
  92. u32 *array_table;
  93. u16 arraylen;
  94. struct rtl_priv *rtlpriv = rtl_priv(hw);
  95. u32 v1 = 0, v2 = 0;
  96. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  97. arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
  98. array_table = RTL8723BEPHY_REG_1TARRAY;
  99. for (i = 0; i < arraylen; i = i + 2) {
  100. v1 = array_table[i];
  101. v2 = array_table[i+1];
  102. if (v1 < 0xcdcdcdcd) {
  103. rtl_bb_delay(hw, v1, v2);
  104. } else {/*This line is the start line of branch.*/
  105. if (!_rtl8723be_check_condition(hw, array_table[i])) {
  106. /*Discard the following (offset, data) pairs*/
  107. READ_NEXT_PAIR(v1, v2, i);
  108. while (v2 != 0xDEAD &&
  109. v2 != 0xCDEF &&
  110. v2 != 0xCDCD &&
  111. i < arraylen - 2) {
  112. READ_NEXT_PAIR(v1, v2, i);
  113. }
  114. i -= 2; /* prevent from for-loop += 2*/
  115. /* Configure matched pairs and
  116. * skip to end of if-else.
  117. */
  118. } else {
  119. READ_NEXT_PAIR(v1, v2, i);
  120. while (v2 != 0xDEAD &&
  121. v2 != 0xCDEF &&
  122. v2 != 0xCDCD &&
  123. i < arraylen - 2) {
  124. rtl_bb_delay(hw,
  125. v1, v2);
  126. READ_NEXT_PAIR(v1, v2, i);
  127. }
  128. while (v2 != 0xDEAD && i < arraylen - 2)
  129. READ_NEXT_PAIR(v1, v2, i);
  130. }
  131. }
  132. }
  133. } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
  134. arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
  135. array_table = RTL8723BEAGCTAB_1TARRAY;
  136. for (i = 0; i < arraylen; i = i + 2) {
  137. v1 = array_table[i];
  138. v2 = array_table[i+1];
  139. if (v1 < 0xCDCDCDCD) {
  140. rtl_set_bbreg(hw, array_table[i],
  141. MASKDWORD,
  142. array_table[i + 1]);
  143. udelay(1);
  144. continue;
  145. } else {/*This line is the start line of branch.*/
  146. if (!_rtl8723be_check_condition(hw, array_table[i])) {
  147. /* Discard the following
  148. * (offset, data) pairs
  149. */
  150. READ_NEXT_PAIR(v1, v2, i);
  151. while (v2 != 0xDEAD &&
  152. v2 != 0xCDEF &&
  153. v2 != 0xCDCD &&
  154. i < arraylen - 2) {
  155. READ_NEXT_PAIR(v1, v2, i);
  156. }
  157. i -= 2; /* prevent from for-loop += 2*/
  158. /*Configure matched pairs and
  159. *skip to end of if-else.
  160. */
  161. } else {
  162. READ_NEXT_PAIR(v1, v2, i);
  163. while (v2 != 0xDEAD &&
  164. v2 != 0xCDEF &&
  165. v2 != 0xCDCD &&
  166. i < arraylen - 2) {
  167. rtl_set_bbreg(hw, array_table[i],
  168. MASKDWORD,
  169. array_table[i + 1]);
  170. udelay(1);
  171. READ_NEXT_PAIR(v1, v2, i);
  172. }
  173. while (v2 != 0xDEAD && i < arraylen - 2)
  174. READ_NEXT_PAIR(v1, v2, i);
  175. }
  176. }
  177. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  178. "The agctab_array_table[0] is "
  179. "%x Rtl818EEPHY_REGArray[1] is %x\n",
  180. array_table[i], array_table[i + 1]);
  181. }
  182. }
  183. return true;
  184. }
  185. static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
  186. {
  187. u8 index = 0;
  188. switch (regaddr) {
  189. case RTXAGC_A_RATE18_06:
  190. case RTXAGC_B_RATE18_06:
  191. index = 0;
  192. break;
  193. case RTXAGC_A_RATE54_24:
  194. case RTXAGC_B_RATE54_24:
  195. index = 1;
  196. break;
  197. case RTXAGC_A_CCK1_MCS32:
  198. case RTXAGC_B_CCK1_55_MCS32:
  199. index = 2;
  200. break;
  201. case RTXAGC_B_CCK11_A_CCK2_11:
  202. index = 3;
  203. break;
  204. case RTXAGC_A_MCS03_MCS00:
  205. case RTXAGC_B_MCS03_MCS00:
  206. index = 4;
  207. break;
  208. case RTXAGC_A_MCS07_MCS04:
  209. case RTXAGC_B_MCS07_MCS04:
  210. index = 5;
  211. break;
  212. case RTXAGC_A_MCS11_MCS08:
  213. case RTXAGC_B_MCS11_MCS08:
  214. index = 6;
  215. break;
  216. case RTXAGC_A_MCS15_MCS12:
  217. case RTXAGC_B_MCS15_MCS12:
  218. index = 7;
  219. break;
  220. default:
  221. regaddr &= 0xFFF;
  222. if (regaddr >= 0xC20 && regaddr <= 0xC4C)
  223. index = (u8) ((regaddr - 0xC20) / 4);
  224. else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
  225. index = (u8) ((regaddr - 0xE20) / 4);
  226. break;
  227. };
  228. return index;
  229. }
  230. u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
  231. u32 regaddr, u32 bitmask)
  232. {
  233. struct rtl_priv *rtlpriv = rtl_priv(hw);
  234. u32 original_value, readback_value, bitshift;
  235. unsigned long flags;
  236. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  237. "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  238. regaddr, rfpath, bitmask);
  239. spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  240. original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
  241. bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  242. readback_value = (original_value & bitmask) >> bitshift;
  243. spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  244. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  245. "regaddr(%#x), rfpath(%#x), "
  246. "bitmask(%#x), original_value(%#x)\n",
  247. regaddr, rfpath, bitmask, original_value);
  248. return readback_value;
  249. }
  250. void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
  251. u32 regaddr, u32 bitmask, u32 data)
  252. {
  253. struct rtl_priv *rtlpriv = rtl_priv(hw);
  254. u32 original_value, bitshift;
  255. unsigned long flags;
  256. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  257. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  258. regaddr, bitmask, data, path);
  259. spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  260. if (bitmask != RFREG_OFFSET_MASK) {
  261. original_value = rtl8723_phy_rf_serial_read(hw, path,
  262. regaddr);
  263. bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  264. data = ((original_value & (~bitmask)) |
  265. (data << bitshift));
  266. }
  267. rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
  268. spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  269. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  270. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  271. regaddr, bitmask, data, path);
  272. }
  273. bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
  274. {
  275. struct rtl_priv *rtlpriv = rtl_priv(hw);
  276. bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
  277. rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
  278. return rtstatus;
  279. }
  280. bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
  281. {
  282. bool rtstatus = true;
  283. struct rtl_priv *rtlpriv = rtl_priv(hw);
  284. u16 regval;
  285. u8 reg_hwparafile = 1;
  286. u32 tmp;
  287. u8 crystalcap = rtlpriv->efuse.crystalcap;
  288. rtl8723_phy_init_bb_rf_reg_def(hw);
  289. regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
  290. rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
  291. regval | BIT(13) | BIT(0) | BIT(1));
  292. rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
  293. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
  294. FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
  295. FEN_BB_GLB_RSTN | FEN_BBRSTB);
  296. tmp = rtl_read_dword(rtlpriv, 0x4c);
  297. rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
  298. rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
  299. if (reg_hwparafile == 1)
  300. rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
  301. crystalcap = crystalcap & 0x3F;
  302. rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
  303. (crystalcap | crystalcap << 6));
  304. return rtstatus;
  305. }
  306. bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
  307. {
  308. return rtl8723be_phy_rf6052_config(hw);
  309. }
  310. static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
  311. u32 data, enum radio_path rfpath,
  312. u32 regaddr)
  313. {
  314. if (addr == 0xfe || addr == 0xffe) {
  315. mdelay(50);
  316. } else {
  317. rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
  318. udelay(1);
  319. }
  320. }
  321. static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
  322. u32 addr, u32 data)
  323. {
  324. u32 content = 0x1000; /*RF Content: radio_a_txt*/
  325. u32 maskforphyset = (u32)(content & 0xE000);
  326. _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
  327. addr | maskforphyset);
  328. }
  329. static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
  330. {
  331. struct rtl_priv *rtlpriv = rtl_priv(hw);
  332. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  333. u8 band, path, txnum, section;
  334. for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
  335. for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
  336. for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
  337. for (section = 0;
  338. section < TX_PWR_BY_RATE_NUM_SECTION;
  339. ++section)
  340. rtlphy->tx_power_by_rate_offset[band]
  341. [path][txnum][section] = 0;
  342. }
  343. static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band,
  344. u8 path, u8 rate_section,
  345. u8 txnum, u8 value)
  346. {
  347. struct rtl_priv *rtlpriv = rtl_priv(hw);
  348. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  349. if (path > RF90_PATH_D) {
  350. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  351. "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
  352. path);
  353. return;
  354. }
  355. if (band == BAND_ON_2_4G) {
  356. switch (rate_section) {
  357. case CCK:
  358. rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
  359. break;
  360. case OFDM:
  361. rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
  362. break;
  363. case HT_MCS0_MCS7:
  364. rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
  365. break;
  366. case HT_MCS8_MCS15:
  367. rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
  368. break;
  369. default:
  370. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  371. "Invalid RateSection %d in Band 2.4G, Rf Path"
  372. " %d, %dTx in PHY_SetTxPowerByRateBase()\n",
  373. rate_section, path, txnum);
  374. break;
  375. };
  376. } else {
  377. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  378. "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
  379. band);
  380. }
  381. }
  382. static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path,
  383. u8 txnum, u8 rate_section)
  384. {
  385. struct rtl_priv *rtlpriv = rtl_priv(hw);
  386. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  387. u8 value = 0;
  388. if (path > RF90_PATH_D) {
  389. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  390. "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
  391. path);
  392. return 0;
  393. }
  394. if (band == BAND_ON_2_4G) {
  395. switch (rate_section) {
  396. case CCK:
  397. value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
  398. break;
  399. case OFDM:
  400. value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
  401. break;
  402. case HT_MCS0_MCS7:
  403. value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
  404. break;
  405. case HT_MCS8_MCS15:
  406. value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
  407. break;
  408. default:
  409. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  410. "Invalid RateSection %d in Band 2.4G, Rf Path"
  411. " %d, %dTx in PHY_GetTxPowerByRateBase()\n",
  412. rate_section, path, txnum);
  413. break;
  414. };
  415. } else {
  416. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  417. "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
  418. band);
  419. }
  420. return value;
  421. }
  422. static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
  423. {
  424. struct rtl_priv *rtlpriv = rtl_priv(hw);
  425. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  426. u16 raw_value = 0;
  427. u8 base = 0, path = 0;
  428. for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
  429. if (path == RF90_PATH_A) {
  430. raw_value = (u16) (rtlphy->tx_power_by_rate_offset
  431. [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
  432. base = (raw_value >> 4) * 10 + (raw_value & 0xF);
  433. phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK,
  434. RF_1TX, base);
  435. } else if (path == RF90_PATH_B) {
  436. raw_value = (u16) (rtlphy->tx_power_by_rate_offset
  437. [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
  438. base = (raw_value >> 4) * 10 + (raw_value & 0xF);
  439. phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
  440. CCK, RF_1TX, base);
  441. }
  442. raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  443. [path][RF_1TX][1] >> 24) & 0xFF;
  444. base = (raw_value >> 4) * 10 + (raw_value & 0xF);
  445. phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX,
  446. base);
  447. raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  448. [path][RF_1TX][5] >> 24) & 0xFF;
  449. base = (raw_value >> 4) * 10 + (raw_value & 0xF);
  450. phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7,
  451. RF_1TX, base);
  452. raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  453. [path][RF_2TX][7] >> 24) & 0xFF;
  454. base = (raw_value >> 4) * 10 + (raw_value & 0xF);
  455. phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
  456. HT_MCS8_MCS15, RF_2TX, base);
  457. }
  458. }
  459. static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val)
  460. {
  461. char i = 0;
  462. u8 temp_value = 0;
  463. u32 temp_data = 0;
  464. for (i = 3; i >= 0; --i) {
  465. if (i >= start && i <= end) {
  466. /* Get the exact value */
  467. temp_value = (u8) (*data >> (i * 8)) & 0xF;
  468. temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10;
  469. /* Change the value to a relative value */
  470. temp_value = (temp_value > base_val) ?
  471. temp_value - base_val :
  472. base_val - temp_value;
  473. } else {
  474. temp_value = (u8) (*data >> (i * 8)) & 0xFF;
  475. }
  476. temp_data <<= 8;
  477. temp_data |= temp_value;
  478. }
  479. *data = temp_data;
  480. }
  481. static void conv_dbm_to_rel(struct ieee80211_hw *hw)
  482. {
  483. struct rtl_priv *rtlpriv = rtl_priv(hw);
  484. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  485. u8 base = 0, rfpath = RF90_PATH_A;
  486. base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
  487. RF_1TX, CCK);
  488. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  489. [rfpath][RF_1TX][2]), 1, 1, base);
  490. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  491. [rfpath][RF_1TX][3]), 1, 3, base);
  492. base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
  493. RF_1TX, OFDM);
  494. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  495. [rfpath][RF_1TX][0]), 0, 3, base);
  496. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  497. [rfpath][RF_1TX][1]), 0, 3, base);
  498. base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
  499. RF_1TX, HT_MCS0_MCS7);
  500. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  501. [rfpath][RF_1TX][4]), 0, 3, base);
  502. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  503. [rfpath][RF_1TX][5]), 0, 3, base);
  504. base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
  505. RF_2TX, HT_MCS8_MCS15);
  506. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  507. [rfpath][RF_2TX][6]), 0, 3, base);
  508. phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
  509. [rfpath][RF_2TX][7]), 0, 3, base);
  510. RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
  511. "<=== conv_dbm_to_rel()\n");
  512. }
  513. static void _rtl8723be_phy_txpower_by_rate_configuration(
  514. struct ieee80211_hw *hw)
  515. {
  516. _rtl8723be_phy_store_txpower_by_rate_base(hw);
  517. conv_dbm_to_rel(hw);
  518. }
  519. static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
  520. {
  521. struct rtl_priv *rtlpriv = rtl_priv(hw);
  522. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  523. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  524. bool rtstatus;
  525. rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
  526. BASEBAND_CONFIG_PHY_REG);
  527. if (!rtstatus) {
  528. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
  529. return false;
  530. }
  531. _rtl8723be_phy_init_tx_power_by_rate(hw);
  532. if (!rtlefuse->autoload_failflag) {
  533. rtlphy->pwrgroup_cnt = 0;
  534. rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
  535. BASEBAND_CONFIG_PHY_REG);
  536. }
  537. _rtl8723be_phy_txpower_by_rate_configuration(hw);
  538. if (!rtstatus) {
  539. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
  540. return false;
  541. }
  542. rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
  543. BASEBAND_CONFIG_AGC_TAB);
  544. if (!rtstatus) {
  545. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
  546. return false;
  547. }
  548. rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
  549. RFPGA0_XA_HSSIPARAMETER2,
  550. 0x200));
  551. return true;
  552. }
  553. static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
  554. u32 band, u32 rfpath,
  555. u32 txnum, u32 regaddr,
  556. u32 bitmask, u32 data)
  557. {
  558. struct rtl_priv *rtlpriv = rtl_priv(hw);
  559. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  560. u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
  561. if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
  562. RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
  563. "Invalid Band %d\n", band);
  564. return;
  565. }
  566. if (rfpath > TX_PWR_BY_RATE_NUM_RF) {
  567. RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
  568. "Invalid RfPath %d\n", rfpath);
  569. return;
  570. }
  571. if (txnum > TX_PWR_BY_RATE_NUM_RF) {
  572. RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
  573. "Invalid TxNum %d\n", txnum);
  574. return;
  575. }
  576. rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
  577. data;
  578. }
  579. static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  580. u8 configtype)
  581. {
  582. struct rtl_priv *rtlpriv = rtl_priv(hw);
  583. int i;
  584. u32 *phy_regarray_table_pg;
  585. u16 phy_regarray_pg_len;
  586. u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
  587. phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
  588. phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
  589. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  590. for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
  591. v1 = phy_regarray_table_pg[i];
  592. v2 = phy_regarray_table_pg[i+1];
  593. v3 = phy_regarray_table_pg[i+2];
  594. v4 = phy_regarray_table_pg[i+3];
  595. v5 = phy_regarray_table_pg[i+4];
  596. v6 = phy_regarray_table_pg[i+5];
  597. if (v1 < 0xcdcdcdcd) {
  598. if (phy_regarray_table_pg[i] == 0xfe ||
  599. phy_regarray_table_pg[i] == 0xffe)
  600. mdelay(50);
  601. else
  602. _rtl8723be_store_tx_power_by_rate(hw,
  603. v1, v2, v3, v4, v5, v6);
  604. continue;
  605. } else {
  606. /*don't need the hw_body*/
  607. if (!_rtl8723be_check_condition(hw,
  608. phy_regarray_table_pg[i])) {
  609. i += 2; /* skip the pair of expression*/
  610. v1 = phy_regarray_table_pg[i];
  611. v2 = phy_regarray_table_pg[i+1];
  612. v3 = phy_regarray_table_pg[i+2];
  613. while (v2 != 0xDEAD) {
  614. i += 3;
  615. v1 = phy_regarray_table_pg[i];
  616. v2 = phy_regarray_table_pg[i+1];
  617. v3 = phy_regarray_table_pg[i+2];
  618. }
  619. }
  620. }
  621. }
  622. } else {
  623. RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
  624. "configtype != BaseBand_Config_PHY_REG\n");
  625. }
  626. return true;
  627. }
  628. bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
  629. enum radio_path rfpath)
  630. {
  631. #define READ_NEXT_RF_PAIR(v1, v2, i) \
  632. do { \
  633. i += 2; \
  634. v1 = radioa_array_table[i]; \
  635. v2 = radioa_array_table[i+1]; \
  636. } while (0)
  637. int i;
  638. bool rtstatus = true;
  639. u32 *radioa_array_table;
  640. u16 radioa_arraylen;
  641. struct rtl_priv *rtlpriv = rtl_priv(hw);
  642. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  643. u32 v1 = 0, v2 = 0;
  644. radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
  645. radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
  646. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  647. "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
  648. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
  649. rtstatus = true;
  650. switch (rfpath) {
  651. case RF90_PATH_A:
  652. for (i = 0; i < radioa_arraylen; i = i + 2) {
  653. v1 = radioa_array_table[i];
  654. v2 = radioa_array_table[i+1];
  655. if (v1 < 0xcdcdcdcd) {
  656. _rtl8723be_config_rf_radio_a(hw, v1, v2);
  657. } else { /*This line is the start line of branch.*/
  658. if (!_rtl8723be_check_condition(hw,
  659. radioa_array_table[i])) {
  660. /* Discard the following
  661. * (offset, data) pairs
  662. */
  663. READ_NEXT_RF_PAIR(v1, v2, i);
  664. while (v2 != 0xDEAD &&
  665. v2 != 0xCDEF &&
  666. v2 != 0xCDCD &&
  667. i < radioa_arraylen - 2)
  668. READ_NEXT_RF_PAIR(v1, v2, i);
  669. i -= 2; /* prevent from for-loop += 2*/
  670. } else {
  671. /* Configure matched pairs
  672. * and skip to end of if-else.
  673. */
  674. READ_NEXT_RF_PAIR(v1, v2, i);
  675. while (v2 != 0xDEAD &&
  676. v2 != 0xCDEF &&
  677. v2 != 0xCDCD &&
  678. i < radioa_arraylen - 2) {
  679. _rtl8723be_config_rf_radio_a(hw,
  680. v1, v2);
  681. READ_NEXT_RF_PAIR(v1, v2, i);
  682. }
  683. while (v2 != 0xDEAD &&
  684. i < radioa_arraylen - 2) {
  685. READ_NEXT_RF_PAIR(v1, v2, i);
  686. }
  687. }
  688. }
  689. }
  690. if (rtlhal->oem_id == RT_CID_819X_HP)
  691. _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
  692. break;
  693. case RF90_PATH_B:
  694. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  695. "switch case not process\n");
  696. break;
  697. case RF90_PATH_C:
  698. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  699. "switch case not process\n");
  700. break;
  701. case RF90_PATH_D:
  702. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  703. "switch case not process\n");
  704. break;
  705. }
  706. return true;
  707. }
  708. void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
  709. {
  710. struct rtl_priv *rtlpriv = rtl_priv(hw);
  711. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  712. rtlphy->default_initialgain[0] =
  713. (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
  714. rtlphy->default_initialgain[1] =
  715. (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
  716. rtlphy->default_initialgain[2] =
  717. (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
  718. rtlphy->default_initialgain[3] =
  719. (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
  720. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  721. "Default initial gain (c50 = 0x%x, "
  722. "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
  723. rtlphy->default_initialgain[0],
  724. rtlphy->default_initialgain[1],
  725. rtlphy->default_initialgain[2],
  726. rtlphy->default_initialgain[3]);
  727. rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
  728. MASKBYTE0);
  729. rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
  730. MASKDWORD);
  731. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  732. "Default framesync (0x%x) = 0x%x\n",
  733. ROFDM0_RXDETECTOR3, rtlphy->framesync);
  734. }
  735. void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
  736. {
  737. struct rtl_priv *rtlpriv = rtl_priv(hw);
  738. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  739. u8 txpwr_level;
  740. long txpwr_dbm;
  741. txpwr_level = rtlphy->cur_cck_txpwridx;
  742. txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
  743. txpwr_level);
  744. txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
  745. if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
  746. txpwr_dbm)
  747. txpwr_dbm =
  748. rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
  749. txpwr_level);
  750. txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
  751. if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
  752. txpwr_level) > txpwr_dbm)
  753. txpwr_dbm =
  754. rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
  755. txpwr_level);
  756. *powerlevel = txpwr_dbm;
  757. }
  758. static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
  759. u8 rate)
  760. {
  761. u8 rate_section = 0;
  762. switch (rate) {
  763. case DESC92C_RATE1M:
  764. rate_section = 2;
  765. break;
  766. case DESC92C_RATE2M:
  767. case DESC92C_RATE5_5M:
  768. if (path == RF90_PATH_A)
  769. rate_section = 3;
  770. else if (path == RF90_PATH_B)
  771. rate_section = 2;
  772. break;
  773. case DESC92C_RATE11M:
  774. rate_section = 3;
  775. break;
  776. case DESC92C_RATE6M:
  777. case DESC92C_RATE9M:
  778. case DESC92C_RATE12M:
  779. case DESC92C_RATE18M:
  780. rate_section = 0;
  781. break;
  782. case DESC92C_RATE24M:
  783. case DESC92C_RATE36M:
  784. case DESC92C_RATE48M:
  785. case DESC92C_RATE54M:
  786. rate_section = 1;
  787. break;
  788. case DESC92C_RATEMCS0:
  789. case DESC92C_RATEMCS1:
  790. case DESC92C_RATEMCS2:
  791. case DESC92C_RATEMCS3:
  792. rate_section = 4;
  793. break;
  794. case DESC92C_RATEMCS4:
  795. case DESC92C_RATEMCS5:
  796. case DESC92C_RATEMCS6:
  797. case DESC92C_RATEMCS7:
  798. rate_section = 5;
  799. break;
  800. case DESC92C_RATEMCS8:
  801. case DESC92C_RATEMCS9:
  802. case DESC92C_RATEMCS10:
  803. case DESC92C_RATEMCS11:
  804. rate_section = 6;
  805. break;
  806. case DESC92C_RATEMCS12:
  807. case DESC92C_RATEMCS13:
  808. case DESC92C_RATEMCS14:
  809. case DESC92C_RATEMCS15:
  810. rate_section = 7;
  811. break;
  812. default:
  813. RT_ASSERT(true, "Rate_Section is Illegal\n");
  814. break;
  815. }
  816. return rate_section;
  817. }
  818. static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
  819. enum band_type band,
  820. enum radio_path rfpath, u8 rate)
  821. {
  822. struct rtl_priv *rtlpriv = rtl_priv(hw);
  823. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  824. u8 shift = 0, rate_section, tx_num;
  825. char tx_pwr_diff = 0;
  826. rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
  827. rate);
  828. tx_num = RF_TX_NUM_NONIMPLEMENT;
  829. if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
  830. if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
  831. tx_num = RF_2TX;
  832. else
  833. tx_num = RF_1TX;
  834. }
  835. switch (rate) {
  836. case DESC92C_RATE6M:
  837. case DESC92C_RATE24M:
  838. case DESC92C_RATEMCS0:
  839. case DESC92C_RATEMCS4:
  840. case DESC92C_RATEMCS8:
  841. case DESC92C_RATEMCS12:
  842. shift = 0;
  843. break;
  844. case DESC92C_RATE1M:
  845. case DESC92C_RATE2M:
  846. case DESC92C_RATE9M:
  847. case DESC92C_RATE36M:
  848. case DESC92C_RATEMCS1:
  849. case DESC92C_RATEMCS5:
  850. case DESC92C_RATEMCS9:
  851. case DESC92C_RATEMCS13:
  852. shift = 8;
  853. break;
  854. case DESC92C_RATE5_5M:
  855. case DESC92C_RATE12M:
  856. case DESC92C_RATE48M:
  857. case DESC92C_RATEMCS2:
  858. case DESC92C_RATEMCS6:
  859. case DESC92C_RATEMCS10:
  860. case DESC92C_RATEMCS14:
  861. shift = 16;
  862. break;
  863. case DESC92C_RATE11M:
  864. case DESC92C_RATE18M:
  865. case DESC92C_RATE54M:
  866. case DESC92C_RATEMCS3:
  867. case DESC92C_RATEMCS7:
  868. case DESC92C_RATEMCS11:
  869. case DESC92C_RATEMCS15:
  870. shift = 24;
  871. break;
  872. default:
  873. RT_ASSERT(true, "Rate_Section is Illegal\n");
  874. break;
  875. }
  876. tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
  877. [rate_section] >> shift) & 0xff;
  878. return tx_pwr_diff;
  879. }
  880. static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
  881. u8 rate, u8 bandwidth, u8 channel)
  882. {
  883. struct rtl_priv *rtlpriv = rtl_priv(hw);
  884. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  885. u8 index = (channel - 1);
  886. u8 txpower;
  887. u8 power_diff_byrate = 0;
  888. if (channel > 14 || channel < 1) {
  889. index = 0;
  890. RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
  891. "Illegal channel!\n");
  892. }
  893. if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
  894. txpower = rtlefuse->txpwrlevel_cck[path][index];
  895. else if (DESC92C_RATE6M <= rate)
  896. txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
  897. else
  898. RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
  899. "invalid rate\n");
  900. if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
  901. !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
  902. txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
  903. if (bandwidth == HT_CHANNEL_WIDTH_20) {
  904. if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
  905. txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
  906. if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
  907. txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
  908. } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
  909. if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
  910. txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
  911. if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
  912. txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
  913. }
  914. if (rtlefuse->eeprom_regulatory != 2)
  915. power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
  916. BAND_ON_2_4G,
  917. path, rate);
  918. txpower += power_diff_byrate;
  919. if (txpower > MAX_POWER_INDEX)
  920. txpower = MAX_POWER_INDEX;
  921. return txpower;
  922. }
  923. static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
  924. u8 power_index, u8 path, u8 rate)
  925. {
  926. struct rtl_priv *rtlpriv = rtl_priv(hw);
  927. if (path == RF90_PATH_A) {
  928. switch (rate) {
  929. case DESC92C_RATE1M:
  930. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
  931. MASKBYTE1, power_index);
  932. break;
  933. case DESC92C_RATE2M:
  934. rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
  935. MASKBYTE1, power_index);
  936. break;
  937. case DESC92C_RATE5_5M:
  938. rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
  939. MASKBYTE2, power_index);
  940. break;
  941. case DESC92C_RATE11M:
  942. rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
  943. MASKBYTE3, power_index);
  944. break;
  945. case DESC92C_RATE6M:
  946. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
  947. MASKBYTE0, power_index);
  948. break;
  949. case DESC92C_RATE9M:
  950. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
  951. MASKBYTE1, power_index);
  952. break;
  953. case DESC92C_RATE12M:
  954. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
  955. MASKBYTE2, power_index);
  956. break;
  957. case DESC92C_RATE18M:
  958. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
  959. MASKBYTE3, power_index);
  960. break;
  961. case DESC92C_RATE24M:
  962. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
  963. MASKBYTE0, power_index);
  964. break;
  965. case DESC92C_RATE36M:
  966. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
  967. MASKBYTE1, power_index);
  968. break;
  969. case DESC92C_RATE48M:
  970. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
  971. MASKBYTE2, power_index);
  972. break;
  973. case DESC92C_RATE54M:
  974. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
  975. MASKBYTE3, power_index);
  976. break;
  977. case DESC92C_RATEMCS0:
  978. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
  979. MASKBYTE0, power_index);
  980. break;
  981. case DESC92C_RATEMCS1:
  982. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
  983. MASKBYTE1, power_index);
  984. break;
  985. case DESC92C_RATEMCS2:
  986. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
  987. MASKBYTE2, power_index);
  988. break;
  989. case DESC92C_RATEMCS3:
  990. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
  991. MASKBYTE3, power_index);
  992. break;
  993. case DESC92C_RATEMCS4:
  994. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
  995. MASKBYTE0, power_index);
  996. break;
  997. case DESC92C_RATEMCS5:
  998. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
  999. MASKBYTE1, power_index);
  1000. break;
  1001. case DESC92C_RATEMCS6:
  1002. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
  1003. MASKBYTE2, power_index);
  1004. break;
  1005. case DESC92C_RATEMCS7:
  1006. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
  1007. MASKBYTE3, power_index);
  1008. break;
  1009. case DESC92C_RATEMCS8:
  1010. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
  1011. MASKBYTE0, power_index);
  1012. break;
  1013. case DESC92C_RATEMCS9:
  1014. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
  1015. MASKBYTE1, power_index);
  1016. break;
  1017. case DESC92C_RATEMCS10:
  1018. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
  1019. MASKBYTE2, power_index);
  1020. break;
  1021. case DESC92C_RATEMCS11:
  1022. rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
  1023. MASKBYTE3, power_index);
  1024. break;
  1025. default:
  1026. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
  1027. "Invalid Rate!!\n");
  1028. break;
  1029. }
  1030. } else {
  1031. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
  1032. }
  1033. }
  1034. void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
  1035. {
  1036. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  1037. u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
  1038. DESC92C_RATE5_5M, DESC92C_RATE11M};
  1039. u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
  1040. DESC92C_RATE12M, DESC92C_RATE18M,
  1041. DESC92C_RATE24M, DESC92C_RATE36M,
  1042. DESC92C_RATE48M, DESC92C_RATE54M};
  1043. u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
  1044. DESC92C_RATEMCS2, DESC92C_RATEMCS3,
  1045. DESC92C_RATEMCS4, DESC92C_RATEMCS5,
  1046. DESC92C_RATEMCS6, DESC92C_RATEMCS7};
  1047. u8 i, size;
  1048. u8 power_index;
  1049. if (!rtlefuse->txpwr_fromeprom)
  1050. return;
  1051. size = sizeof(cck_rates) / sizeof(u8);
  1052. for (i = 0; i < size; i++) {
  1053. power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
  1054. cck_rates[i],
  1055. rtl_priv(hw)->phy.current_chan_bw,
  1056. channel);
  1057. _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
  1058. cck_rates[i]);
  1059. }
  1060. size = sizeof(ofdm_rates) / sizeof(u8);
  1061. for (i = 0; i < size; i++) {
  1062. power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
  1063. ofdm_rates[i],
  1064. rtl_priv(hw)->phy.current_chan_bw,
  1065. channel);
  1066. _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
  1067. ofdm_rates[i]);
  1068. }
  1069. size = sizeof(ht_rates_1t) / sizeof(u8);
  1070. for (i = 0; i < size; i++) {
  1071. power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
  1072. ht_rates_1t[i],
  1073. rtl_priv(hw)->phy.current_chan_bw,
  1074. channel);
  1075. _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
  1076. ht_rates_1t[i]);
  1077. }
  1078. }
  1079. void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
  1080. {
  1081. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1082. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1083. enum io_type iotype;
  1084. if (!is_hal_stop(rtlhal)) {
  1085. switch (operation) {
  1086. case SCAN_OPT_BACKUP:
  1087. iotype = IO_CMD_PAUSE_DM_BY_SCAN;
  1088. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
  1089. (u8 *)&iotype);
  1090. break;
  1091. case SCAN_OPT_RESTORE:
  1092. iotype = IO_CMD_RESUME_DM_BY_SCAN;
  1093. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
  1094. (u8 *)&iotype);
  1095. break;
  1096. default:
  1097. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1098. "Unknown Scan Backup operation.\n");
  1099. break;
  1100. }
  1101. }
  1102. }
  1103. void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
  1104. {
  1105. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1106. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1107. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1108. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  1109. u8 reg_bw_opmode;
  1110. u8 reg_prsr_rsc;
  1111. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
  1112. "Switch to %s bandwidth\n",
  1113. rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
  1114. "20MHz" : "40MHz");
  1115. if (is_hal_stop(rtlhal)) {
  1116. rtlphy->set_bwmode_inprogress = false;
  1117. return;
  1118. }
  1119. reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
  1120. reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
  1121. switch (rtlphy->current_chan_bw) {
  1122. case HT_CHANNEL_WIDTH_20:
  1123. reg_bw_opmode |= BW_OPMODE_20MHZ;
  1124. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  1125. break;
  1126. case HT_CHANNEL_WIDTH_20_40:
  1127. reg_bw_opmode &= ~BW_OPMODE_20MHZ;
  1128. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  1129. reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
  1130. (mac->cur_40_prime_sc << 5);
  1131. rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
  1132. break;
  1133. default:
  1134. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1135. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  1136. break;
  1137. }
  1138. switch (rtlphy->current_chan_bw) {
  1139. case HT_CHANNEL_WIDTH_20:
  1140. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
  1141. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
  1142. break;
  1143. case HT_CHANNEL_WIDTH_20_40:
  1144. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
  1145. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
  1146. rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
  1147. (mac->cur_40_prime_sc >> 1));
  1148. rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
  1149. rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
  1150. (mac->cur_40_prime_sc ==
  1151. HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
  1152. break;
  1153. default:
  1154. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1155. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  1156. break;
  1157. }
  1158. rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
  1159. rtlphy->set_bwmode_inprogress = false;
  1160. RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
  1161. }
  1162. void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
  1163. enum nl80211_channel_type ch_type)
  1164. {
  1165. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1166. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1167. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1168. u8 tmp_bw = rtlphy->current_chan_bw;
  1169. if (rtlphy->set_bwmode_inprogress)
  1170. return;
  1171. rtlphy->set_bwmode_inprogress = true;
  1172. if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
  1173. rtl8723be_phy_set_bw_mode_callback(hw);
  1174. } else {
  1175. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1176. "false driver sleep or unload\n");
  1177. rtlphy->set_bwmode_inprogress = false;
  1178. rtlphy->current_chan_bw = tmp_bw;
  1179. }
  1180. }
  1181. void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
  1182. {
  1183. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1184. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1185. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1186. u32 delay;
  1187. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
  1188. "switch to channel%d\n", rtlphy->current_channel);
  1189. if (is_hal_stop(rtlhal))
  1190. return;
  1191. do {
  1192. if (!rtlphy->sw_chnl_inprogress)
  1193. break;
  1194. if (!rtl8723be_phy_sw_chn_step_by_step(hw,
  1195. rtlphy->current_channel,
  1196. &rtlphy->sw_chnl_stage,
  1197. &rtlphy->sw_chnl_step,
  1198. &delay)) {
  1199. if (delay > 0)
  1200. mdelay(delay);
  1201. else
  1202. continue;
  1203. } else {
  1204. rtlphy->sw_chnl_inprogress = false;
  1205. }
  1206. break;
  1207. } while (true);
  1208. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
  1209. }
  1210. u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
  1211. {
  1212. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1213. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1214. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1215. if (rtlphy->sw_chnl_inprogress)
  1216. return 0;
  1217. if (rtlphy->set_bwmode_inprogress)
  1218. return 0;
  1219. RT_ASSERT((rtlphy->current_channel <= 14),
  1220. "WIRELESS_MODE_G but channel>14");
  1221. rtlphy->sw_chnl_inprogress = true;
  1222. rtlphy->sw_chnl_stage = 0;
  1223. rtlphy->sw_chnl_step = 0;
  1224. if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
  1225. rtl8723be_phy_sw_chnl_callback(hw);
  1226. RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
  1227. "sw_chnl_inprogress false schdule "
  1228. "workitem current channel %d\n",
  1229. rtlphy->current_channel);
  1230. rtlphy->sw_chnl_inprogress = false;
  1231. } else {
  1232. RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
  1233. "sw_chnl_inprogress false driver sleep or"
  1234. " unload\n");
  1235. rtlphy->sw_chnl_inprogress = false;
  1236. }
  1237. return 1;
  1238. }
  1239. static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
  1240. u8 channel, u8 *stage,
  1241. u8 *step, u32 *delay)
  1242. {
  1243. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1244. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1245. struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
  1246. u32 precommoncmdcnt;
  1247. struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
  1248. u32 postcommoncmdcnt;
  1249. struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
  1250. u32 rfdependcmdcnt;
  1251. struct swchnlcmd *currentcmd = NULL;
  1252. u8 rfpath;
  1253. u8 num_total_rfpath = rtlphy->num_total_rfpath;
  1254. precommoncmdcnt = 0;
  1255. rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
  1256. MAX_PRECMD_CNT,
  1257. CMDID_SET_TXPOWEROWER_LEVEL,
  1258. 0, 0, 0);
  1259. rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
  1260. MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
  1261. postcommoncmdcnt = 0;
  1262. rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
  1263. MAX_POSTCMD_CNT, CMDID_END,
  1264. 0, 0, 0);
  1265. rfdependcmdcnt = 0;
  1266. RT_ASSERT((channel >= 1 && channel <= 14),
  1267. "illegal channel for Zebra: %d\n", channel);
  1268. rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
  1269. MAX_RFDEPENDCMD_CNT,
  1270. CMDID_RF_WRITEREG,
  1271. RF_CHNLBW, channel, 10);
  1272. rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
  1273. MAX_RFDEPENDCMD_CNT,
  1274. CMDID_END, 0, 0, 0);
  1275. do {
  1276. switch (*stage) {
  1277. case 0:
  1278. currentcmd = &precommoncmd[*step];
  1279. break;
  1280. case 1:
  1281. currentcmd = &rfdependcmd[*step];
  1282. break;
  1283. case 2:
  1284. currentcmd = &postcommoncmd[*step];
  1285. break;
  1286. }
  1287. if (currentcmd->cmdid == CMDID_END) {
  1288. if ((*stage) == 2) {
  1289. return true;
  1290. } else {
  1291. (*stage)++;
  1292. (*step) = 0;
  1293. continue;
  1294. }
  1295. }
  1296. switch (currentcmd->cmdid) {
  1297. case CMDID_SET_TXPOWEROWER_LEVEL:
  1298. rtl8723be_phy_set_txpower_level(hw, channel);
  1299. break;
  1300. case CMDID_WRITEPORT_ULONG:
  1301. rtl_write_dword(rtlpriv, currentcmd->para1,
  1302. currentcmd->para2);
  1303. break;
  1304. case CMDID_WRITEPORT_USHORT:
  1305. rtl_write_word(rtlpriv, currentcmd->para1,
  1306. (u16) currentcmd->para2);
  1307. break;
  1308. case CMDID_WRITEPORT_UCHAR:
  1309. rtl_write_byte(rtlpriv, currentcmd->para1,
  1310. (u8) currentcmd->para2);
  1311. break;
  1312. case CMDID_RF_WRITEREG:
  1313. for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
  1314. rtlphy->rfreg_chnlval[rfpath] =
  1315. ((rtlphy->rfreg_chnlval[rfpath] &
  1316. 0xfffffc00) | currentcmd->para2);
  1317. rtl_set_rfreg(hw, (enum radio_path)rfpath,
  1318. currentcmd->para1,
  1319. RFREG_OFFSET_MASK,
  1320. rtlphy->rfreg_chnlval[rfpath]);
  1321. }
  1322. break;
  1323. default:
  1324. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1325. "switch case not process\n");
  1326. break;
  1327. }
  1328. break;
  1329. } while (true);
  1330. (*delay) = currentcmd->msdelay;
  1331. (*step)++;
  1332. return false;
  1333. }
  1334. static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
  1335. {
  1336. u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
  1337. u8 result = 0x00;
  1338. rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
  1339. rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
  1340. rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
  1341. rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
  1342. rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
  1343. rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
  1344. rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
  1345. mdelay(IQK_DELAY_TIME);
  1346. reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
  1347. reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
  1348. reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
  1349. reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
  1350. if (!(reg_eac & BIT(28)) &&
  1351. (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
  1352. (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
  1353. result |= 0x01;
  1354. return result;
  1355. }
  1356. static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
  1357. u8 c1, u8 c2)
  1358. {
  1359. u32 i, j, diff, simularity_bitmap, bound;
  1360. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1361. u8 final_candidate[2] = { 0xFF, 0xFF };
  1362. bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
  1363. if (is2t)
  1364. bound = 8;
  1365. else
  1366. bound = 4;
  1367. simularity_bitmap = 0;
  1368. for (i = 0; i < bound; i++) {
  1369. diff = (result[c1][i] > result[c2][i]) ?
  1370. (result[c1][i] - result[c2][i]) :
  1371. (result[c2][i] - result[c1][i]);
  1372. if (diff > MAX_TOLERANCE) {
  1373. if ((i == 2 || i == 6) && !simularity_bitmap) {
  1374. if (result[c1][i] + result[c1][i + 1] == 0)
  1375. final_candidate[(i / 4)] = c2;
  1376. else if (result[c2][i] + result[c2][i + 1] == 0)
  1377. final_candidate[(i / 4)] = c1;
  1378. else
  1379. simularity_bitmap |= (1 << i);
  1380. } else {
  1381. simularity_bitmap |= (1 << i);
  1382. }
  1383. }
  1384. }
  1385. if (simularity_bitmap == 0) {
  1386. for (i = 0; i < (bound / 4); i++) {
  1387. if (final_candidate[i] != 0xFF) {
  1388. for (j = i * 4; j < (i + 1) * 4 - 2; j++)
  1389. result[3][j] =
  1390. result[final_candidate[i]][j];
  1391. bresult = false;
  1392. }
  1393. }
  1394. return bresult;
  1395. } else if (!(simularity_bitmap & 0x0F)) {
  1396. for (i = 0; i < 4; i++)
  1397. result[3][i] = result[c1][i];
  1398. return false;
  1399. } else if (!(simularity_bitmap & 0xF0) && is2t) {
  1400. for (i = 4; i < 8; i++)
  1401. result[3][i] = result[c1][i];
  1402. return false;
  1403. } else {
  1404. return false;
  1405. }
  1406. }
  1407. static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
  1408. long result[][8], u8 t, bool is2t)
  1409. {
  1410. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1411. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1412. u32 i;
  1413. u8 patha_ok;
  1414. u32 adda_reg[IQK_ADDA_REG_NUM] = {
  1415. 0x85c, 0xe6c, 0xe70, 0xe74,
  1416. 0xe78, 0xe7c, 0xe80, 0xe84,
  1417. 0xe88, 0xe8c, 0xed0, 0xed4,
  1418. 0xed8, 0xedc, 0xee0, 0xeec
  1419. };
  1420. u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
  1421. 0x522, 0x550, 0x551, 0x040
  1422. };
  1423. u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
  1424. ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
  1425. RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
  1426. 0x870, 0x860,
  1427. 0x864, 0x800
  1428. };
  1429. const u32 retrycount = 2;
  1430. u32 path_sel_bb, path_sel_rf;
  1431. u8 tmp_reg_c50, tmp_reg_c58;
  1432. tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
  1433. tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
  1434. if (t == 0) {
  1435. rtl8723_save_adda_registers(hw, adda_reg,
  1436. rtlphy->adda_backup, 16);
  1437. rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
  1438. rtlphy->iqk_mac_backup);
  1439. rtl8723_save_adda_registers(hw, iqk_bb_reg,
  1440. rtlphy->iqk_bb_backup,
  1441. IQK_BB_REG_NUM);
  1442. }
  1443. rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
  1444. if (t == 0) {
  1445. rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
  1446. RFPGA0_XA_HSSIPARAMETER1,
  1447. BIT(8));
  1448. }
  1449. if (!rtlphy->rfpi_enable)
  1450. rtl8723_phy_pi_mode_switch(hw, true);
  1451. path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
  1452. path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
  1453. /*BB Setting*/
  1454. rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
  1455. rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
  1456. rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
  1457. rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
  1458. rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
  1459. rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
  1460. rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
  1461. rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
  1462. if (is2t)
  1463. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
  1464. rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
  1465. rtlphy->iqk_mac_backup);
  1466. rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
  1467. rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
  1468. rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
  1469. rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
  1470. for (i = 0; i < retrycount; i++) {
  1471. patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
  1472. if (patha_ok == 0x01) {
  1473. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  1474. "Path A Tx IQK Success!!\n");
  1475. result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
  1476. 0x3FF0000) >> 16;
  1477. result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
  1478. 0x3FF0000) >> 16;
  1479. break;
  1480. }
  1481. }
  1482. if (0 == patha_ok)
  1483. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  1484. "Path A IQK Success!!\n");
  1485. if (is2t) {
  1486. rtl8723_phy_path_a_standby(hw);
  1487. rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
  1488. }
  1489. rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
  1490. if (t != 0) {
  1491. if (!rtlphy->rfpi_enable)
  1492. rtl8723_phy_pi_mode_switch(hw, false);
  1493. rtl8723_phy_reload_adda_registers(hw, adda_reg,
  1494. rtlphy->adda_backup, 16);
  1495. rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
  1496. rtlphy->iqk_mac_backup);
  1497. rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
  1498. rtlphy->iqk_bb_backup,
  1499. IQK_BB_REG_NUM);
  1500. rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
  1501. rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
  1502. rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
  1503. rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
  1504. if (is2t) {
  1505. rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
  1506. rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
  1507. }
  1508. rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
  1509. rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
  1510. }
  1511. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
  1512. }
  1513. static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
  1514. {
  1515. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1516. u8 tmpreg;
  1517. u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
  1518. tmpreg = rtl_read_byte(rtlpriv, 0xd03);
  1519. if ((tmpreg & 0x70) != 0)
  1520. rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
  1521. else
  1522. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  1523. if ((tmpreg & 0x70) != 0) {
  1524. rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
  1525. if (is2t)
  1526. rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
  1527. MASK12BITS);
  1528. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
  1529. (rf_a_mode & 0x8FFFF) | 0x10000);
  1530. if (is2t)
  1531. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
  1532. (rf_b_mode & 0x8FFFF) | 0x10000);
  1533. }
  1534. lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
  1535. rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
  1536. rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
  1537. mdelay(100);
  1538. rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
  1539. if ((tmpreg & 0x70) != 0) {
  1540. rtl_write_byte(rtlpriv, 0xd03, tmpreg);
  1541. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
  1542. if (is2t)
  1543. rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
  1544. MASK12BITS, rf_b_mode);
  1545. } else {
  1546. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  1547. }
  1548. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
  1549. }
  1550. static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
  1551. bool bmain, bool is2t)
  1552. {
  1553. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1554. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1555. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  1556. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
  1557. if (is_hal_stop(rtlhal)) {
  1558. u8 u1btmp;
  1559. u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
  1560. rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
  1561. rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
  1562. }
  1563. if (is2t) {
  1564. if (bmain)
  1565. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1566. BIT(5) | BIT(6), 0x1);
  1567. else
  1568. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1569. BIT(5) | BIT(6), 0x2);
  1570. } else {
  1571. rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
  1572. rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
  1573. /* We use the RF definition of MAIN and AUX,
  1574. * left antenna and right antenna repectively.
  1575. * Default output at AUX.
  1576. */
  1577. if (bmain) {
  1578. rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
  1579. BIT(14) | BIT(13) | BIT(12), 0);
  1580. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1581. BIT(5) | BIT(4) | BIT(3), 0);
  1582. if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
  1583. rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
  1584. } else {
  1585. rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
  1586. BIT(14) | BIT(13) | BIT(12), 1);
  1587. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1588. BIT(5) | BIT(4) | BIT(3), 1);
  1589. if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
  1590. rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
  1591. }
  1592. }
  1593. }
  1594. #undef IQK_ADDA_REG_NUM
  1595. #undef IQK_DELAY_TIME
  1596. void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
  1597. {
  1598. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1599. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1600. long result[4][8];
  1601. u8 i, final_candidate;
  1602. bool patha_ok, pathb_ok;
  1603. long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
  1604. reg_ecc, reg_tmp = 0;
  1605. bool is12simular, is13simular, is23simular;
  1606. u32 iqk_bb_reg[9] = {
  1607. ROFDM0_XARXIQIMBALANCE,
  1608. ROFDM0_XBRXIQIMBALANCE,
  1609. ROFDM0_ECCATHRESHOLD,
  1610. ROFDM0_AGCRSSITABLE,
  1611. ROFDM0_XATXIQIMBALANCE,
  1612. ROFDM0_XBTXIQIMBALANCE,
  1613. ROFDM0_XCTXAFE,
  1614. ROFDM0_XDTXAFE,
  1615. ROFDM0_RXIQEXTANTA
  1616. };
  1617. if (recovery) {
  1618. rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
  1619. rtlphy->iqk_bb_backup, 9);
  1620. return;
  1621. }
  1622. for (i = 0; i < 8; i++) {
  1623. result[0][i] = 0;
  1624. result[1][i] = 0;
  1625. result[2][i] = 0;
  1626. result[3][i] = 0;
  1627. }
  1628. final_candidate = 0xff;
  1629. patha_ok = false;
  1630. pathb_ok = false;
  1631. is12simular = false;
  1632. is23simular = false;
  1633. is13simular = false;
  1634. for (i = 0; i < 3; i++) {
  1635. if (get_rf_type(rtlphy) == RF_2T2R)
  1636. _rtl8723be_phy_iq_calibrate(hw, result, i, true);
  1637. else
  1638. _rtl8723be_phy_iq_calibrate(hw, result, i, false);
  1639. if (i == 1) {
  1640. is12simular = phy_similarity_cmp(hw, result, 0, 1);
  1641. if (is12simular) {
  1642. final_candidate = 0;
  1643. break;
  1644. }
  1645. }
  1646. if (i == 2) {
  1647. is13simular = phy_similarity_cmp(hw, result, 0, 2);
  1648. if (is13simular) {
  1649. final_candidate = 0;
  1650. break;
  1651. }
  1652. is23simular = phy_similarity_cmp(hw, result, 1, 2);
  1653. if (is23simular) {
  1654. final_candidate = 1;
  1655. } else {
  1656. for (i = 0; i < 8; i++)
  1657. reg_tmp += result[3][i];
  1658. if (reg_tmp != 0)
  1659. final_candidate = 3;
  1660. else
  1661. final_candidate = 0xFF;
  1662. }
  1663. }
  1664. }
  1665. for (i = 0; i < 4; i++) {
  1666. reg_e94 = result[i][0];
  1667. reg_e9c = result[i][1];
  1668. reg_ea4 = result[i][2];
  1669. reg_eac = result[i][3];
  1670. reg_eb4 = result[i][4];
  1671. reg_ebc = result[i][5];
  1672. reg_ec4 = result[i][6];
  1673. reg_ecc = result[i][7];
  1674. }
  1675. if (final_candidate != 0xff) {
  1676. reg_e94 = result[final_candidate][0];
  1677. rtlphy->reg_e94 = reg_e94;
  1678. reg_e9c = result[final_candidate][1];
  1679. rtlphy->reg_e9c = reg_e9c;
  1680. reg_ea4 = result[final_candidate][2];
  1681. reg_eac = result[final_candidate][3];
  1682. reg_eb4 = result[final_candidate][4];
  1683. rtlphy->reg_eb4 = reg_eb4;
  1684. reg_ebc = result[final_candidate][5];
  1685. rtlphy->reg_ebc = reg_ebc;
  1686. reg_ec4 = result[final_candidate][6];
  1687. reg_ecc = result[final_candidate][7];
  1688. patha_ok = true;
  1689. pathb_ok = true;
  1690. } else {
  1691. rtlphy->reg_e94 = 0x100;
  1692. rtlphy->reg_eb4 = 0x100;
  1693. rtlphy->reg_e9c = 0x0;
  1694. rtlphy->reg_ebc = 0x0;
  1695. }
  1696. if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
  1697. rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
  1698. final_candidate,
  1699. (reg_ea4 == 0));
  1700. if (final_candidate != 0xFF) {
  1701. for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
  1702. rtlphy->iqk_matrix[0].value[0][i] =
  1703. result[final_candidate][i];
  1704. rtlphy->iqk_matrix[0].iqk_done = true;
  1705. }
  1706. rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
  1707. }
  1708. void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
  1709. {
  1710. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1711. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1712. struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
  1713. u32 timeout = 2000, timecount = 0;
  1714. while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
  1715. udelay(50);
  1716. timecount += 50;
  1717. }
  1718. rtlphy->lck_inprogress = true;
  1719. RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
  1720. "LCK:Start!!! currentband %x delay %d ms\n",
  1721. rtlhal->current_bandtype, timecount);
  1722. _rtl8723be_phy_lc_calibrate(hw, false);
  1723. rtlphy->lck_inprogress = false;
  1724. }
  1725. void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
  1726. {
  1727. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1728. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1729. if (rtlphy->apk_done)
  1730. return;
  1731. return;
  1732. }
  1733. void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
  1734. {
  1735. _rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
  1736. }
  1737. static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
  1738. {
  1739. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1740. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1741. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1742. "--->Cmd(%#x), set_io_inprogress(%d)\n",
  1743. rtlphy->current_io_type, rtlphy->set_io_inprogress);
  1744. switch (rtlphy->current_io_type) {
  1745. case IO_CMD_RESUME_DM_BY_SCAN:
  1746. rtlpriv->dm_digtable.cur_igvalue =
  1747. rtlphy->initgain_backup.xaagccore1;
  1748. /*rtl92c_dm_write_dig(hw);*/
  1749. rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
  1750. rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
  1751. break;
  1752. case IO_CMD_PAUSE_DM_BY_SCAN:
  1753. rtlphy->initgain_backup.xaagccore1 =
  1754. rtlpriv->dm_digtable.cur_igvalue;
  1755. rtlpriv->dm_digtable.cur_igvalue = 0x17;
  1756. rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
  1757. break;
  1758. default:
  1759. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1760. "switch case not process\n");
  1761. break;
  1762. }
  1763. rtlphy->set_io_inprogress = false;
  1764. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1765. "(%#x)\n", rtlphy->current_io_type);
  1766. }
  1767. bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
  1768. {
  1769. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1770. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1771. bool postprocessing = false;
  1772. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1773. "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
  1774. iotype, rtlphy->set_io_inprogress);
  1775. do {
  1776. switch (iotype) {
  1777. case IO_CMD_RESUME_DM_BY_SCAN:
  1778. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1779. "[IO CMD] Resume DM after scan.\n");
  1780. postprocessing = true;
  1781. break;
  1782. case IO_CMD_PAUSE_DM_BY_SCAN:
  1783. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1784. "[IO CMD] Pause DM before scan.\n");
  1785. postprocessing = true;
  1786. break;
  1787. default:
  1788. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1789. "switch case not process\n");
  1790. break;
  1791. }
  1792. } while (false);
  1793. if (postprocessing && !rtlphy->set_io_inprogress) {
  1794. rtlphy->set_io_inprogress = true;
  1795. rtlphy->current_io_type = iotype;
  1796. } else {
  1797. return false;
  1798. }
  1799. rtl8723be_phy_set_io(hw);
  1800. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
  1801. return true;
  1802. }
  1803. static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
  1804. {
  1805. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1806. rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
  1807. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  1808. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  1809. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  1810. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  1811. }
  1812. static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
  1813. {
  1814. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1815. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  1816. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
  1817. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  1818. rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
  1819. }
  1820. static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
  1821. enum rf_pwrstate rfpwr_state)
  1822. {
  1823. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1824. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  1825. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  1826. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  1827. bool bresult = true;
  1828. u8 i, queue_id;
  1829. struct rtl8192_tx_ring *ring = NULL;
  1830. switch (rfpwr_state) {
  1831. case ERFON:
  1832. if ((ppsc->rfpwr_state == ERFOFF) &&
  1833. RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
  1834. bool rtstatus;
  1835. u32 initialize_count = 0;
  1836. do {
  1837. initialize_count++;
  1838. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1839. "IPS Set eRf nic enable\n");
  1840. rtstatus = rtl_ps_enable_nic(hw);
  1841. } while (!rtstatus && (initialize_count < 10));
  1842. RT_CLEAR_PS_LEVEL(ppsc,
  1843. RT_RF_OFF_LEVL_HALT_NIC);
  1844. } else {
  1845. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1846. "Set ERFON sleeped:%d ms\n",
  1847. jiffies_to_msecs(jiffies -
  1848. ppsc->last_sleep_jiffies));
  1849. ppsc->last_awake_jiffies = jiffies;
  1850. rtl8723be_phy_set_rf_on(hw);
  1851. }
  1852. if (mac->link_state == MAC80211_LINKED)
  1853. rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
  1854. else
  1855. rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
  1856. break;
  1857. case ERFOFF:
  1858. for (queue_id = 0, i = 0;
  1859. queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
  1860. ring = &pcipriv->dev.tx_ring[queue_id];
  1861. if (skb_queue_len(&ring->queue) == 0) {
  1862. queue_id++;
  1863. continue;
  1864. } else {
  1865. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1866. "eRf Off/Sleep: %d times "
  1867. "TcbBusyQueue[%d] =%d before "
  1868. "doze!\n", (i + 1), queue_id,
  1869. skb_queue_len(&ring->queue));
  1870. udelay(10);
  1871. i++;
  1872. }
  1873. if (i >= MAX_DOZE_WAITING_TIMES_9x) {
  1874. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1875. "\n ERFSLEEP: %d times "
  1876. "TcbBusyQueue[%d] = %d !\n",
  1877. MAX_DOZE_WAITING_TIMES_9x,
  1878. queue_id,
  1879. skb_queue_len(&ring->queue));
  1880. break;
  1881. }
  1882. }
  1883. if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
  1884. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1885. "IPS Set eRf nic disable\n");
  1886. rtl_ps_disable_nic(hw);
  1887. RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
  1888. } else {
  1889. if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
  1890. rtlpriv->cfg->ops->led_control(hw,
  1891. LED_CTL_NO_LINK);
  1892. } else {
  1893. rtlpriv->cfg->ops->led_control(hw,
  1894. LED_CTL_POWER_OFF);
  1895. }
  1896. }
  1897. break;
  1898. case ERFSLEEP:
  1899. if (ppsc->rfpwr_state == ERFOFF)
  1900. break;
  1901. for (queue_id = 0, i = 0;
  1902. queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
  1903. ring = &pcipriv->dev.tx_ring[queue_id];
  1904. if (skb_queue_len(&ring->queue) == 0) {
  1905. queue_id++;
  1906. continue;
  1907. } else {
  1908. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1909. "eRf Off/Sleep: %d times "
  1910. "TcbBusyQueue[%d] =%d before "
  1911. "doze!\n", (i + 1), queue_id,
  1912. skb_queue_len(&ring->queue));
  1913. udelay(10);
  1914. i++;
  1915. }
  1916. if (i >= MAX_DOZE_WAITING_TIMES_9x) {
  1917. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1918. "\n ERFSLEEP: %d times "
  1919. "TcbBusyQueue[%d] = %d !\n",
  1920. MAX_DOZE_WAITING_TIMES_9x,
  1921. queue_id,
  1922. skb_queue_len(&ring->queue));
  1923. break;
  1924. }
  1925. }
  1926. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1927. "Set ERFSLEEP awaked:%d ms\n",
  1928. jiffies_to_msecs(jiffies -
  1929. ppsc->last_awake_jiffies));
  1930. ppsc->last_sleep_jiffies = jiffies;
  1931. _rtl8723be_phy_set_rf_sleep(hw);
  1932. break;
  1933. default:
  1934. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1935. "switch case not process\n");
  1936. bresult = false;
  1937. break;
  1938. }
  1939. if (bresult)
  1940. ppsc->rfpwr_state = rfpwr_state;
  1941. return bresult;
  1942. }
  1943. bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
  1944. enum rf_pwrstate rfpwr_state)
  1945. {
  1946. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  1947. bool bresult = false;
  1948. if (rfpwr_state == ppsc->rfpwr_state)
  1949. return bresult;
  1950. bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
  1951. return bresult;
  1952. }