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