net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / phydm / phydm_dfs.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21 /*
22 ============================================================
23  include files
24 ============================================================
25 */
26
27 #include "mp_precomp.h"
28 #include "phydm_precomp.h"
29
30 #if defined(CONFIG_PHYDM_DFS_MASTER)
31 void phydm_radar_detect_reset(void *p_dm_void)
32 {
33         struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
34
35         odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 0);
36         odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 1);
37 }
38
39 void phydm_radar_detect_disable(void *p_dm_void)
40 {
41         struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
42
43         odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 0);
44         ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("\n"));
45 }
46
47 static void phydm_radar_detect_with_dbg_parm(void *p_dm_void)
48 {
49         struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
50
51         odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, p_dm_odm->radar_detect_reg_918);
52         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, p_dm_odm->radar_detect_reg_91c);
53         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, p_dm_odm->radar_detect_reg_920);
54         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, p_dm_odm->radar_detect_reg_924);
55 }
56
57 /* Init radar detection parameters, called after ch, bw is set */
58 void phydm_radar_detect_enable(void *p_dm_void)
59 {
60         struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
61         u8 region_domain = p_dm_odm->dfs_region_domain;
62         u8 c_channel = *(p_dm_odm->p_channel);
63         u8 band_width = *(p_dm_odm->p_band_width);
64         u8 enable = 0;
65
66         if (region_domain == PHYDM_DFS_DOMAIN_UNKNOWN) {
67                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("PHYDM_DFS_DOMAIN_UNKNOWN\n"));
68                 goto exit;
69         }
70
71         if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8812 | ODM_RTL8881A)) {
72
73                 odm_set_bb_reg(p_dm_odm, 0x814, 0x3fffffff, 0x04cc4d10);
74                 odm_set_bb_reg(p_dm_odm, 0x834, MASKBYTE0, 0x06);
75
76                 if (p_dm_odm->radar_detect_dbg_parm_en) {
77                         phydm_radar_detect_with_dbg_parm(p_dm_odm);
78                         enable = 1;
79                         goto exit;
80                 }
81
82                 if (region_domain == PHYDM_DFS_DOMAIN_ETSI) {
83                         odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c17ecdf);
84                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
85                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0fa21a20);
86                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0f69204);
87
88                 } else if (region_domain == PHYDM_DFS_DOMAIN_MKK) {
89                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
90                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67234);
91
92                         if (c_channel >= 52 && c_channel <= 64) {
93                                 odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16ecdf);
94                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0f141a20);
95                         } else {
96                                 odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
97                                 if (band_width == ODM_BW20M)
98                                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64721a20);
99                                 else
100                                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68721a20);
101                         }
102
103                 } else if (region_domain == PHYDM_DFS_DOMAIN_FCC) {
104                         odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
105                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
106                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67231);
107                         if (band_width == ODM_BW20M)
108                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64741a20);
109                         else
110                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68741a20);
111
112                 } else {
113                         /* not supported */
114                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported dfs_region_domain:%d\n", region_domain));
115                         goto exit;
116                 }
117
118         } else if (p_dm_odm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
119
120                 odm_set_bb_reg(p_dm_odm, 0x814, 0x3fffffff, 0x04cc4d10);
121                 odm_set_bb_reg(p_dm_odm, 0x834, MASKBYTE0, 0x06);
122
123                 /* 8822B only, when BW = 20M, DFIR output is 40Mhz, but DFS input is 80MMHz, so it need to upgrade to 80MHz */
124                 if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
125                         if (band_width == ODM_BW20M)
126                                 odm_set_bb_reg(p_dm_odm, 0x1984, BIT(26), 1);
127                         else
128                                 odm_set_bb_reg(p_dm_odm, 0x1984, BIT(26), 0);
129                 }
130
131                 if (p_dm_odm->radar_detect_dbg_parm_en) {
132                         phydm_radar_detect_with_dbg_parm(p_dm_odm);
133                         enable = 1;
134                         goto exit;
135                 }
136
137                 if (region_domain == PHYDM_DFS_DOMAIN_ETSI) {
138                         odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
139                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
140                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0fa21a20);
141                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0f57204);
142
143                 } else if (region_domain == PHYDM_DFS_DOMAIN_MKK) {
144                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
145                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67234);
146
147                         if (c_channel >= 52 && c_channel <= 64) {
148                                 odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16ecdf);
149                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0f141a20);
150                         } else {
151                                 odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c166cdf);
152                                 if (band_width == ODM_BW20M)
153                                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64721a20);
154                                 else
155                                         odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68721a20);
156                         }
157
158                 } else if (region_domain == PHYDM_DFS_DOMAIN_FCC) {
159                         odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c166cdf);
160                         odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
161                         odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67231);
162                         if (band_width == ODM_BW20M)
163                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64741a20);
164                         else
165                                 odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68741a20);
166
167                 } else {
168                         /* not supported */
169                         ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported dfs_region_domain:%d\n", region_domain));
170                         goto exit;
171                 }
172         } else {
173                 /* not supported IC type*/
174                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported IC type:%d\n", p_dm_odm->support_ic_type));
175                 goto exit;
176         }
177
178         enable = 1;
179
180 exit:
181         if (enable) {
182                 phydm_radar_detect_reset(p_dm_odm);
183                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("on cch:%u, bw:%u\n", c_channel, band_width));
184         } else
185                 phydm_radar_detect_disable(p_dm_odm);
186 }
187
188 boolean phydm_radar_detect(void *p_dm_void)
189 {
190         struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
191         boolean enable_DFS = false;
192         boolean radar_detected = false;
193         u8 region_domain = p_dm_odm->dfs_region_domain;
194
195         if (region_domain == PHYDM_DFS_DOMAIN_UNKNOWN) {
196                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("PHYDM_DFS_DOMAIN_UNKNOWN\n"));
197                 return false;
198         }
199
200         if (odm_get_bb_reg(p_dm_odm, 0x924, BIT(15)))
201                 enable_DFS = true;
202
203         if ((odm_get_bb_reg(p_dm_odm, 0xf98, BIT(17)))
204             || (!(region_domain == PHYDM_DFS_DOMAIN_ETSI) && (odm_get_bb_reg(p_dm_odm, 0xf98, BIT(19)))))
205                 radar_detected = true;
206
207         if (enable_DFS && radar_detected) {
208                 ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD
209                         , ("Radar detect: enable_DFS:%d, radar_detected:%d\n"
210                                 , enable_DFS, radar_detected));
211
212                 phydm_radar_detect_reset(p_dm_odm);
213         }
214
215 exit:
216         return enable_DFS && radar_detected;
217 }
218 #endif /* defined(CONFIG_PHYDM_DFS_MASTER) */
219
220 boolean
221 phydm_dfs_master_enabled(
222         void            *p_dm_void
223 )
224 {
225 #ifdef CONFIG_PHYDM_DFS_MASTER
226         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
227
228         return *p_dm_odm->dfs_master_enabled ? true : false;
229 #else
230         return false;
231 #endif
232 }
233
234 void
235 phydm_dfs_debug(
236         void            *p_dm_void,
237         u32             *const argv,
238         u32             *_used,
239         char            *output,
240         u32             *_out_len
241 )
242 {
243         struct PHY_DM_STRUCT            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
244         u32 used = *_used;
245         u32 out_len = *_out_len;
246
247         switch (argv[0]) {
248         case 1:
249 #if defined(CONFIG_PHYDM_DFS_MASTER)
250                 /* set dbg parameters for radar detection instead of the default value */
251                 if (argv[1] == 1) {
252                         p_dm_odm->radar_detect_reg_918 = argv[2];
253                         p_dm_odm->radar_detect_reg_91c = argv[3];
254                         p_dm_odm->radar_detect_reg_920 = argv[4];
255                         p_dm_odm->radar_detect_reg_924 = argv[5];
256                         p_dm_odm->radar_detect_dbg_parm_en = 1;
257
258                         PHYDM_SNPRINTF((output + used, out_len - used, "Radar detection with dbg parameter\n"));
259                         PHYDM_SNPRINTF((output + used, out_len - used, "reg918:0x%08X\n", p_dm_odm->radar_detect_reg_918));
260                         PHYDM_SNPRINTF((output + used, out_len - used, "reg91c:0x%08X\n", p_dm_odm->radar_detect_reg_91c));
261                         PHYDM_SNPRINTF((output + used, out_len - used, "reg920:0x%08X\n", p_dm_odm->radar_detect_reg_920));
262                         PHYDM_SNPRINTF((output + used, out_len - used, "reg924:0x%08X\n", p_dm_odm->radar_detect_reg_924));
263                 } else {
264                         p_dm_odm->radar_detect_dbg_parm_en = 0;
265                         PHYDM_SNPRINTF((output + used, out_len - used, "Radar detection with default parameter\n"));
266                 }
267                 phydm_radar_detect_enable(p_dm_odm);
268 #endif /* defined(CONFIG_PHYDM_DFS_MASTER) */
269
270                 break;
271         default:
272                 break;
273         }
274 }