16f3fcdc8SLarry Finger // SPDX-License-Identifier: GPL-2.0
26f3fcdc8SLarry Finger /* Copyright(c) 2009-2012 Realtek Corporation.*/
3f1d2b4d3SLarry Finger
4f1d2b4d3SLarry Finger #include "../wifi.h"
5f1d2b4d3SLarry Finger #include "../pci.h"
6f1d2b4d3SLarry Finger #include "../ps.h"
7f1d2b4d3SLarry Finger #include "../core.h"
8f1d2b4d3SLarry Finger #include "reg.h"
9f1d2b4d3SLarry Finger #include "def.h"
10f1d2b4d3SLarry Finger #include "phy.h"
11f1d2b4d3SLarry Finger #include "rf.h"
12f1d2b4d3SLarry Finger #include "dm.h"
13f1d2b4d3SLarry Finger #include "fw.h"
14f1d2b4d3SLarry Finger #include "hw.h"
15f1d2b4d3SLarry Finger #include "table.h"
16f1d2b4d3SLarry Finger
rtl92s_phy_query_bb_reg(struct ieee80211_hw * hw,u32 regaddr,u32 bitmask)17f1d2b4d3SLarry Finger u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
18f1d2b4d3SLarry Finger {
19f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
20f1d2b4d3SLarry Finger u32 returnvalue = 0, originalvalue, bitshift;
21f1d2b4d3SLarry Finger
22fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
23f1d2b4d3SLarry Finger regaddr, bitmask);
24f1d2b4d3SLarry Finger
25f1d2b4d3SLarry Finger originalvalue = rtl_read_dword(rtlpriv, regaddr);
26*df14b372SSu Hui bitshift = calculate_bit_shift(bitmask);
27f1d2b4d3SLarry Finger returnvalue = (originalvalue & bitmask) >> bitshift;
28f1d2b4d3SLarry Finger
29fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
30f1d2b4d3SLarry Finger bitmask, regaddr, originalvalue);
31f1d2b4d3SLarry Finger
32f1d2b4d3SLarry Finger return returnvalue;
33f1d2b4d3SLarry Finger
34f1d2b4d3SLarry Finger }
35f1d2b4d3SLarry Finger
rtl92s_phy_set_bb_reg(struct ieee80211_hw * hw,u32 regaddr,u32 bitmask,u32 data)36f1d2b4d3SLarry Finger void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
37f1d2b4d3SLarry Finger u32 data)
38f1d2b4d3SLarry Finger {
39f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
40f1d2b4d3SLarry Finger u32 originalvalue, bitshift;
41f1d2b4d3SLarry Finger
42fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
43f1d2b4d3SLarry Finger "regaddr(%#x), bitmask(%#x), data(%#x)\n",
44f1d2b4d3SLarry Finger regaddr, bitmask, data);
45f1d2b4d3SLarry Finger
46f1d2b4d3SLarry Finger if (bitmask != MASKDWORD) {
47f1d2b4d3SLarry Finger originalvalue = rtl_read_dword(rtlpriv, regaddr);
48*df14b372SSu Hui bitshift = calculate_bit_shift(bitmask);
49f1d2b4d3SLarry Finger data = ((originalvalue & (~bitmask)) | (data << bitshift));
50f1d2b4d3SLarry Finger }
51f1d2b4d3SLarry Finger
52f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, regaddr, data);
53f1d2b4d3SLarry Finger
54fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
55f1d2b4d3SLarry Finger "regaddr(%#x), bitmask(%#x), data(%#x)\n",
56f1d2b4d3SLarry Finger regaddr, bitmask, data);
57f1d2b4d3SLarry Finger
58f1d2b4d3SLarry Finger }
59f1d2b4d3SLarry Finger
_rtl92s_phy_rf_serial_read(struct ieee80211_hw * hw,enum radio_path rfpath,u32 offset)60f1d2b4d3SLarry Finger static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
61f1d2b4d3SLarry Finger enum radio_path rfpath, u32 offset)
62f1d2b4d3SLarry Finger {
63f1d2b4d3SLarry Finger
64f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
65f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
66f1d2b4d3SLarry Finger struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
67f1d2b4d3SLarry Finger u32 newoffset;
68f1d2b4d3SLarry Finger u32 tmplong, tmplong2;
69f1d2b4d3SLarry Finger u8 rfpi_enable = 0;
70f1d2b4d3SLarry Finger u32 retvalue = 0;
71f1d2b4d3SLarry Finger
72f1d2b4d3SLarry Finger offset &= 0x3f;
73f1d2b4d3SLarry Finger newoffset = offset;
74f1d2b4d3SLarry Finger
75f1d2b4d3SLarry Finger tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
76f1d2b4d3SLarry Finger
77f1d2b4d3SLarry Finger if (rfpath == RF90_PATH_A)
78f1d2b4d3SLarry Finger tmplong2 = tmplong;
79f1d2b4d3SLarry Finger else
80f1d2b4d3SLarry Finger tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
81f1d2b4d3SLarry Finger
82f1d2b4d3SLarry Finger tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
83f1d2b4d3SLarry Finger BLSSI_READEDGE;
84f1d2b4d3SLarry Finger
85f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
86f1d2b4d3SLarry Finger tmplong & (~BLSSI_READEDGE));
87f1d2b4d3SLarry Finger
88f1d2b4d3SLarry Finger mdelay(1);
89f1d2b4d3SLarry Finger
90f1d2b4d3SLarry Finger rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
91f1d2b4d3SLarry Finger mdelay(1);
92f1d2b4d3SLarry Finger
93f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
94f1d2b4d3SLarry Finger BLSSI_READEDGE);
95f1d2b4d3SLarry Finger mdelay(1);
96f1d2b4d3SLarry Finger
97f1d2b4d3SLarry Finger if (rfpath == RF90_PATH_A)
98f1d2b4d3SLarry Finger rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
99f1d2b4d3SLarry Finger BIT(8));
100f1d2b4d3SLarry Finger else if (rfpath == RF90_PATH_B)
101f1d2b4d3SLarry Finger rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
102f1d2b4d3SLarry Finger BIT(8));
103f1d2b4d3SLarry Finger
104f1d2b4d3SLarry Finger if (rfpi_enable)
105f1d2b4d3SLarry Finger retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
106f1d2b4d3SLarry Finger BLSSI_READBACK_DATA);
107f1d2b4d3SLarry Finger else
108f1d2b4d3SLarry Finger retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
109f1d2b4d3SLarry Finger BLSSI_READBACK_DATA);
110f1d2b4d3SLarry Finger
111fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
112f1d2b4d3SLarry Finger rfpath, pphyreg->rf_rb, retvalue);
113f1d2b4d3SLarry Finger
114f1d2b4d3SLarry Finger return retvalue;
115f1d2b4d3SLarry Finger
116f1d2b4d3SLarry Finger }
117f1d2b4d3SLarry Finger
_rtl92s_phy_rf_serial_write(struct ieee80211_hw * hw,enum radio_path rfpath,u32 offset,u32 data)118f1d2b4d3SLarry Finger static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
119f1d2b4d3SLarry Finger enum radio_path rfpath, u32 offset,
120f1d2b4d3SLarry Finger u32 data)
121f1d2b4d3SLarry Finger {
122f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
123f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
124f1d2b4d3SLarry Finger struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
125f1d2b4d3SLarry Finger u32 data_and_addr = 0;
126f1d2b4d3SLarry Finger u32 newoffset;
127f1d2b4d3SLarry Finger
128f1d2b4d3SLarry Finger offset &= 0x3f;
129f1d2b4d3SLarry Finger newoffset = offset;
130f1d2b4d3SLarry Finger
131f1d2b4d3SLarry Finger data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
132f1d2b4d3SLarry Finger rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
133f1d2b4d3SLarry Finger
134fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
135f1d2b4d3SLarry Finger rfpath, pphyreg->rf3wire_offset, data_and_addr);
136f1d2b4d3SLarry Finger }
137f1d2b4d3SLarry Finger
138f1d2b4d3SLarry Finger
rtl92s_phy_query_rf_reg(struct ieee80211_hw * hw,enum radio_path rfpath,u32 regaddr,u32 bitmask)139f1d2b4d3SLarry Finger u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
140f1d2b4d3SLarry Finger u32 regaddr, u32 bitmask)
141f1d2b4d3SLarry Finger {
142f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
143f1d2b4d3SLarry Finger u32 original_value, readback_value, bitshift;
144f1d2b4d3SLarry Finger
145fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
146f1d2b4d3SLarry Finger "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
147f1d2b4d3SLarry Finger regaddr, rfpath, bitmask);
148f1d2b4d3SLarry Finger
149f1d2b4d3SLarry Finger spin_lock(&rtlpriv->locks.rf_lock);
150f1d2b4d3SLarry Finger
151f1d2b4d3SLarry Finger original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
152f1d2b4d3SLarry Finger
153*df14b372SSu Hui bitshift = calculate_bit_shift(bitmask);
154f1d2b4d3SLarry Finger readback_value = (original_value & bitmask) >> bitshift;
155f1d2b4d3SLarry Finger
156f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_lock);
157f1d2b4d3SLarry Finger
158fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
159f1d2b4d3SLarry Finger "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
160f1d2b4d3SLarry Finger regaddr, rfpath, bitmask, original_value);
161f1d2b4d3SLarry Finger
162f1d2b4d3SLarry Finger return readback_value;
163f1d2b4d3SLarry Finger }
164f1d2b4d3SLarry Finger
rtl92s_phy_set_rf_reg(struct ieee80211_hw * hw,enum radio_path rfpath,u32 regaddr,u32 bitmask,u32 data)165f1d2b4d3SLarry Finger void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
166f1d2b4d3SLarry Finger u32 regaddr, u32 bitmask, u32 data)
167f1d2b4d3SLarry Finger {
168f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
169f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
170f1d2b4d3SLarry Finger u32 original_value, bitshift;
171f1d2b4d3SLarry Finger
172f1d2b4d3SLarry Finger if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
173f1d2b4d3SLarry Finger return;
174f1d2b4d3SLarry Finger
175fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
176f1d2b4d3SLarry Finger "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
177f1d2b4d3SLarry Finger regaddr, bitmask, data, rfpath);
178f1d2b4d3SLarry Finger
179f1d2b4d3SLarry Finger spin_lock(&rtlpriv->locks.rf_lock);
180f1d2b4d3SLarry Finger
181f1d2b4d3SLarry Finger if (bitmask != RFREG_OFFSET_MASK) {
182f1d2b4d3SLarry Finger original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
183f1d2b4d3SLarry Finger regaddr);
184*df14b372SSu Hui bitshift = calculate_bit_shift(bitmask);
185f1d2b4d3SLarry Finger data = ((original_value & (~bitmask)) | (data << bitshift));
186f1d2b4d3SLarry Finger }
187f1d2b4d3SLarry Finger
188f1d2b4d3SLarry Finger _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
189f1d2b4d3SLarry Finger
190f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_lock);
191f1d2b4d3SLarry Finger
192fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
193f1d2b4d3SLarry Finger "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
194f1d2b4d3SLarry Finger regaddr, bitmask, data, rfpath);
195f1d2b4d3SLarry Finger
196f1d2b4d3SLarry Finger }
197f1d2b4d3SLarry Finger
rtl92s_phy_scan_operation_backup(struct ieee80211_hw * hw,u8 operation)198f1d2b4d3SLarry Finger void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
199f1d2b4d3SLarry Finger u8 operation)
200f1d2b4d3SLarry Finger {
201f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
202f1d2b4d3SLarry Finger
203f1d2b4d3SLarry Finger if (!is_hal_stop(rtlhal)) {
204f1d2b4d3SLarry Finger switch (operation) {
205f1d2b4d3SLarry Finger case SCAN_OPT_BACKUP:
206f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
207f1d2b4d3SLarry Finger break;
208f1d2b4d3SLarry Finger case SCAN_OPT_RESTORE:
209f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
210f1d2b4d3SLarry Finger break;
211f1d2b4d3SLarry Finger default:
2122d15acacSLarry Finger pr_err("Unknown operation\n");
213f1d2b4d3SLarry Finger break;
214f1d2b4d3SLarry Finger }
215f1d2b4d3SLarry Finger }
216f1d2b4d3SLarry Finger }
217f1d2b4d3SLarry Finger
rtl92s_phy_set_bw_mode(struct ieee80211_hw * hw,enum nl80211_channel_type ch_type)218f1d2b4d3SLarry Finger void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
219f1d2b4d3SLarry Finger enum nl80211_channel_type ch_type)
220f1d2b4d3SLarry Finger {
221f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
222f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
223f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
224f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
225f1d2b4d3SLarry Finger u8 reg_bw_opmode;
226f1d2b4d3SLarry Finger
227fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
228f1d2b4d3SLarry Finger rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
229f1d2b4d3SLarry Finger "20MHz" : "40MHz");
230f1d2b4d3SLarry Finger
231f1d2b4d3SLarry Finger if (rtlphy->set_bwmode_inprogress)
232f1d2b4d3SLarry Finger return;
233f1d2b4d3SLarry Finger if (is_hal_stop(rtlhal))
234f1d2b4d3SLarry Finger return;
235f1d2b4d3SLarry Finger
236f1d2b4d3SLarry Finger rtlphy->set_bwmode_inprogress = true;
237f1d2b4d3SLarry Finger
238f1d2b4d3SLarry Finger reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
239f1d2b4d3SLarry Finger /* dummy read */
240f1d2b4d3SLarry Finger rtl_read_byte(rtlpriv, RRSR + 2);
241f1d2b4d3SLarry Finger
242f1d2b4d3SLarry Finger switch (rtlphy->current_chan_bw) {
243f1d2b4d3SLarry Finger case HT_CHANNEL_WIDTH_20:
244f1d2b4d3SLarry Finger reg_bw_opmode |= BW_OPMODE_20MHZ;
245f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
246f1d2b4d3SLarry Finger break;
247f1d2b4d3SLarry Finger case HT_CHANNEL_WIDTH_20_40:
248f1d2b4d3SLarry Finger reg_bw_opmode &= ~BW_OPMODE_20MHZ;
249f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
250f1d2b4d3SLarry Finger break;
251f1d2b4d3SLarry Finger default:
2522d15acacSLarry Finger pr_err("unknown bandwidth: %#X\n",
2532d15acacSLarry Finger rtlphy->current_chan_bw);
254f1d2b4d3SLarry Finger break;
255f1d2b4d3SLarry Finger }
256f1d2b4d3SLarry Finger
257f1d2b4d3SLarry Finger switch (rtlphy->current_chan_bw) {
258f1d2b4d3SLarry Finger case HT_CHANNEL_WIDTH_20:
259f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
260f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
261f1d2b4d3SLarry Finger
262f1d2b4d3SLarry Finger if (rtlhal->version >= VERSION_8192S_BCUT)
263f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
264f1d2b4d3SLarry Finger break;
265f1d2b4d3SLarry Finger case HT_CHANNEL_WIDTH_20_40:
266f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
267f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
268f1d2b4d3SLarry Finger
269f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
270f1d2b4d3SLarry Finger (mac->cur_40_prime_sc >> 1));
271f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
272f1d2b4d3SLarry Finger
273f1d2b4d3SLarry Finger if (rtlhal->version >= VERSION_8192S_BCUT)
274f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
275f1d2b4d3SLarry Finger break;
276f1d2b4d3SLarry Finger default:
2772d15acacSLarry Finger pr_err("unknown bandwidth: %#X\n",
2782d15acacSLarry Finger rtlphy->current_chan_bw);
279f1d2b4d3SLarry Finger break;
280f1d2b4d3SLarry Finger }
281f1d2b4d3SLarry Finger
282f1d2b4d3SLarry Finger rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
283f1d2b4d3SLarry Finger rtlphy->set_bwmode_inprogress = false;
284fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
285f1d2b4d3SLarry Finger }
286f1d2b4d3SLarry Finger
_rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd * cmdtable,u32 cmdtableidx,u32 cmdtablesz,enum swchnlcmd_id cmdid,u32 para1,u32 para2,u32 msdelay)287f1d2b4d3SLarry Finger static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
288f1d2b4d3SLarry Finger u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
289f1d2b4d3SLarry Finger u32 para1, u32 para2, u32 msdelay)
290f1d2b4d3SLarry Finger {
291f1d2b4d3SLarry Finger struct swchnlcmd *pcmd;
292f1d2b4d3SLarry Finger
293f1d2b4d3SLarry Finger if (cmdtable == NULL) {
294531940f9SLarry Finger WARN_ONCE(true, "rtl8192se: cmdtable cannot be NULL\n");
295f1d2b4d3SLarry Finger return false;
296f1d2b4d3SLarry Finger }
297f1d2b4d3SLarry Finger
298f1d2b4d3SLarry Finger if (cmdtableidx >= cmdtablesz)
299f1d2b4d3SLarry Finger return false;
300f1d2b4d3SLarry Finger
301f1d2b4d3SLarry Finger pcmd = cmdtable + cmdtableidx;
302f1d2b4d3SLarry Finger pcmd->cmdid = cmdid;
303f1d2b4d3SLarry Finger pcmd->para1 = para1;
304f1d2b4d3SLarry Finger pcmd->para2 = para2;
305f1d2b4d3SLarry Finger pcmd->msdelay = msdelay;
306f1d2b4d3SLarry Finger
307f1d2b4d3SLarry Finger return true;
308f1d2b4d3SLarry Finger }
309f1d2b4d3SLarry Finger
_rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw * hw,u8 channel,u8 * stage,u8 * step,u32 * delay)310f1d2b4d3SLarry Finger static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
311f1d2b4d3SLarry Finger u8 channel, u8 *stage, u8 *step, u32 *delay)
312f1d2b4d3SLarry Finger {
313f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
314f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
315f1d2b4d3SLarry Finger struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
316f1d2b4d3SLarry Finger u32 precommoncmdcnt;
317f1d2b4d3SLarry Finger struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
318f1d2b4d3SLarry Finger u32 postcommoncmdcnt;
319f1d2b4d3SLarry Finger struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
320f1d2b4d3SLarry Finger u32 rfdependcmdcnt;
321f1d2b4d3SLarry Finger struct swchnlcmd *currentcmd = NULL;
322f1d2b4d3SLarry Finger u8 rfpath;
323f1d2b4d3SLarry Finger u8 num_total_rfpath = rtlphy->num_total_rfpath;
324f1d2b4d3SLarry Finger
325f1d2b4d3SLarry Finger precommoncmdcnt = 0;
326f1d2b4d3SLarry Finger _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
327f1d2b4d3SLarry Finger MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
328f1d2b4d3SLarry Finger _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
329f1d2b4d3SLarry Finger MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
330f1d2b4d3SLarry Finger
331f1d2b4d3SLarry Finger postcommoncmdcnt = 0;
332f1d2b4d3SLarry Finger
333f1d2b4d3SLarry Finger _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
334f1d2b4d3SLarry Finger MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
335f1d2b4d3SLarry Finger
336f1d2b4d3SLarry Finger rfdependcmdcnt = 0;
337f1d2b4d3SLarry Finger
338531940f9SLarry Finger WARN_ONCE((channel < 1 || channel > 14),
339531940f9SLarry Finger "rtl8192se: invalid channel for Zebra: %d\n", channel);
340f1d2b4d3SLarry Finger
341f1d2b4d3SLarry Finger _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
342f1d2b4d3SLarry Finger MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
343f1d2b4d3SLarry Finger RF_CHNLBW, channel, 10);
344f1d2b4d3SLarry Finger
345f1d2b4d3SLarry Finger _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
346f1d2b4d3SLarry Finger MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
347f1d2b4d3SLarry Finger
348f1d2b4d3SLarry Finger do {
349f1d2b4d3SLarry Finger switch (*stage) {
350f1d2b4d3SLarry Finger case 0:
351f1d2b4d3SLarry Finger currentcmd = &precommoncmd[*step];
352f1d2b4d3SLarry Finger break;
353f1d2b4d3SLarry Finger case 1:
354f1d2b4d3SLarry Finger currentcmd = &rfdependcmd[*step];
355f1d2b4d3SLarry Finger break;
356f1d2b4d3SLarry Finger case 2:
357f1d2b4d3SLarry Finger currentcmd = &postcommoncmd[*step];
358f1d2b4d3SLarry Finger break;
359f1d2b4d3SLarry Finger default:
360f1d2b4d3SLarry Finger return true;
361f1d2b4d3SLarry Finger }
362f1d2b4d3SLarry Finger
363f1d2b4d3SLarry Finger if (currentcmd->cmdid == CMDID_END) {
364f1d2b4d3SLarry Finger if ((*stage) == 2) {
365f1d2b4d3SLarry Finger return true;
366f1d2b4d3SLarry Finger } else {
367f1d2b4d3SLarry Finger (*stage)++;
368f1d2b4d3SLarry Finger (*step) = 0;
369f1d2b4d3SLarry Finger continue;
370f1d2b4d3SLarry Finger }
371f1d2b4d3SLarry Finger }
372f1d2b4d3SLarry Finger
373f1d2b4d3SLarry Finger switch (currentcmd->cmdid) {
374f1d2b4d3SLarry Finger case CMDID_SET_TXPOWEROWER_LEVEL:
375f1d2b4d3SLarry Finger rtl92s_phy_set_txpower(hw, channel);
376f1d2b4d3SLarry Finger break;
377f1d2b4d3SLarry Finger case CMDID_WRITEPORT_ULONG:
378f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, currentcmd->para1,
379f1d2b4d3SLarry Finger currentcmd->para2);
380f1d2b4d3SLarry Finger break;
381f1d2b4d3SLarry Finger case CMDID_WRITEPORT_USHORT:
382f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, currentcmd->para1,
383f1d2b4d3SLarry Finger (u16)currentcmd->para2);
384f1d2b4d3SLarry Finger break;
385f1d2b4d3SLarry Finger case CMDID_WRITEPORT_UCHAR:
386f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, currentcmd->para1,
387f1d2b4d3SLarry Finger (u8)currentcmd->para2);
388f1d2b4d3SLarry Finger break;
389f1d2b4d3SLarry Finger case CMDID_RF_WRITEREG:
390f1d2b4d3SLarry Finger for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
391f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[rfpath] =
392f1d2b4d3SLarry Finger ((rtlphy->rfreg_chnlval[rfpath] &
393f1d2b4d3SLarry Finger 0xfffffc00) | currentcmd->para2);
394f1d2b4d3SLarry Finger rtl_set_rfreg(hw, (enum radio_path)rfpath,
395f1d2b4d3SLarry Finger currentcmd->para1,
396f1d2b4d3SLarry Finger RFREG_OFFSET_MASK,
397f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[rfpath]);
398f1d2b4d3SLarry Finger }
399f1d2b4d3SLarry Finger break;
400f1d2b4d3SLarry Finger default:
4012d15acacSLarry Finger pr_err("switch case %#x not processed\n",
402ad574889SJoe Perches currentcmd->cmdid);
403f1d2b4d3SLarry Finger break;
404f1d2b4d3SLarry Finger }
405f1d2b4d3SLarry Finger
406f1d2b4d3SLarry Finger break;
407f1d2b4d3SLarry Finger } while (true);
408f1d2b4d3SLarry Finger
409f1d2b4d3SLarry Finger (*delay) = currentcmd->msdelay;
410f1d2b4d3SLarry Finger (*step)++;
411f1d2b4d3SLarry Finger return false;
412f1d2b4d3SLarry Finger }
413f1d2b4d3SLarry Finger
rtl92s_phy_sw_chnl(struct ieee80211_hw * hw)414f1d2b4d3SLarry Finger u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
415f1d2b4d3SLarry Finger {
416f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
417f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
418f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
419f1d2b4d3SLarry Finger u32 delay;
420f1d2b4d3SLarry Finger bool ret;
421f1d2b4d3SLarry Finger
422fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n",
423f1d2b4d3SLarry Finger rtlphy->current_channel);
424f1d2b4d3SLarry Finger
425f1d2b4d3SLarry Finger if (rtlphy->sw_chnl_inprogress)
426f1d2b4d3SLarry Finger return 0;
427f1d2b4d3SLarry Finger
428f1d2b4d3SLarry Finger if (rtlphy->set_bwmode_inprogress)
429f1d2b4d3SLarry Finger return 0;
430f1d2b4d3SLarry Finger
431f1d2b4d3SLarry Finger if (is_hal_stop(rtlhal))
432f1d2b4d3SLarry Finger return 0;
433f1d2b4d3SLarry Finger
434f1d2b4d3SLarry Finger rtlphy->sw_chnl_inprogress = true;
435f1d2b4d3SLarry Finger rtlphy->sw_chnl_stage = 0;
436f1d2b4d3SLarry Finger rtlphy->sw_chnl_step = 0;
437f1d2b4d3SLarry Finger
438f1d2b4d3SLarry Finger do {
439f1d2b4d3SLarry Finger if (!rtlphy->sw_chnl_inprogress)
440f1d2b4d3SLarry Finger break;
441f1d2b4d3SLarry Finger
442f1d2b4d3SLarry Finger ret = _rtl92s_phy_sw_chnl_step_by_step(hw,
443f1d2b4d3SLarry Finger rtlphy->current_channel,
444f1d2b4d3SLarry Finger &rtlphy->sw_chnl_stage,
445f1d2b4d3SLarry Finger &rtlphy->sw_chnl_step, &delay);
446f1d2b4d3SLarry Finger if (!ret) {
447f1d2b4d3SLarry Finger if (delay > 0)
448f1d2b4d3SLarry Finger mdelay(delay);
449f1d2b4d3SLarry Finger else
450f1d2b4d3SLarry Finger continue;
451f1d2b4d3SLarry Finger } else {
452f1d2b4d3SLarry Finger rtlphy->sw_chnl_inprogress = false;
453f1d2b4d3SLarry Finger }
454f1d2b4d3SLarry Finger break;
455f1d2b4d3SLarry Finger } while (true);
456f1d2b4d3SLarry Finger
457f1d2b4d3SLarry Finger rtlphy->sw_chnl_inprogress = false;
458f1d2b4d3SLarry Finger
459fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
460f1d2b4d3SLarry Finger
461f1d2b4d3SLarry Finger return 1;
462f1d2b4d3SLarry Finger }
463f1d2b4d3SLarry Finger
_rtl92se_phy_set_rf_sleep(struct ieee80211_hw * hw)464f1d2b4d3SLarry Finger static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
465f1d2b4d3SLarry Finger {
466f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
467f1d2b4d3SLarry Finger u8 u1btmp;
468f1d2b4d3SLarry Finger
469f1d2b4d3SLarry Finger u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
470f1d2b4d3SLarry Finger u1btmp |= BIT(0);
471f1d2b4d3SLarry Finger
472f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
473f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
474f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
475f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x57FC);
476f1d2b4d3SLarry Finger udelay(100);
477f1d2b4d3SLarry Finger
478f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x77FC);
479f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
480f1d2b4d3SLarry Finger udelay(10);
481f1d2b4d3SLarry Finger
482f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x37FC);
483f1d2b4d3SLarry Finger udelay(10);
484f1d2b4d3SLarry Finger
485f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x77FC);
486f1d2b4d3SLarry Finger udelay(10);
487f1d2b4d3SLarry Finger
488f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x57FC);
489f1d2b4d3SLarry Finger
490f1d2b4d3SLarry Finger /* we should chnge GPIO to input mode
491f1d2b4d3SLarry Finger * this will drop away current about 25mA*/
492f1d2b4d3SLarry Finger rtl8192se_gpiobit3_cfg_inputmode(hw);
493f1d2b4d3SLarry Finger }
494f1d2b4d3SLarry Finger
rtl92s_phy_set_rf_power_state(struct ieee80211_hw * hw,enum rf_pwrstate rfpwr_state)495f1d2b4d3SLarry Finger bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
496f1d2b4d3SLarry Finger enum rf_pwrstate rfpwr_state)
497f1d2b4d3SLarry Finger {
498f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
499f1d2b4d3SLarry Finger struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
500f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
501f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
502f1d2b4d3SLarry Finger bool bresult = true;
503f1d2b4d3SLarry Finger u8 i, queue_id;
504f1d2b4d3SLarry Finger struct rtl8192_tx_ring *ring = NULL;
505f1d2b4d3SLarry Finger
506f1d2b4d3SLarry Finger if (rfpwr_state == ppsc->rfpwr_state)
507f1d2b4d3SLarry Finger return false;
508f1d2b4d3SLarry Finger
509f1d2b4d3SLarry Finger switch (rfpwr_state) {
510f1d2b4d3SLarry Finger case ERFON:{
511f1d2b4d3SLarry Finger if ((ppsc->rfpwr_state == ERFOFF) &&
512f1d2b4d3SLarry Finger RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
513f1d2b4d3SLarry Finger
514f1d2b4d3SLarry Finger bool rtstatus;
5152a83ad1fSLarry Finger u32 initializecount = 0;
516f1d2b4d3SLarry Finger do {
5172a83ad1fSLarry Finger initializecount++;
518fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
519f1d2b4d3SLarry Finger "IPS Set eRf nic enable\n");
520f1d2b4d3SLarry Finger rtstatus = rtl_ps_enable_nic(hw);
5212a83ad1fSLarry Finger } while (!rtstatus && (initializecount < 10));
522f1d2b4d3SLarry Finger
523f1d2b4d3SLarry Finger RT_CLEAR_PS_LEVEL(ppsc,
524f1d2b4d3SLarry Finger RT_RF_OFF_LEVL_HALT_NIC);
525f1d2b4d3SLarry Finger } else {
526fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG,
527fca8218dSLarry Finger "awake, slept:%d ms state_inap:%x\n",
528f1d2b4d3SLarry Finger jiffies_to_msecs(jiffies -
529fca8218dSLarry Finger ppsc->last_sleep_jiffies),
530f1d2b4d3SLarry Finger rtlpriv->psc.state_inap);
531f1d2b4d3SLarry Finger ppsc->last_awake_jiffies = jiffies;
532f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x37FC);
533f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
534f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
535f1d2b4d3SLarry Finger }
536f1d2b4d3SLarry Finger
537f1d2b4d3SLarry Finger if (mac->link_state == MAC80211_LINKED)
538f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw,
539f1d2b4d3SLarry Finger LED_CTL_LINK);
540f1d2b4d3SLarry Finger else
541f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw,
542f1d2b4d3SLarry Finger LED_CTL_NO_LINK);
543f1d2b4d3SLarry Finger break;
544f1d2b4d3SLarry Finger }
545f1d2b4d3SLarry Finger case ERFOFF:{
546f1d2b4d3SLarry Finger if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
547fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
548f1d2b4d3SLarry Finger "IPS Set eRf nic disable\n");
549f1d2b4d3SLarry Finger rtl_ps_disable_nic(hw);
550f1d2b4d3SLarry Finger RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
551f1d2b4d3SLarry Finger } else {
552f1d2b4d3SLarry Finger if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
553f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw,
554f1d2b4d3SLarry Finger LED_CTL_NO_LINK);
555f1d2b4d3SLarry Finger else
556f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw,
557f1d2b4d3SLarry Finger LED_CTL_POWER_OFF);
558f1d2b4d3SLarry Finger }
559f1d2b4d3SLarry Finger break;
560f1d2b4d3SLarry Finger }
561f1d2b4d3SLarry Finger case ERFSLEEP:
562f1d2b4d3SLarry Finger if (ppsc->rfpwr_state == ERFOFF)
563f1d2b4d3SLarry Finger return false;
564f1d2b4d3SLarry Finger
565f1d2b4d3SLarry Finger for (queue_id = 0, i = 0;
566f1d2b4d3SLarry Finger queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
567f1d2b4d3SLarry Finger ring = &pcipriv->dev.tx_ring[queue_id];
568f1d2b4d3SLarry Finger if (skb_queue_len(&ring->queue) == 0 ||
569f1d2b4d3SLarry Finger queue_id == BEACON_QUEUE) {
570f1d2b4d3SLarry Finger queue_id++;
571f1d2b4d3SLarry Finger continue;
572f1d2b4d3SLarry Finger } else {
573fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
574f1d2b4d3SLarry Finger "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n",
575f1d2b4d3SLarry Finger i + 1, queue_id,
576f1d2b4d3SLarry Finger skb_queue_len(&ring->queue));
577f1d2b4d3SLarry Finger
578f1d2b4d3SLarry Finger udelay(10);
579f1d2b4d3SLarry Finger i++;
580f1d2b4d3SLarry Finger }
581f1d2b4d3SLarry Finger
582f1d2b4d3SLarry Finger if (i >= MAX_DOZE_WAITING_TIMES_9x) {
583fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
584f1d2b4d3SLarry Finger "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
585f1d2b4d3SLarry Finger MAX_DOZE_WAITING_TIMES_9x,
586f1d2b4d3SLarry Finger queue_id,
587f1d2b4d3SLarry Finger skb_queue_len(&ring->queue));
588f1d2b4d3SLarry Finger break;
589f1d2b4d3SLarry Finger }
590f1d2b4d3SLarry Finger }
591f1d2b4d3SLarry Finger
592fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG,
593f1d2b4d3SLarry Finger "Set ERFSLEEP awaked:%d ms\n",
594f1d2b4d3SLarry Finger jiffies_to_msecs(jiffies -
595f1d2b4d3SLarry Finger ppsc->last_awake_jiffies));
596f1d2b4d3SLarry Finger
597fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG,
598f1d2b4d3SLarry Finger "sleep awaked:%d ms state_inap:%x\n",
599f1d2b4d3SLarry Finger jiffies_to_msecs(jiffies -
600f1d2b4d3SLarry Finger ppsc->last_awake_jiffies),
601f1d2b4d3SLarry Finger rtlpriv->psc.state_inap);
602f1d2b4d3SLarry Finger ppsc->last_sleep_jiffies = jiffies;
603f1d2b4d3SLarry Finger _rtl92se_phy_set_rf_sleep(hw);
604f1d2b4d3SLarry Finger break;
605f1d2b4d3SLarry Finger default:
6062d15acacSLarry Finger pr_err("switch case %#x not processed\n",
6072d15acacSLarry Finger rfpwr_state);
608f1d2b4d3SLarry Finger bresult = false;
609f1d2b4d3SLarry Finger break;
610f1d2b4d3SLarry Finger }
611f1d2b4d3SLarry Finger
612f1d2b4d3SLarry Finger if (bresult)
613f1d2b4d3SLarry Finger ppsc->rfpwr_state = rfpwr_state;
614f1d2b4d3SLarry Finger
615f1d2b4d3SLarry Finger return bresult;
616f1d2b4d3SLarry Finger }
617f1d2b4d3SLarry Finger
_rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw * hw,enum radio_path rfpath)618f1d2b4d3SLarry Finger static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
619f1d2b4d3SLarry Finger enum radio_path rfpath)
620f1d2b4d3SLarry Finger {
621f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
622f1d2b4d3SLarry Finger bool rtstatus = true;
623f1d2b4d3SLarry Finger u32 tmpval = 0;
624f1d2b4d3SLarry Finger
625f1d2b4d3SLarry Finger /* If inferiority IC, we have to increase the PA bias current */
626f1d2b4d3SLarry Finger if (rtlhal->ic_class != IC_INFERIORITY_A) {
627f1d2b4d3SLarry Finger tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
628f1d2b4d3SLarry Finger rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
629f1d2b4d3SLarry Finger }
630f1d2b4d3SLarry Finger
631f1d2b4d3SLarry Finger return rtstatus;
632f1d2b4d3SLarry Finger }
633f1d2b4d3SLarry Finger
_rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw * hw,u32 reg_addr,u32 bitmask,u32 data)634f1d2b4d3SLarry Finger static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
635f1d2b4d3SLarry Finger u32 reg_addr, u32 bitmask, u32 data)
636f1d2b4d3SLarry Finger {
637f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
638f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
639f1d2b4d3SLarry Finger int index;
640f1d2b4d3SLarry Finger
641f1d2b4d3SLarry Finger if (reg_addr == RTXAGC_RATE18_06)
642f1d2b4d3SLarry Finger index = 0;
643f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_RATE54_24)
644f1d2b4d3SLarry Finger index = 1;
645f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_CCK_MCS32)
646f1d2b4d3SLarry Finger index = 6;
647f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_MCS03_MCS00)
648f1d2b4d3SLarry Finger index = 2;
649f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_MCS07_MCS04)
650f1d2b4d3SLarry Finger index = 3;
651f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_MCS11_MCS08)
652f1d2b4d3SLarry Finger index = 4;
653f1d2b4d3SLarry Finger else if (reg_addr == RTXAGC_MCS15_MCS12)
654f1d2b4d3SLarry Finger index = 5;
655f1d2b4d3SLarry Finger else
656f1d2b4d3SLarry Finger return;
657f1d2b4d3SLarry Finger
658f1d2b4d3SLarry Finger rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data;
659f1d2b4d3SLarry Finger if (index == 5)
660f1d2b4d3SLarry Finger rtlphy->pwrgroup_cnt++;
661f1d2b4d3SLarry Finger }
662f1d2b4d3SLarry Finger
_rtl92s_phy_init_register_definition(struct ieee80211_hw * hw)663f1d2b4d3SLarry Finger static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
664f1d2b4d3SLarry Finger {
665f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
666f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
667f1d2b4d3SLarry Finger
668f1d2b4d3SLarry Finger /*RF Interface Sowrtware Control */
669f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
670f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
671f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
672f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
673f1d2b4d3SLarry Finger
674f1d2b4d3SLarry Finger /* RF Interface Readback Value */
675f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
676f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
677f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
678f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
679f1d2b4d3SLarry Finger
680f1d2b4d3SLarry Finger /* RF Interface Output (and Enable) */
681f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
682f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
683f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
684f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
685f1d2b4d3SLarry Finger
686f1d2b4d3SLarry Finger /* RF Interface (Output and) Enable */
687f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
688f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
689f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
690f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
691f1d2b4d3SLarry Finger
692f1d2b4d3SLarry Finger /* Addr of LSSI. Wirte RF register by driver */
693f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
694f1d2b4d3SLarry Finger RFPGA0_XA_LSSIPARAMETER;
695f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
696f1d2b4d3SLarry Finger RFPGA0_XB_LSSIPARAMETER;
697f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
698f1d2b4d3SLarry Finger RFPGA0_XC_LSSIPARAMETER;
699f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
700f1d2b4d3SLarry Finger RFPGA0_XD_LSSIPARAMETER;
701f1d2b4d3SLarry Finger
702f1d2b4d3SLarry Finger /* RF parameter */
703f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
704f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
705f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
706f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
707f1d2b4d3SLarry Finger
708f1d2b4d3SLarry Finger /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
709f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
710f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
711f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
712f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
713f1d2b4d3SLarry Finger
714f1d2b4d3SLarry Finger /* Tranceiver A~D HSSI Parameter-1 */
715f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
716f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
717f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
718f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
719f1d2b4d3SLarry Finger
720f1d2b4d3SLarry Finger /* Tranceiver A~D HSSI Parameter-2 */
721f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
722f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
723f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
724f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
725f1d2b4d3SLarry Finger
726f1d2b4d3SLarry Finger /* RF switch Control */
727f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
728f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
729f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
730f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
731f1d2b4d3SLarry Finger
732f1d2b4d3SLarry Finger /* AGC control 1 */
733f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
734f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
735f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
736f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
737f1d2b4d3SLarry Finger
738f1d2b4d3SLarry Finger /* AGC control 2 */
739f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
740f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
741f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
742f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
743f1d2b4d3SLarry Finger
744f1d2b4d3SLarry Finger /* RX AFE control 1 */
745f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
746f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
747f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE;
748f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
749f1d2b4d3SLarry Finger
750f1d2b4d3SLarry Finger /* RX AFE control 1 */
751f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
752f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
753f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
754f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
755f1d2b4d3SLarry Finger
756f1d2b4d3SLarry Finger /* Tx AFE control 1 */
757f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
758f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
759f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
760f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
761f1d2b4d3SLarry Finger
762f1d2b4d3SLarry Finger /* Tx AFE control 2 */
763f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
764f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
765f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
766f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
767f1d2b4d3SLarry Finger
768f1d2b4d3SLarry Finger /* Tranceiver LSSI Readback */
769f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
770f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
771f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
772f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
773f1d2b4d3SLarry Finger
774f1d2b4d3SLarry Finger /* Tranceiver LSSI Readback PI mode */
775f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK;
776f1d2b4d3SLarry Finger rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK;
777f1d2b4d3SLarry Finger }
778f1d2b4d3SLarry Finger
779f1d2b4d3SLarry Finger
_rtl92s_phy_config_bb(struct ieee80211_hw * hw,u8 configtype)780f1d2b4d3SLarry Finger static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
781f1d2b4d3SLarry Finger {
782f1d2b4d3SLarry Finger int i;
783f1d2b4d3SLarry Finger u32 *phy_reg_table;
784f1d2b4d3SLarry Finger u32 *agc_table;
785f1d2b4d3SLarry Finger u16 phy_reg_len, agc_len;
786f1d2b4d3SLarry Finger
787f1d2b4d3SLarry Finger agc_len = AGCTAB_ARRAYLENGTH;
788f1d2b4d3SLarry Finger agc_table = rtl8192seagctab_array;
789f1d2b4d3SLarry Finger /* Default RF_type: 2T2R */
790f1d2b4d3SLarry Finger phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
791f1d2b4d3SLarry Finger phy_reg_table = rtl8192sephy_reg_2t2rarray;
792f1d2b4d3SLarry Finger
793f1d2b4d3SLarry Finger if (configtype == BASEBAND_CONFIG_PHY_REG) {
794f1d2b4d3SLarry Finger for (i = 0; i < phy_reg_len; i = i + 2) {
795f1d2b4d3SLarry Finger rtl_addr_delay(phy_reg_table[i]);
796f1d2b4d3SLarry Finger
797f1d2b4d3SLarry Finger /* Add delay for ECS T20 & LG malow platform, */
798f1d2b4d3SLarry Finger udelay(1);
799f1d2b4d3SLarry Finger
800f1d2b4d3SLarry Finger rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
801f1d2b4d3SLarry Finger phy_reg_table[i + 1]);
802f1d2b4d3SLarry Finger }
803f1d2b4d3SLarry Finger } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
804f1d2b4d3SLarry Finger for (i = 0; i < agc_len; i = i + 2) {
805f1d2b4d3SLarry Finger rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
806f1d2b4d3SLarry Finger agc_table[i + 1]);
807f1d2b4d3SLarry Finger
808f1d2b4d3SLarry Finger /* Add delay for ECS T20 & LG malow platform */
809f1d2b4d3SLarry Finger udelay(1);
810f1d2b4d3SLarry Finger }
811f1d2b4d3SLarry Finger }
812f1d2b4d3SLarry Finger
813f1d2b4d3SLarry Finger return true;
814f1d2b4d3SLarry Finger }
815f1d2b4d3SLarry Finger
_rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw * hw,u8 configtype)816f1d2b4d3SLarry Finger static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
817f1d2b4d3SLarry Finger u8 configtype)
818f1d2b4d3SLarry Finger {
819f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
820f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
821f1d2b4d3SLarry Finger u32 *phy_regarray2xtxr_table;
822f1d2b4d3SLarry Finger u16 phy_regarray2xtxr_len;
823f1d2b4d3SLarry Finger int i;
824f1d2b4d3SLarry Finger
825f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T1R) {
826f1d2b4d3SLarry Finger phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
827f1d2b4d3SLarry Finger phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
828f1d2b4d3SLarry Finger } else if (rtlphy->rf_type == RF_1T2R) {
829f1d2b4d3SLarry Finger phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
830f1d2b4d3SLarry Finger phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
831f1d2b4d3SLarry Finger } else {
832f1d2b4d3SLarry Finger return false;
833f1d2b4d3SLarry Finger }
834f1d2b4d3SLarry Finger
835f1d2b4d3SLarry Finger if (configtype == BASEBAND_CONFIG_PHY_REG) {
836f1d2b4d3SLarry Finger for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
837f1d2b4d3SLarry Finger rtl_addr_delay(phy_regarray2xtxr_table[i]);
838f1d2b4d3SLarry Finger
839f1d2b4d3SLarry Finger rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
840f1d2b4d3SLarry Finger phy_regarray2xtxr_table[i + 1],
841f1d2b4d3SLarry Finger phy_regarray2xtxr_table[i + 2]);
842f1d2b4d3SLarry Finger }
843f1d2b4d3SLarry Finger }
844f1d2b4d3SLarry Finger
845f1d2b4d3SLarry Finger return true;
846f1d2b4d3SLarry Finger }
847f1d2b4d3SLarry Finger
_rtl92s_phy_config_bb_with_pg(struct ieee80211_hw * hw,u8 configtype)848f1d2b4d3SLarry Finger static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
849f1d2b4d3SLarry Finger u8 configtype)
850f1d2b4d3SLarry Finger {
851f1d2b4d3SLarry Finger int i;
852f1d2b4d3SLarry Finger u32 *phy_table_pg;
853f1d2b4d3SLarry Finger u16 phy_pg_len;
854f1d2b4d3SLarry Finger
855f1d2b4d3SLarry Finger phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
856f1d2b4d3SLarry Finger phy_table_pg = rtl8192sephy_reg_array_pg;
857f1d2b4d3SLarry Finger
858f1d2b4d3SLarry Finger if (configtype == BASEBAND_CONFIG_PHY_REG) {
859f1d2b4d3SLarry Finger for (i = 0; i < phy_pg_len; i = i + 3) {
860f1d2b4d3SLarry Finger rtl_addr_delay(phy_table_pg[i]);
861f1d2b4d3SLarry Finger
862f1d2b4d3SLarry Finger _rtl92s_store_pwrindex_diffrate_offset(hw,
863f1d2b4d3SLarry Finger phy_table_pg[i],
864f1d2b4d3SLarry Finger phy_table_pg[i + 1],
865f1d2b4d3SLarry Finger phy_table_pg[i + 2]);
866f1d2b4d3SLarry Finger rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
867f1d2b4d3SLarry Finger phy_table_pg[i + 1],
868f1d2b4d3SLarry Finger phy_table_pg[i + 2]);
869f1d2b4d3SLarry Finger }
870f1d2b4d3SLarry Finger }
871f1d2b4d3SLarry Finger
872f1d2b4d3SLarry Finger return true;
873f1d2b4d3SLarry Finger }
874f1d2b4d3SLarry Finger
_rtl92s_phy_bb_config_parafile(struct ieee80211_hw * hw)875f1d2b4d3SLarry Finger static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
876f1d2b4d3SLarry Finger {
877f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
878f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
879f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
880f1d2b4d3SLarry Finger bool rtstatus = true;
881f1d2b4d3SLarry Finger
882f1d2b4d3SLarry Finger /* 1. Read PHY_REG.TXT BB INIT!! */
883f1d2b4d3SLarry Finger /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
884f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
885f1d2b4d3SLarry Finger rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
886f1d2b4d3SLarry Finger rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
887f1d2b4d3SLarry Finger
888f1d2b4d3SLarry Finger if (rtlphy->rf_type != RF_2T2R &&
889f1d2b4d3SLarry Finger rtlphy->rf_type != RF_2T2R_GREEN)
890f1d2b4d3SLarry Finger /* so we should reconfig BB reg with the right
891f1d2b4d3SLarry Finger * PHY parameters. */
892f1d2b4d3SLarry Finger rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
893f1d2b4d3SLarry Finger BASEBAND_CONFIG_PHY_REG);
894f1d2b4d3SLarry Finger } else {
895f1d2b4d3SLarry Finger rtstatus = false;
896f1d2b4d3SLarry Finger }
897f1d2b4d3SLarry Finger
898f1d2b4d3SLarry Finger if (!rtstatus) {
8992d15acacSLarry Finger pr_err("Write BB Reg Fail!!\n");
9002a83ad1fSLarry Finger goto phy_bb8190_config_parafile_fail;
901f1d2b4d3SLarry Finger }
902f1d2b4d3SLarry Finger
903f1d2b4d3SLarry Finger /* 2. If EEPROM or EFUSE autoload OK, We must config by
904f1d2b4d3SLarry Finger * PHY_REG_PG.txt */
905f1d2b4d3SLarry Finger if (rtlefuse->autoload_failflag == false) {
906f1d2b4d3SLarry Finger rtlphy->pwrgroup_cnt = 0;
907f1d2b4d3SLarry Finger
908f1d2b4d3SLarry Finger rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
909f1d2b4d3SLarry Finger BASEBAND_CONFIG_PHY_REG);
910f1d2b4d3SLarry Finger }
911f1d2b4d3SLarry Finger if (!rtstatus) {
9122d15acacSLarry Finger pr_err("_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n");
9132a83ad1fSLarry Finger goto phy_bb8190_config_parafile_fail;
914f1d2b4d3SLarry Finger }
915f1d2b4d3SLarry Finger
916f1d2b4d3SLarry Finger /* 3. BB AGC table Initialization */
917f1d2b4d3SLarry Finger rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
918f1d2b4d3SLarry Finger
919f1d2b4d3SLarry Finger if (!rtstatus) {
920f1d2b4d3SLarry Finger pr_err("%s(): AGC Table Fail\n", __func__);
9212a83ad1fSLarry Finger goto phy_bb8190_config_parafile_fail;
922f1d2b4d3SLarry Finger }
923f1d2b4d3SLarry Finger
924f1d2b4d3SLarry Finger /* Check if the CCK HighPower is turned ON. */
925f1d2b4d3SLarry Finger /* This is used to calculate PWDB. */
926f1d2b4d3SLarry Finger rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
927f1d2b4d3SLarry Finger RFPGA0_XA_HSSIPARAMETER2, 0x200));
928f1d2b4d3SLarry Finger
9292a83ad1fSLarry Finger phy_bb8190_config_parafile_fail:
930f1d2b4d3SLarry Finger return rtstatus;
931f1d2b4d3SLarry Finger }
932f1d2b4d3SLarry Finger
rtl92s_phy_config_rf(struct ieee80211_hw * hw,enum radio_path rfpath)933f1d2b4d3SLarry Finger u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
934f1d2b4d3SLarry Finger {
935f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
936f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
937f1d2b4d3SLarry Finger int i;
938f1d2b4d3SLarry Finger bool rtstatus = true;
939f1d2b4d3SLarry Finger u32 *radio_a_table;
940f1d2b4d3SLarry Finger u32 *radio_b_table;
941f1d2b4d3SLarry Finger u16 radio_a_tblen, radio_b_tblen;
942f1d2b4d3SLarry Finger
943f1d2b4d3SLarry Finger radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
944f1d2b4d3SLarry Finger radio_a_table = rtl8192seradioa_1t_array;
945f1d2b4d3SLarry Finger
946f1d2b4d3SLarry Finger /* Using Green mode array table for RF_2T2R_GREEN */
947f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_2T2R_GREEN) {
948f1d2b4d3SLarry Finger radio_b_table = rtl8192seradiob_gm_array;
949f1d2b4d3SLarry Finger radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
950f1d2b4d3SLarry Finger } else {
951f1d2b4d3SLarry Finger radio_b_table = rtl8192seradiob_array;
952f1d2b4d3SLarry Finger radio_b_tblen = RADIOB_ARRAYLENGTH;
953f1d2b4d3SLarry Finger }
954f1d2b4d3SLarry Finger
955fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
956f1d2b4d3SLarry Finger rtstatus = true;
957f1d2b4d3SLarry Finger
958f1d2b4d3SLarry Finger switch (rfpath) {
959f1d2b4d3SLarry Finger case RF90_PATH_A:
960f1d2b4d3SLarry Finger for (i = 0; i < radio_a_tblen; i = i + 2) {
961f1d2b4d3SLarry Finger rtl_rfreg_delay(hw, rfpath, radio_a_table[i],
962f1d2b4d3SLarry Finger MASK20BITS, radio_a_table[i + 1]);
963f1d2b4d3SLarry Finger
964f1d2b4d3SLarry Finger }
965f1d2b4d3SLarry Finger
966f1d2b4d3SLarry Finger /* PA Bias current for inferiority IC */
967f1d2b4d3SLarry Finger _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
968f1d2b4d3SLarry Finger break;
969f1d2b4d3SLarry Finger case RF90_PATH_B:
970f1d2b4d3SLarry Finger for (i = 0; i < radio_b_tblen; i = i + 2) {
971f1d2b4d3SLarry Finger rtl_rfreg_delay(hw, rfpath, radio_b_table[i],
972f1d2b4d3SLarry Finger MASK20BITS, radio_b_table[i + 1]);
973f1d2b4d3SLarry Finger }
974f1d2b4d3SLarry Finger break;
975f1d2b4d3SLarry Finger case RF90_PATH_C:
976f1d2b4d3SLarry Finger ;
977f1d2b4d3SLarry Finger break;
978f1d2b4d3SLarry Finger case RF90_PATH_D:
979f1d2b4d3SLarry Finger ;
980f1d2b4d3SLarry Finger break;
981f1d2b4d3SLarry Finger default:
982f1d2b4d3SLarry Finger break;
983f1d2b4d3SLarry Finger }
984f1d2b4d3SLarry Finger
985f1d2b4d3SLarry Finger return rtstatus;
986f1d2b4d3SLarry Finger }
987f1d2b4d3SLarry Finger
988f1d2b4d3SLarry Finger
rtl92s_phy_mac_config(struct ieee80211_hw * hw)989f1d2b4d3SLarry Finger bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
990f1d2b4d3SLarry Finger {
991f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
992f1d2b4d3SLarry Finger u32 i;
993f1d2b4d3SLarry Finger u32 arraylength;
9942a83ad1fSLarry Finger u32 *ptrarray;
995f1d2b4d3SLarry Finger
996f1d2b4d3SLarry Finger arraylength = MAC_2T_ARRAYLENGTH;
9972a83ad1fSLarry Finger ptrarray = rtl8192semac_2t_array;
998f1d2b4d3SLarry Finger
999f1d2b4d3SLarry Finger for (i = 0; i < arraylength; i = i + 2)
10002a83ad1fSLarry Finger rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
1001f1d2b4d3SLarry Finger
1002f1d2b4d3SLarry Finger return true;
1003f1d2b4d3SLarry Finger }
1004f1d2b4d3SLarry Finger
1005f1d2b4d3SLarry Finger
rtl92s_phy_bb_config(struct ieee80211_hw * hw)1006f1d2b4d3SLarry Finger bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1007f1d2b4d3SLarry Finger {
1008f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1009f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1010711fa16fSColin Ian King bool rtstatus;
1011f1d2b4d3SLarry Finger u8 pathmap, index, rf_num = 0;
1012f1d2b4d3SLarry Finger u8 path1, path2;
1013f1d2b4d3SLarry Finger
1014f1d2b4d3SLarry Finger _rtl92s_phy_init_register_definition(hw);
1015f1d2b4d3SLarry Finger
1016f1d2b4d3SLarry Finger /* Config BB and AGC */
1017f1d2b4d3SLarry Finger rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1018f1d2b4d3SLarry Finger
1019f1d2b4d3SLarry Finger
1020f1d2b4d3SLarry Finger /* Check BB/RF confiuration setting. */
1021f1d2b4d3SLarry Finger /* We only need to configure RF which is turned on. */
1022f1d2b4d3SLarry Finger path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1023f1d2b4d3SLarry Finger mdelay(10);
1024f1d2b4d3SLarry Finger path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1025f1d2b4d3SLarry Finger pathmap = path1 | path2;
1026f1d2b4d3SLarry Finger
1027f1d2b4d3SLarry Finger rtlphy->rf_pathmap = pathmap;
1028f1d2b4d3SLarry Finger for (index = 0; index < 4; index++) {
1029f1d2b4d3SLarry Finger if ((pathmap >> index) & 0x1)
1030f1d2b4d3SLarry Finger rf_num++;
1031f1d2b4d3SLarry Finger }
1032f1d2b4d3SLarry Finger
1033f1d2b4d3SLarry Finger if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1034f1d2b4d3SLarry Finger (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1035f1d2b4d3SLarry Finger (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1036f1d2b4d3SLarry Finger (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
10372d15acacSLarry Finger pr_err("RF_Type(%x) does not match RF_Num(%x)!!\n",
1038f1d2b4d3SLarry Finger rtlphy->rf_type, rf_num);
10392d15acacSLarry Finger pr_err("path1 0x%x, path2 0x%x, pathmap 0x%x\n",
1040f1d2b4d3SLarry Finger path1, path2, pathmap);
1041f1d2b4d3SLarry Finger }
1042f1d2b4d3SLarry Finger
1043f1d2b4d3SLarry Finger return rtstatus;
1044f1d2b4d3SLarry Finger }
1045f1d2b4d3SLarry Finger
rtl92s_phy_rf_config(struct ieee80211_hw * hw)1046f1d2b4d3SLarry Finger bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1047f1d2b4d3SLarry Finger {
1048f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1049f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1050f1d2b4d3SLarry Finger
1051f1d2b4d3SLarry Finger /* Initialize general global value */
1052f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T1R)
1053f1d2b4d3SLarry Finger rtlphy->num_total_rfpath = 1;
1054f1d2b4d3SLarry Finger else
1055f1d2b4d3SLarry Finger rtlphy->num_total_rfpath = 2;
1056f1d2b4d3SLarry Finger
1057f1d2b4d3SLarry Finger /* Config BB and RF */
1058f1d2b4d3SLarry Finger return rtl92s_phy_rf6052_config(hw);
1059f1d2b4d3SLarry Finger }
1060f1d2b4d3SLarry Finger
rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw * hw)1061f1d2b4d3SLarry Finger void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1062f1d2b4d3SLarry Finger {
1063f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1064f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1065f1d2b4d3SLarry Finger
1066f1d2b4d3SLarry Finger /* read rx initial gain */
1067f1d2b4d3SLarry Finger rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1068f1d2b4d3SLarry Finger ROFDM0_XAAGCCORE1, MASKBYTE0);
1069f1d2b4d3SLarry Finger rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1070f1d2b4d3SLarry Finger ROFDM0_XBAGCCORE1, MASKBYTE0);
1071f1d2b4d3SLarry Finger rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1072f1d2b4d3SLarry Finger ROFDM0_XCAGCCORE1, MASKBYTE0);
1073f1d2b4d3SLarry Finger rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1074f1d2b4d3SLarry Finger ROFDM0_XDAGCCORE1, MASKBYTE0);
1075fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1076f1d2b4d3SLarry Finger "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
1077f1d2b4d3SLarry Finger rtlphy->default_initialgain[0],
1078f1d2b4d3SLarry Finger rtlphy->default_initialgain[1],
1079f1d2b4d3SLarry Finger rtlphy->default_initialgain[2],
1080f1d2b4d3SLarry Finger rtlphy->default_initialgain[3]);
1081f1d2b4d3SLarry Finger
1082f1d2b4d3SLarry Finger /* read framesync */
1083f1d2b4d3SLarry Finger rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1084f1d2b4d3SLarry Finger rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1085f1d2b4d3SLarry Finger MASKDWORD);
1086fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1087f1d2b4d3SLarry Finger "Default framesync (0x%x) = 0x%x\n",
1088f1d2b4d3SLarry Finger ROFDM0_RXDETECTOR3, rtlphy->framesync);
1089f1d2b4d3SLarry Finger
1090f1d2b4d3SLarry Finger }
1091f1d2b4d3SLarry Finger
_rtl92s_phy_get_txpower_index(struct ieee80211_hw * hw,u8 channel,u8 * cckpowerlevel,u8 * ofdmpowerlevel)1092f1d2b4d3SLarry Finger static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
10932a83ad1fSLarry Finger u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1094f1d2b4d3SLarry Finger {
1095f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1096f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1097f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1098f1d2b4d3SLarry Finger u8 index = (channel - 1);
1099f1d2b4d3SLarry Finger
1100f1d2b4d3SLarry Finger /* 1. CCK */
1101f1d2b4d3SLarry Finger /* RF-A */
1102f1d2b4d3SLarry Finger cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1103f1d2b4d3SLarry Finger /* RF-B */
1104f1d2b4d3SLarry Finger cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1105f1d2b4d3SLarry Finger
1106f1d2b4d3SLarry Finger /* 2. OFDM for 1T or 2T */
1107f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1108f1d2b4d3SLarry Finger /* Read HT 40 OFDM TX power */
11092a83ad1fSLarry Finger ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
11102a83ad1fSLarry Finger ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1111f1d2b4d3SLarry Finger } else if (rtlphy->rf_type == RF_2T2R) {
1112f1d2b4d3SLarry Finger /* Read HT 40 OFDM TX power */
11132a83ad1fSLarry Finger ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
11142a83ad1fSLarry Finger ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
1115f1d2b4d3SLarry Finger } else {
11162a83ad1fSLarry Finger ofdmpowerlevel[0] = 0;
11172a83ad1fSLarry Finger ofdmpowerlevel[1] = 0;
1118f1d2b4d3SLarry Finger }
1119f1d2b4d3SLarry Finger }
1120f1d2b4d3SLarry Finger
_rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw * hw,u8 channel,u8 * cckpowerlevel,u8 * ofdmpowerlevel)1121f1d2b4d3SLarry Finger static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1122f1d2b4d3SLarry Finger u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1123f1d2b4d3SLarry Finger {
1124f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1125f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1126f1d2b4d3SLarry Finger
1127f1d2b4d3SLarry Finger rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1128f1d2b4d3SLarry Finger rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1129f1d2b4d3SLarry Finger }
1130f1d2b4d3SLarry Finger
rtl92s_phy_set_txpower(struct ieee80211_hw * hw,u8 channel)1131f1d2b4d3SLarry Finger void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1132f1d2b4d3SLarry Finger {
1133f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1134f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1135f1d2b4d3SLarry Finger /* [0]:RF-A, [1]:RF-B */
11362a83ad1fSLarry Finger u8 cckpowerlevel[2], ofdmpowerlevel[2];
1137f1d2b4d3SLarry Finger
1138f1d2b4d3SLarry Finger if (!rtlefuse->txpwr_fromeprom)
1139f1d2b4d3SLarry Finger return;
1140f1d2b4d3SLarry Finger
1141f1d2b4d3SLarry Finger /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1142f1d2b4d3SLarry Finger * but the RF-B Tx Power must be calculated by the antenna diff.
1143f1d2b4d3SLarry Finger * So we have to rewrite Antenna gain offset register here.
1144f1d2b4d3SLarry Finger * Please refer to BB register 0x80c
1145f1d2b4d3SLarry Finger * 1. For CCK.
1146f1d2b4d3SLarry Finger * 2. For OFDM 1T or 2T */
1147f1d2b4d3SLarry Finger _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
11482a83ad1fSLarry Finger &ofdmpowerlevel[0]);
1149f1d2b4d3SLarry Finger
1150fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1151f1d2b4d3SLarry Finger "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1152f1d2b4d3SLarry Finger channel, cckpowerlevel[0], cckpowerlevel[1],
11532a83ad1fSLarry Finger ofdmpowerlevel[0], ofdmpowerlevel[1]);
1154f1d2b4d3SLarry Finger
1155f1d2b4d3SLarry Finger _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
11562a83ad1fSLarry Finger &ofdmpowerlevel[0]);
1157f1d2b4d3SLarry Finger
1158f1d2b4d3SLarry Finger rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
11592a83ad1fSLarry Finger rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerlevel[0], channel);
1160f1d2b4d3SLarry Finger
1161f1d2b4d3SLarry Finger }
1162f1d2b4d3SLarry Finger
rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw * hw)1163f1d2b4d3SLarry Finger void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1164f1d2b4d3SLarry Finger {
1165f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1166f1d2b4d3SLarry Finger u16 pollingcnt = 10000;
1167f1d2b4d3SLarry Finger u32 tmpvalue;
1168f1d2b4d3SLarry Finger
1169f1d2b4d3SLarry Finger /* Make sure that CMD IO has be accepted by FW. */
1170f1d2b4d3SLarry Finger do {
1171f1d2b4d3SLarry Finger udelay(10);
1172f1d2b4d3SLarry Finger
1173f1d2b4d3SLarry Finger tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1174f1d2b4d3SLarry Finger if (tmpvalue == 0)
1175f1d2b4d3SLarry Finger break;
1176f1d2b4d3SLarry Finger } while (--pollingcnt);
1177f1d2b4d3SLarry Finger
1178f1d2b4d3SLarry Finger if (pollingcnt == 0)
11792d15acacSLarry Finger pr_err("Set FW Cmd fail!!\n");
1180f1d2b4d3SLarry Finger }
1181f1d2b4d3SLarry Finger
1182f1d2b4d3SLarry Finger
_rtl92s_phy_set_fwcmd_io(struct ieee80211_hw * hw)1183f1d2b4d3SLarry Finger static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1184f1d2b4d3SLarry Finger {
1185f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1186f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1187f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1188f1d2b4d3SLarry Finger u32 input, current_aid = 0;
1189f1d2b4d3SLarry Finger
1190f1d2b4d3SLarry Finger if (is_hal_stop(rtlhal))
1191f1d2b4d3SLarry Finger return;
1192f1d2b4d3SLarry Finger
1193f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) < 0x34)
1194f1d2b4d3SLarry Finger goto skip;
1195f1d2b4d3SLarry Finger /* We re-map RA related CMD IO to combinational ones */
1196f1d2b4d3SLarry Finger /* if FW version is v.52 or later. */
1197f1d2b4d3SLarry Finger switch (rtlhal->current_fwcmd_io) {
1198f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_N:
1199f1d2b4d3SLarry Finger rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1200f1d2b4d3SLarry Finger break;
1201f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_BG:
1202f1d2b4d3SLarry Finger rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1203f1d2b4d3SLarry Finger break;
1204f1d2b4d3SLarry Finger default:
1205f1d2b4d3SLarry Finger break;
1206f1d2b4d3SLarry Finger }
1207f1d2b4d3SLarry Finger
1208f1d2b4d3SLarry Finger skip:
1209f1d2b4d3SLarry Finger switch (rtlhal->current_fwcmd_io) {
1210f1d2b4d3SLarry Finger case FW_CMD_RA_RESET:
1211fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
1212f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1213f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1214f1d2b4d3SLarry Finger break;
1215f1d2b4d3SLarry Finger case FW_CMD_RA_ACTIVE:
1216fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
1217f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1218f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1219f1d2b4d3SLarry Finger break;
1220f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_N:
1221fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
1222f1d2b4d3SLarry Finger input = FW_RA_REFRESH;
1223f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, input);
1224f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1225f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1226f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1227f1d2b4d3SLarry Finger break;
1228f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_BG:
1229fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG,
1230f1d2b4d3SLarry Finger "FW_CMD_RA_REFRESH_BG\n");
1231f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1232f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1233f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1234f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1235f1d2b4d3SLarry Finger break;
1236f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_N_COMB:
1237fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG,
1238f1d2b4d3SLarry Finger "FW_CMD_RA_REFRESH_N_COMB\n");
1239f1d2b4d3SLarry Finger input = FW_RA_IOT_N_COMB;
1240f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, input);
1241f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1242f1d2b4d3SLarry Finger break;
1243f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_BG_COMB:
1244fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG,
1245f1d2b4d3SLarry Finger "FW_CMD_RA_REFRESH_BG_COMB\n");
1246f1d2b4d3SLarry Finger input = FW_RA_IOT_BG_COMB;
1247f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, input);
1248f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1249f1d2b4d3SLarry Finger break;
1250f1d2b4d3SLarry Finger case FW_CMD_IQK_ENABLE:
1251fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
1252f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1253f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1254f1d2b4d3SLarry Finger break;
1255f1d2b4d3SLarry Finger case FW_CMD_PAUSE_DM_BY_SCAN:
1256f1d2b4d3SLarry Finger /* Lower initial gain */
1257f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1258f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1259f1d2b4d3SLarry Finger /* CCA threshold */
1260f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1261f1d2b4d3SLarry Finger break;
1262f1d2b4d3SLarry Finger case FW_CMD_RESUME_DM_BY_SCAN:
1263f1d2b4d3SLarry Finger /* CCA threshold */
1264f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1265f1d2b4d3SLarry Finger rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1266f1d2b4d3SLarry Finger break;
1267f1d2b4d3SLarry Finger case FW_CMD_HIGH_PWR_DISABLE:
1268f1d2b4d3SLarry Finger if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1269f1d2b4d3SLarry Finger break;
1270f1d2b4d3SLarry Finger
1271f1d2b4d3SLarry Finger /* Lower initial gain */
1272f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1273f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1274f1d2b4d3SLarry Finger /* CCA threshold */
1275f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1276f1d2b4d3SLarry Finger break;
1277f1d2b4d3SLarry Finger case FW_CMD_HIGH_PWR_ENABLE:
1278f1d2b4d3SLarry Finger if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1279f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txpower_enable)
1280f1d2b4d3SLarry Finger break;
1281f1d2b4d3SLarry Finger
1282f1d2b4d3SLarry Finger /* CCA threshold */
1283f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1284f1d2b4d3SLarry Finger break;
1285f1d2b4d3SLarry Finger case FW_CMD_LPS_ENTER:
1286fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
1287f1d2b4d3SLarry Finger current_aid = rtlpriv->mac80211.assoc_id;
1288f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1289f1d2b4d3SLarry Finger ((current_aid | 0xc000) << 8)));
1290f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1291f1d2b4d3SLarry Finger /* FW set TXOP disable here, so disable EDCA
1292f1d2b4d3SLarry Finger * turbo mode until driver leave LPS */
1293f1d2b4d3SLarry Finger break;
1294f1d2b4d3SLarry Finger case FW_CMD_LPS_LEAVE:
1295fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
1296f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1297f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1298f1d2b4d3SLarry Finger break;
1299f1d2b4d3SLarry Finger case FW_CMD_ADD_A2_ENTRY:
1300fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
1301f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1302f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1303f1d2b4d3SLarry Finger break;
1304f1d2b4d3SLarry Finger case FW_CMD_CTRL_DM_BY_DRIVER:
1305fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1306f1d2b4d3SLarry Finger "FW_CMD_CTRL_DM_BY_DRIVER\n");
1307f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1308f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1309f1d2b4d3SLarry Finger break;
1310f1d2b4d3SLarry Finger
1311f1d2b4d3SLarry Finger default:
1312f1d2b4d3SLarry Finger break;
1313f1d2b4d3SLarry Finger }
1314f1d2b4d3SLarry Finger
1315f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1316f1d2b4d3SLarry Finger
1317f1d2b4d3SLarry Finger /* Clear FW CMD operation flag. */
1318f1d2b4d3SLarry Finger rtlhal->set_fwcmd_inprogress = false;
1319f1d2b4d3SLarry Finger }
1320f1d2b4d3SLarry Finger
rtl92s_phy_set_fw_cmd(struct ieee80211_hw * hw,enum fwcmd_iotype fw_cmdio)1321f1d2b4d3SLarry Finger bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1322f1d2b4d3SLarry Finger {
1323f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1324f1d2b4d3SLarry Finger struct dig_t *digtable = &rtlpriv->dm_digtable;
1325f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1326f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1327f1d2b4d3SLarry Finger u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1328f1d2b4d3SLarry Finger u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1329f1d2b4d3SLarry Finger bool postprocessing = false;
1330f1d2b4d3SLarry Finger
1331fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1332f1d2b4d3SLarry Finger "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1333f1d2b4d3SLarry Finger fw_cmdio, rtlhal->set_fwcmd_inprogress);
1334f1d2b4d3SLarry Finger
1335f1d2b4d3SLarry Finger do {
1336f1d2b4d3SLarry Finger /* We re-map to combined FW CMD ones if firmware version */
1337f1d2b4d3SLarry Finger /* is v.53 or later. */
1338f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1339f1d2b4d3SLarry Finger switch (fw_cmdio) {
1340f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_N:
1341f1d2b4d3SLarry Finger fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1342f1d2b4d3SLarry Finger break;
1343f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_BG:
1344f1d2b4d3SLarry Finger fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1345f1d2b4d3SLarry Finger break;
1346f1d2b4d3SLarry Finger default:
1347f1d2b4d3SLarry Finger break;
1348f1d2b4d3SLarry Finger }
1349f1d2b4d3SLarry Finger } else {
1350f1d2b4d3SLarry Finger if ((fw_cmdio == FW_CMD_IQK_ENABLE) ||
1351f1d2b4d3SLarry Finger (fw_cmdio == FW_CMD_RA_REFRESH_N) ||
1352f1d2b4d3SLarry Finger (fw_cmdio == FW_CMD_RA_REFRESH_BG)) {
1353f1d2b4d3SLarry Finger postprocessing = true;
1354f1d2b4d3SLarry Finger break;
1355f1d2b4d3SLarry Finger }
1356f1d2b4d3SLarry Finger }
1357f1d2b4d3SLarry Finger
1358f1d2b4d3SLarry Finger /* If firmware version is v.62 or later,
1359f1d2b4d3SLarry Finger * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1360f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1361f1d2b4d3SLarry Finger if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1362f1d2b4d3SLarry Finger fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1363f1d2b4d3SLarry Finger }
1364f1d2b4d3SLarry Finger
1365f1d2b4d3SLarry Finger
1366f1d2b4d3SLarry Finger /* We shall revise all FW Cmd IO into Reg0x364
1367f1d2b4d3SLarry Finger * DM map table in the future. */
1368f1d2b4d3SLarry Finger switch (fw_cmdio) {
1369f1d2b4d3SLarry Finger case FW_CMD_RA_INIT:
1370fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
1371f1d2b4d3SLarry Finger fw_cmdmap |= FW_RA_INIT_CTL;
1372f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1373f1d2b4d3SLarry Finger /* Clear control flag to sync with FW. */
1374f1d2b4d3SLarry Finger FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1375f1d2b4d3SLarry Finger break;
1376f1d2b4d3SLarry Finger case FW_CMD_DIG_DISABLE:
1377fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1378f1d2b4d3SLarry Finger "Set DIG disable!!\n");
1379f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1380f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1381f1d2b4d3SLarry Finger break;
1382f1d2b4d3SLarry Finger case FW_CMD_DIG_ENABLE:
1383f1d2b4d3SLarry Finger case FW_CMD_DIG_RESUME:
1384f1d2b4d3SLarry Finger if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1385fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1386f1d2b4d3SLarry Finger "Set DIG enable or resume!!\n");
1387f1d2b4d3SLarry Finger fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1388f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1389f1d2b4d3SLarry Finger }
1390f1d2b4d3SLarry Finger break;
1391f1d2b4d3SLarry Finger case FW_CMD_DIG_HALT:
1392fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1393f1d2b4d3SLarry Finger "Set DIG halt!!\n");
1394f1d2b4d3SLarry Finger fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1395f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1396f1d2b4d3SLarry Finger break;
1397f1d2b4d3SLarry Finger case FW_CMD_TXPWR_TRACK_THERMAL: {
1398f1d2b4d3SLarry Finger u8 thermalval = 0;
1399f1d2b4d3SLarry Finger fw_cmdmap |= FW_PWR_TRK_CTL;
1400f1d2b4d3SLarry Finger
1401f1d2b4d3SLarry Finger /* Clear FW parameter in terms of thermal parts. */
1402f1d2b4d3SLarry Finger fw_param &= FW_PWR_TRK_PARAM_CLR;
1403f1d2b4d3SLarry Finger
1404f1d2b4d3SLarry Finger thermalval = rtlpriv->dm.thermalvalue;
1405f1d2b4d3SLarry Finger fw_param |= ((thermalval << 24) |
1406f1d2b4d3SLarry Finger (rtlefuse->thermalmeter[0] << 16));
1407f1d2b4d3SLarry Finger
1408fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1409f1d2b4d3SLarry Finger "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
1410f1d2b4d3SLarry Finger fw_cmdmap, fw_param);
1411f1d2b4d3SLarry Finger
1412f1d2b4d3SLarry Finger FW_CMD_PARA_SET(rtlpriv, fw_param);
1413f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1414f1d2b4d3SLarry Finger
1415f1d2b4d3SLarry Finger /* Clear control flag to sync with FW. */
1416f1d2b4d3SLarry Finger FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1417f1d2b4d3SLarry Finger }
1418f1d2b4d3SLarry Finger break;
1419f1d2b4d3SLarry Finger /* The following FW CMDs are only compatible to
1420f1d2b4d3SLarry Finger * v.53 or later. */
1421f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_N_COMB:
1422f1d2b4d3SLarry Finger fw_cmdmap |= FW_RA_N_CTL;
1423f1d2b4d3SLarry Finger
1424f1d2b4d3SLarry Finger /* Clear RA BG mode control. */
1425f1d2b4d3SLarry Finger fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1426f1d2b4d3SLarry Finger
1427f1d2b4d3SLarry Finger /* Clear FW parameter in terms of RA parts. */
1428f1d2b4d3SLarry Finger fw_param &= FW_RA_PARAM_CLR;
1429f1d2b4d3SLarry Finger
1430fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1431f1d2b4d3SLarry Finger "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
1432f1d2b4d3SLarry Finger fw_cmdmap, fw_param);
1433f1d2b4d3SLarry Finger
1434f1d2b4d3SLarry Finger FW_CMD_PARA_SET(rtlpriv, fw_param);
1435f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1436f1d2b4d3SLarry Finger
1437f1d2b4d3SLarry Finger /* Clear control flag to sync with FW. */
1438f1d2b4d3SLarry Finger FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1439f1d2b4d3SLarry Finger break;
1440f1d2b4d3SLarry Finger case FW_CMD_RA_REFRESH_BG_COMB:
1441f1d2b4d3SLarry Finger fw_cmdmap |= FW_RA_BG_CTL;
1442f1d2b4d3SLarry Finger
1443f1d2b4d3SLarry Finger /* Clear RA n-mode control. */
1444f1d2b4d3SLarry Finger fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1445f1d2b4d3SLarry Finger /* Clear FW parameter in terms of RA parts. */
1446f1d2b4d3SLarry Finger fw_param &= FW_RA_PARAM_CLR;
1447f1d2b4d3SLarry Finger
1448f1d2b4d3SLarry Finger FW_CMD_PARA_SET(rtlpriv, fw_param);
1449f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1450f1d2b4d3SLarry Finger
1451f1d2b4d3SLarry Finger /* Clear control flag to sync with FW. */
1452f1d2b4d3SLarry Finger FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1453f1d2b4d3SLarry Finger break;
1454f1d2b4d3SLarry Finger case FW_CMD_IQK_ENABLE:
1455f1d2b4d3SLarry Finger fw_cmdmap |= FW_IQK_CTL;
1456f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1457f1d2b4d3SLarry Finger /* Clear control flag to sync with FW. */
1458f1d2b4d3SLarry Finger FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1459f1d2b4d3SLarry Finger break;
1460f1d2b4d3SLarry Finger /* The following FW CMD is compatible to v.62 or later. */
1461f1d2b4d3SLarry Finger case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1462f1d2b4d3SLarry Finger fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1463f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1464f1d2b4d3SLarry Finger break;
1465f1d2b4d3SLarry Finger /* The followed FW Cmds needs post-processing later. */
1466f1d2b4d3SLarry Finger case FW_CMD_RESUME_DM_BY_SCAN:
1467f1d2b4d3SLarry Finger fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1468f1d2b4d3SLarry Finger FW_HIGH_PWR_ENABLE_CTL |
1469f1d2b4d3SLarry Finger FW_SS_CTL);
1470f1d2b4d3SLarry Finger
1471f1d2b4d3SLarry Finger if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1472f1d2b4d3SLarry Finger !digtable->dig_enable_flag)
1473f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1474f1d2b4d3SLarry Finger
1475f1d2b4d3SLarry Finger if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1476f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txpower_enable)
1477f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1478f1d2b4d3SLarry Finger
1479f1d2b4d3SLarry Finger if ((digtable->dig_ext_port_stage ==
1480f1d2b4d3SLarry Finger DIG_EXT_PORT_STAGE_0) ||
1481f1d2b4d3SLarry Finger (digtable->dig_ext_port_stage ==
1482f1d2b4d3SLarry Finger DIG_EXT_PORT_STAGE_1))
1483f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1484f1d2b4d3SLarry Finger
1485f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1486f1d2b4d3SLarry Finger postprocessing = true;
1487f1d2b4d3SLarry Finger break;
1488f1d2b4d3SLarry Finger case FW_CMD_PAUSE_DM_BY_SCAN:
1489f1d2b4d3SLarry Finger fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1490f1d2b4d3SLarry Finger FW_HIGH_PWR_ENABLE_CTL |
1491f1d2b4d3SLarry Finger FW_SS_CTL);
1492f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1493f1d2b4d3SLarry Finger postprocessing = true;
1494f1d2b4d3SLarry Finger break;
1495f1d2b4d3SLarry Finger case FW_CMD_HIGH_PWR_DISABLE:
1496f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1497f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1498f1d2b4d3SLarry Finger postprocessing = true;
1499f1d2b4d3SLarry Finger break;
1500f1d2b4d3SLarry Finger case FW_CMD_HIGH_PWR_ENABLE:
1501f1d2b4d3SLarry Finger if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1502f1d2b4d3SLarry Finger !rtlpriv->dm.dynamic_txpower_enable) {
1503f1d2b4d3SLarry Finger fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1504f1d2b4d3SLarry Finger FW_SS_CTL);
1505f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1506f1d2b4d3SLarry Finger postprocessing = true;
1507f1d2b4d3SLarry Finger }
1508f1d2b4d3SLarry Finger break;
1509f1d2b4d3SLarry Finger case FW_CMD_DIG_MODE_FA:
1510f1d2b4d3SLarry Finger fw_cmdmap |= FW_FA_CTL;
1511f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1512f1d2b4d3SLarry Finger break;
1513f1d2b4d3SLarry Finger case FW_CMD_DIG_MODE_SS:
1514f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_FA_CTL;
1515f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1516f1d2b4d3SLarry Finger break;
1517f1d2b4d3SLarry Finger case FW_CMD_PAPE_CONTROL:
1518fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
1519f1d2b4d3SLarry Finger "[FW CMD] Set PAPE Control\n");
1520f1d2b4d3SLarry Finger fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1521f1d2b4d3SLarry Finger
1522f1d2b4d3SLarry Finger FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1523f1d2b4d3SLarry Finger break;
1524f1d2b4d3SLarry Finger default:
1525f1d2b4d3SLarry Finger /* Pass to original FW CMD processing callback
1526f1d2b4d3SLarry Finger * routine. */
1527f1d2b4d3SLarry Finger postprocessing = true;
1528f1d2b4d3SLarry Finger break;
1529f1d2b4d3SLarry Finger }
1530f1d2b4d3SLarry Finger } while (false);
1531f1d2b4d3SLarry Finger
1532f1d2b4d3SLarry Finger /* We shall post processing these FW CMD if
1533f1d2b4d3SLarry Finger * variable postprocessing is set.
1534f1d2b4d3SLarry Finger */
1535f1d2b4d3SLarry Finger if (postprocessing && !rtlhal->set_fwcmd_inprogress) {
1536f1d2b4d3SLarry Finger rtlhal->set_fwcmd_inprogress = true;
1537f1d2b4d3SLarry Finger /* Update current FW Cmd for callback use. */
1538f1d2b4d3SLarry Finger rtlhal->current_fwcmd_io = fw_cmdio;
1539f1d2b4d3SLarry Finger } else {
1540f1d2b4d3SLarry Finger return false;
1541f1d2b4d3SLarry Finger }
1542f1d2b4d3SLarry Finger
1543f1d2b4d3SLarry Finger _rtl92s_phy_set_fwcmd_io(hw);
1544f1d2b4d3SLarry Finger return true;
1545f1d2b4d3SLarry Finger }
1546f1d2b4d3SLarry Finger
_rtl92s_phy_check_ephy_switchready(struct ieee80211_hw * hw)1547f1d2b4d3SLarry Finger static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1548f1d2b4d3SLarry Finger {
1549f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1550f1d2b4d3SLarry Finger u32 delay = 100;
1551f1d2b4d3SLarry Finger u8 regu1;
1552f1d2b4d3SLarry Finger
1553f1d2b4d3SLarry Finger regu1 = rtl_read_byte(rtlpriv, 0x554);
1554f1d2b4d3SLarry Finger while ((regu1 & BIT(5)) && (delay > 0)) {
1555f1d2b4d3SLarry Finger regu1 = rtl_read_byte(rtlpriv, 0x554);
1556f1d2b4d3SLarry Finger delay--;
1557f1d2b4d3SLarry Finger /* We delay only 50us to prevent
1558f1d2b4d3SLarry Finger * being scheduled out. */
1559f1d2b4d3SLarry Finger udelay(50);
1560f1d2b4d3SLarry Finger }
1561f1d2b4d3SLarry Finger }
1562f1d2b4d3SLarry Finger
rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw * hw)1563f1d2b4d3SLarry Finger void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1564f1d2b4d3SLarry Finger {
1565f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1566f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1567f1d2b4d3SLarry Finger
1568f1d2b4d3SLarry Finger /* The way to be capable to switch clock request
1569f1d2b4d3SLarry Finger * when the PG setting does not support clock request.
1570f1d2b4d3SLarry Finger * This is the backdoor solution to switch clock
1571f1d2b4d3SLarry Finger * request before ASPM or D3. */
1572f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1573f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1574f1d2b4d3SLarry Finger
1575f1d2b4d3SLarry Finger /* Switch EPHY parameter!!!! */
1576f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, 0x550, 0x1000);
1577f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x554, 0x20);
1578f1d2b4d3SLarry Finger _rtl92s_phy_check_ephy_switchready(hw);
1579f1d2b4d3SLarry Finger
1580f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1581f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x554, 0x3e);
1582f1d2b4d3SLarry Finger _rtl92s_phy_check_ephy_switchready(hw);
1583f1d2b4d3SLarry Finger
1584f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, 0x550, 0xff80);
1585f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x554, 0x39);
1586f1d2b4d3SLarry Finger _rtl92s_phy_check_ephy_switchready(hw);
1587f1d2b4d3SLarry Finger
1588f1d2b4d3SLarry Finger /* Delay L1 enter time */
1589f1d2b4d3SLarry Finger if (ppsc->support_aspm && !ppsc->support_backdoor)
1590f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x560, 0x40);
1591f1d2b4d3SLarry Finger else
1592f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x560, 0x00);
1593f1d2b4d3SLarry Finger
1594f1d2b4d3SLarry Finger }
1595f1d2b4d3SLarry Finger
rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw * hw,u16 beaconinterval)1596f1d2b4d3SLarry Finger void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval)
1597f1d2b4d3SLarry Finger {
1598f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1599f1d2b4d3SLarry Finger u32 new_bcn_num = 0;
1600f1d2b4d3SLarry Finger
1601f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x33) {
1602f1d2b4d3SLarry Finger /* Fw v.51 and later. */
1603f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, 0xF1000000 |
1604f1d2b4d3SLarry Finger (beaconinterval << 8));
1605f1d2b4d3SLarry Finger } else {
1606f1d2b4d3SLarry Finger new_bcn_num = beaconinterval * 32 - 64;
1607f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num);
1608f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM3, 0xB026007C);
1609f1d2b4d3SLarry Finger }
1610f1d2b4d3SLarry Finger }
1611