1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 
15 /* ************************************************************
16  * include files
17  * *************************************************************/
18 
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
21 
22 /*
23  * ODM IO Relative API.
24  */
25 
odm_read_1byte(struct phy_dm_struct * dm,u32 reg_addr)26 u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr)
27 {
28 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
29 
30 	return rtl_read_byte(rtlpriv, reg_addr);
31 }
32 
odm_read_2byte(struct phy_dm_struct * dm,u32 reg_addr)33 u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr)
34 {
35 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
36 
37 	return rtl_read_word(rtlpriv, reg_addr);
38 }
39 
odm_read_4byte(struct phy_dm_struct * dm,u32 reg_addr)40 u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr)
41 {
42 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
43 
44 	return rtl_read_dword(rtlpriv, reg_addr);
45 }
46 
odm_write_1byte(struct phy_dm_struct * dm,u32 reg_addr,u8 data)47 void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data)
48 {
49 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
50 
51 	rtl_write_byte(rtlpriv, reg_addr, data);
52 }
53 
odm_write_2byte(struct phy_dm_struct * dm,u32 reg_addr,u16 data)54 void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data)
55 {
56 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
57 
58 	rtl_write_word(rtlpriv, reg_addr, data);
59 }
60 
odm_write_4byte(struct phy_dm_struct * dm,u32 reg_addr,u32 data)61 void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data)
62 {
63 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
64 
65 	rtl_write_dword(rtlpriv, reg_addr, data);
66 }
67 
odm_set_mac_reg(struct phy_dm_struct * dm,u32 reg_addr,u32 bit_mask,u32 data)68 void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
69 		     u32 data)
70 {
71 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
72 
73 	rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data);
74 }
75 
odm_get_mac_reg(struct phy_dm_struct * dm,u32 reg_addr,u32 bit_mask)76 u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask)
77 {
78 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
79 
80 	return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask);
81 }
82 
odm_set_bb_reg(struct phy_dm_struct * dm,u32 reg_addr,u32 bit_mask,u32 data)83 void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask,
84 		    u32 data)
85 {
86 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
87 
88 	rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data);
89 }
90 
odm_get_bb_reg(struct phy_dm_struct * dm,u32 reg_addr,u32 bit_mask)91 u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask)
92 {
93 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
94 
95 	return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask);
96 }
97 
odm_set_rf_reg(struct phy_dm_struct * dm,enum odm_rf_radio_path e_rf_path,u32 reg_addr,u32 bit_mask,u32 data)98 void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
99 		    u32 reg_addr, u32 bit_mask, u32 data)
100 {
101 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
102 
103 	rtl_set_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr,
104 		      bit_mask, data);
105 }
106 
odm_get_rf_reg(struct phy_dm_struct * dm,enum odm_rf_radio_path e_rf_path,u32 reg_addr,u32 bit_mask)107 u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path,
108 		   u32 reg_addr, u32 bit_mask)
109 {
110 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
111 
112 	return rtl_get_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr,
113 			     bit_mask);
114 }
115 
116 /*
117  * ODM Memory relative API.
118  */
odm_allocate_memory(struct phy_dm_struct * dm,void ** ptr,u32 length)119 void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length)
120 {
121 	*ptr = kmalloc(length, GFP_ATOMIC);
122 }
123 
124 /* length could be ignored, used to detect memory leakage. */
odm_free_memory(struct phy_dm_struct * dm,void * ptr,u32 length)125 void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length)
126 {
127 	kfree(ptr);
128 }
129 
odm_move_memory(struct phy_dm_struct * dm,void * p_dest,void * src,u32 length)130 void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src,
131 		     u32 length)
132 {
133 	memcpy(p_dest, src, length);
134 }
135 
odm_memory_set(struct phy_dm_struct * dm,void * pbuf,s8 value,u32 length)136 void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length)
137 {
138 	memset(pbuf, value, length);
139 }
140 
odm_compare_memory(struct phy_dm_struct * dm,void * p_buf1,void * buf2,u32 length)141 s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2,
142 		       u32 length)
143 {
144 	return memcmp(p_buf1, buf2, length);
145 }
146 
147 /*
148  * ODM MISC relative API.
149  */
odm_acquire_spin_lock(struct phy_dm_struct * dm,enum rt_spinlock_type type)150 void odm_acquire_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type)
151 {
152 }
153 
odm_release_spin_lock(struct phy_dm_struct * dm,enum rt_spinlock_type type)154 void odm_release_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type)
155 {
156 }
157 
158 /*
159  * ODM Timer relative API.
160  */
odm_stall_execution(u32 us_delay)161 void odm_stall_execution(u32 us_delay) { udelay(us_delay); }
162 
ODM_delay_ms(u32 ms)163 void ODM_delay_ms(u32 ms) { mdelay(ms); }
164 
ODM_delay_us(u32 us)165 void ODM_delay_us(u32 us) { udelay(us); }
166 
ODM_sleep_ms(u32 ms)167 void ODM_sleep_ms(u32 ms) { msleep(ms); }
168 
ODM_sleep_us(u32 us)169 void ODM_sleep_us(u32 us) { usleep_range(us, us + 1); }
170 
phydm_trans_h2c_id(struct phy_dm_struct * dm,u8 phydm_h2c_id)171 static u8 phydm_trans_h2c_id(struct phy_dm_struct *dm, u8 phydm_h2c_id)
172 {
173 	u8 platform_h2c_id = phydm_h2c_id;
174 
175 	switch (phydm_h2c_id) {
176 	/* 1 [0] */
177 	case ODM_H2C_RSSI_REPORT:
178 
179 		break;
180 
181 	/* 1 [3] */
182 	case ODM_H2C_WIFI_CALIBRATION:
183 
184 		break;
185 
186 	/* 1 [4] */
187 	case ODM_H2C_IQ_CALIBRATION:
188 
189 		break;
190 	/* 1 [5] */
191 	case ODM_H2C_RA_PARA_ADJUST:
192 
193 		break;
194 
195 	/* 1 [6] */
196 	case PHYDM_H2C_DYNAMIC_TX_PATH:
197 
198 		break;
199 
200 	/* [7]*/
201 	case PHYDM_H2C_FW_TRACE_EN:
202 
203 		platform_h2c_id = 0x49;
204 
205 		break;
206 
207 	case PHYDM_H2C_TXBF:
208 		break;
209 
210 	case PHYDM_H2C_MU:
211 		platform_h2c_id = 0x4a; /*H2C_MU*/
212 		break;
213 
214 	default:
215 		platform_h2c_id = phydm_h2c_id;
216 		break;
217 	}
218 
219 	return platform_h2c_id;
220 }
221 
222 /*ODM FW relative API.*/
223 
odm_fill_h2c_cmd(struct phy_dm_struct * dm,u8 phydm_h2c_id,u32 cmd_len,u8 * cmd_buffer)224 void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 phydm_h2c_id, u32 cmd_len,
225 		      u8 *cmd_buffer)
226 {
227 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
228 	u8 platform_h2c_id;
229 
230 	platform_h2c_id = phydm_trans_h2c_id(dm, phydm_h2c_id);
231 
232 	ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG,
233 		     "[H2C]  platform_h2c_id = ((0x%x))\n", platform_h2c_id);
234 
235 	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->hw, platform_h2c_id, cmd_len,
236 					cmd_buffer);
237 }
238 
phydm_c2H_content_parsing(void * dm_void,u8 c2h_cmd_id,u8 c2h_cmd_len,u8 * tmp_buf)239 u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len,
240 			     u8 *tmp_buf)
241 {
242 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
243 	u8 extend_c2h_sub_id = 0;
244 	u8 find_c2h_cmd = true;
245 
246 	switch (c2h_cmd_id) {
247 	case PHYDM_C2H_DBG:
248 		phydm_fw_trace_handler(dm, tmp_buf, c2h_cmd_len);
249 		break;
250 
251 	case PHYDM_C2H_RA_RPT:
252 		phydm_c2h_ra_report_handler(dm, tmp_buf, c2h_cmd_len);
253 		break;
254 
255 	case PHYDM_C2H_RA_PARA_RPT:
256 		odm_c2h_ra_para_report_handler(dm, tmp_buf, c2h_cmd_len);
257 		break;
258 
259 	case PHYDM_C2H_DYNAMIC_TX_PATH_RPT:
260 		break;
261 
262 	case PHYDM_C2H_IQK_FINISH:
263 		break;
264 
265 	case PHYDM_C2H_DBG_CODE:
266 		phydm_fw_trace_handler_code(dm, tmp_buf, c2h_cmd_len);
267 		break;
268 
269 	case PHYDM_C2H_EXTEND:
270 		extend_c2h_sub_id = tmp_buf[0];
271 		if (extend_c2h_sub_id == PHYDM_EXTEND_C2H_DBG_PRINT)
272 			phydm_fw_trace_handler_8051(dm, tmp_buf, c2h_cmd_len);
273 
274 		break;
275 
276 	default:
277 		find_c2h_cmd = false;
278 		break;
279 	}
280 
281 	return find_c2h_cmd;
282 }
283 
odm_get_current_time(struct phy_dm_struct * dm)284 u64 odm_get_current_time(struct phy_dm_struct *dm) { return jiffies; }
285 
odm_get_progressing_time(struct phy_dm_struct * dm,u64 start_time)286 u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time)
287 {
288 	return jiffies_to_msecs(jiffies - (u32)start_time);
289 }
290 
odm_set_tx_power_index_by_rate_section(struct phy_dm_struct * dm,u8 rf_path,u8 channel,u8 rate_section)291 void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm,
292 					    u8 rf_path, u8 channel,
293 					    u8 rate_section)
294 {
295 	void *adapter = dm->adapter;
296 
297 	phy_set_tx_power_index_by_rs(adapter, channel, rf_path, rate_section);
298 }
299 
odm_get_tx_power_index(struct phy_dm_struct * dm,u8 rf_path,u8 tx_rate,u8 band_width,u8 channel)300 u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate,
301 			  u8 band_width, u8 channel)
302 {
303 	void *adapter = dm->adapter;
304 
305 	return phy_get_tx_power_index(adapter, (enum odm_rf_radio_path)rf_path,
306 				      tx_rate, band_width, channel);
307 }
308