net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / hal_com_phycfg.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 #define _HAL_COM_PHYCFG_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 #define PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) (((_pg_v) & 0xf0) >> 4)
26 #define PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) ((_pg_v) & 0x0f)
27 #define PG_TXPWR_MSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_MSB_DIFF_S4BIT(_pg_v))
28 #define PG_TXPWR_LSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_LSB_DIFF_S4BIT(_pg_v))
29 #define IS_PG_TXPWR_BASE_INVALID(_base) ((_base) > 63)
30 #define IS_PG_TXPWR_DIFF_INVALID(_diff) ((_diff) > 7 || (_diff) < -8)
31 #define PG_TXPWR_INVALID_BASE 255
32 #define PG_TXPWR_INVALID_DIFF 8
33
34 #if !IS_PG_TXPWR_BASE_INVALID(PG_TXPWR_INVALID_BASE)
35 #error "PG_TXPWR_BASE definition has problem"
36 #endif
37
38 #if !IS_PG_TXPWR_DIFF_INVALID(PG_TXPWR_INVALID_DIFF)
39 #error "PG_TXPWR_DIFF definition has problem"
40 #endif
41
42 #define PG_TXPWR_SRC_PG_DATA    0
43 #define PG_TXPWR_SRC_IC_DEF             1
44 #define PG_TXPWR_SRC_DEF                2
45 #define PG_TXPWR_SRC_NUM                3
46
47 const char *const _pg_txpwr_src_str[] = {
48         "PG_DATA",
49         "IC_DEF",
50         "DEF",
51         "UNKNOWN"
52 };
53
54 #define pg_txpwr_src_str(src) (((src) >= PG_TXPWR_SRC_NUM) ? _pg_txpwr_src_str[PG_TXPWR_SRC_NUM] : _pg_txpwr_src_str[(src)])
55
56 #ifndef DBG_PG_TXPWR_READ
57 #define DBG_PG_TXPWR_READ 0
58 #endif
59
60 void dump_pg_txpwr_info_2g(void *sel, TxPowerInfo24G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
61 {
62         int path, group, tx_idx;
63
64         RTW_PRINT_SEL(sel, "2.4G\n");
65         RTW_PRINT_SEL(sel, "CCK-1T base:\n");
66         RTW_PRINT_SEL(sel, "%4s ", "");
67         for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
68                 _RTW_PRINT_SEL(sel, "G%02d ", group);
69         _RTW_PRINT_SEL(sel, "\n");
70         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
71                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
72                 for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
73                         _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexCCK_Base[path][group]);
74                 _RTW_PRINT_SEL(sel, "\n");
75         }
76         RTW_PRINT_SEL(sel, "\n");
77
78         RTW_PRINT_SEL(sel, "CCK diff:\n");
79         RTW_PRINT_SEL(sel, "%4s ", "");
80         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
81                 _RTW_PRINT_SEL(sel, "%dT ", path + 1);
82         _RTW_PRINT_SEL(sel, "\n");
83         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
84                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
85                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
86                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->CCK_Diff[path][tx_idx]);
87                 _RTW_PRINT_SEL(sel, "\n");
88         }
89         RTW_PRINT_SEL(sel, "\n");
90
91         RTW_PRINT_SEL(sel, "BW40-1S base:\n");
92         RTW_PRINT_SEL(sel, "%4s ", "");
93         for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
94                 _RTW_PRINT_SEL(sel, "G%02d ", group);
95         _RTW_PRINT_SEL(sel, "\n");
96         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
97                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
98                 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
99                         _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
100                 _RTW_PRINT_SEL(sel, "\n");
101         }
102         RTW_PRINT_SEL(sel, "\n");
103
104         RTW_PRINT_SEL(sel, "OFDM diff:\n");
105         RTW_PRINT_SEL(sel, "%4s ", "");
106         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
107                 _RTW_PRINT_SEL(sel, "%dT ", path + 1);
108         _RTW_PRINT_SEL(sel, "\n");
109         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
110                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
111                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
112                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
113                 _RTW_PRINT_SEL(sel, "\n");
114         }
115         RTW_PRINT_SEL(sel, "\n");
116
117         RTW_PRINT_SEL(sel, "BW20 diff:\n");
118         RTW_PRINT_SEL(sel, "%4s ", "");
119         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
120                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
121         _RTW_PRINT_SEL(sel, "\n");
122         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
123                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
124                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
125                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
126                 _RTW_PRINT_SEL(sel, "\n");
127         }
128         RTW_PRINT_SEL(sel, "\n");
129
130         RTW_PRINT_SEL(sel, "BW40 diff:\n");
131         RTW_PRINT_SEL(sel, "%4s ", "");
132         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
133                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
134         _RTW_PRINT_SEL(sel, "\n");
135         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
136                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
137                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
138                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
139                 _RTW_PRINT_SEL(sel, "\n");
140         }
141         RTW_PRINT_SEL(sel, "\n");
142 }
143
144 void dump_pg_txpwr_info_5g(void *sel, TxPowerInfo5G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
145 {
146         int path, group, tx_idx;
147
148         RTW_PRINT_SEL(sel, "5G\n");
149         RTW_PRINT_SEL(sel, "BW40-1S base:\n");
150         RTW_PRINT_SEL(sel, "%4s ", "");
151         for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
152                 _RTW_PRINT_SEL(sel, "G%02d ", group);
153         _RTW_PRINT_SEL(sel, "\n");
154         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
155                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
156                 for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
157                         _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
158                 _RTW_PRINT_SEL(sel, "\n");
159         }
160         RTW_PRINT_SEL(sel, "\n");
161
162         RTW_PRINT_SEL(sel, "OFDM diff:\n");
163         RTW_PRINT_SEL(sel, "%4s ", "");
164         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
165                 _RTW_PRINT_SEL(sel, "%dT ", path + 1);
166         _RTW_PRINT_SEL(sel, "\n");
167         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
168                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
169                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
170                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
171                 _RTW_PRINT_SEL(sel, "\n");
172         }
173         RTW_PRINT_SEL(sel, "\n");
174
175         RTW_PRINT_SEL(sel, "BW20 diff:\n");
176         RTW_PRINT_SEL(sel, "%4s ", "");
177         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
178                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
179         _RTW_PRINT_SEL(sel, "\n");
180         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
181                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
182                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
183                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
184                 _RTW_PRINT_SEL(sel, "\n");
185         }
186         RTW_PRINT_SEL(sel, "\n");
187
188         RTW_PRINT_SEL(sel, "BW40 diff:\n");
189         RTW_PRINT_SEL(sel, "%4s ", "");
190         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
191                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
192         _RTW_PRINT_SEL(sel, "\n");
193         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
194                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
195                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
196                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
197                 _RTW_PRINT_SEL(sel, "\n");
198         }
199         RTW_PRINT_SEL(sel, "\n");
200
201         RTW_PRINT_SEL(sel, "BW80 diff:\n");
202         RTW_PRINT_SEL(sel, "%4s ", "");
203         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
204                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
205         _RTW_PRINT_SEL(sel, "\n");
206         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
207                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
208                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
209                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW80_Diff[path][tx_idx]);
210                 _RTW_PRINT_SEL(sel, "\n");
211         }
212         RTW_PRINT_SEL(sel, "\n");
213
214         RTW_PRINT_SEL(sel, "BW160 diff:\n");
215         RTW_PRINT_SEL(sel, "%4s ", "");
216         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
217                 _RTW_PRINT_SEL(sel, "%dS ", path + 1);
218         _RTW_PRINT_SEL(sel, "\n");
219         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
220                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
221                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
222                         _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW160_Diff[path][tx_idx]);
223                 _RTW_PRINT_SEL(sel, "\n");
224         }
225         RTW_PRINT_SEL(sel, "\n");
226 }
227
228 const struct map_t pg_txpwr_def_info =
229         MAP_ENT(0xB8, 1, 0xFF
230                 , MAPSEG_ARRAY_ENT(0x10, 168,
231                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE,
232                         0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
233                         0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
234                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
235                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
236                         0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24,
237                         0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
238                         0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
239                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
240                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE,
241                         0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE)
242         );
243
244 #ifdef CONFIG_RTL8188E
245 static const struct map_t rtl8188e_pg_txpwr_def_info =
246         MAP_ENT(0xB8, 1, 0xFF
247                 , MAPSEG_ARRAY_ENT(0x10, 12,
248                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24)
249         );
250 #endif
251
252 #ifdef CONFIG_RTL8188F
253 static const struct map_t rtl8188f_pg_txpwr_def_info =
254         MAP_ENT(0xB8, 1, 0xFF
255                 , MAPSEG_ARRAY_ENT(0x10, 12,
256                         0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24)
257         );
258 #endif
259
260 #ifdef CONFIG_RTL8723B
261 static const struct map_t rtl8723b_pg_txpwr_def_info =
262         MAP_ENT(0xB8, 2, 0xFF
263                 , MAPSEG_ARRAY_ENT(0x10, 12,
264                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0xE0)
265                 , MAPSEG_ARRAY_ENT(0x3A, 12,
266                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0xE0)
267         );
268 #endif
269
270 #ifdef CONFIG_RTL8703B
271 static const struct map_t rtl8703b_pg_txpwr_def_info =
272         MAP_ENT(0xB8, 1, 0xFF
273                 , MAPSEG_ARRAY_ENT(0x10, 12,
274                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
275         );
276 #endif
277
278 #ifdef CONFIG_RTL8723D
279 static const struct map_t rtl8723d_pg_txpwr_def_info =
280         MAP_ENT(0xB8, 2, 0xFF
281                 , MAPSEG_ARRAY_ENT(0x10, 12,
282                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
283                 , MAPSEG_ARRAY_ENT(0x3A, 12,
284                         0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x02)
285         );
286 #endif
287
288 #ifdef CONFIG_RTL8192E
289 static const struct map_t rtl8192e_pg_txpwr_def_info =
290         MAP_ENT(0xB8, 2, 0xFF
291                 , MAPSEG_ARRAY_ENT(0x10, 14,
292                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
293                 , MAPSEG_ARRAY_ENT(0x3A, 14,
294                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE)
295         );
296 #endif
297
298 #ifdef CONFIG_RTL8821A
299 static const struct map_t rtl8821a_pg_txpwr_def_info =
300         MAP_ENT(0xB8, 1, 0xFF
301                 , MAPSEG_ARRAY_ENT(0x10, 39,
302                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xFF, 0xFF, 0xFF, 0xFF,
303                         0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
304                         0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00)
305         );
306 #endif
307
308 #ifdef CONFIG_RTL8821C
309 static const struct map_t rtl8821c_pg_txpwr_def_info =
310         MAP_ENT(0xB8, 1, 0xFF
311                 , MAPSEG_ARRAY_ENT(0x10, 54,
312                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 
313                         0xFF, 0xFF, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 
314                         0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xFF, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
315                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02)
316         );
317 #endif
318
319 #ifdef CONFIG_RTL8812A
320 static const struct map_t rtl8812a_pg_txpwr_def_info =
321         MAP_ENT(0xB8, 1, 0xFF
322                 , MAPSEG_ARRAY_ENT(0x10, 82,
323                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF,
324                         0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
325                         0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF, 0x00, 0xEE, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
326                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A,
327                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF,
328                         0x00, 0xEE)
329         );
330 #endif
331
332 #ifdef CONFIG_RTL8822B
333 static const struct map_t rtl8822b_pg_txpwr_def_info =
334         MAP_ENT(0xB8, 1, 0xFF
335                 , MAPSEG_ARRAY_ENT(0x10, 82,
336                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF,
337                         0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
338                         0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF, 0xEC, 0xEC, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
339                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A,
340                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF,
341                         0xEC, 0xEC)
342         );
343 #endif
344
345 #ifdef CONFIG_RTL8814A
346 static const struct map_t rtl8814a_pg_txpwr_def_info =
347         MAP_ENT(0xB8, 1, 0xFF
348                 , MAPSEG_ARRAY_ENT(0x10, 168,
349                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE,
350                         0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
351                         0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
352                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
353                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
354                         0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02,
355                         0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
356                         0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
357                         0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
358                         0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE,
359                         0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE)
360         );
361 #endif
362
363 const struct map_t *hal_pg_txpwr_def_info(_adapter *adapter)
364 {
365         u8 interface_type = 0;
366         const struct map_t *map = NULL;
367
368         interface_type = rtw_get_intf_type(adapter);
369
370         switch (rtw_get_chip_type(adapter)) {
371 #ifdef CONFIG_RTL8723B
372         case RTL8723B:
373                 map = &rtl8723b_pg_txpwr_def_info;
374                 break;
375 #endif
376 #ifdef CONFIG_RTL8703B
377         case RTL8703B:
378                 map = &rtl8703b_pg_txpwr_def_info;
379                 break;
380 #endif
381 #ifdef CONFIG_RTL8723D
382         case RTL8723D:
383                 map = &rtl8723d_pg_txpwr_def_info;
384                 break;
385 #endif
386 #ifdef CONFIG_RTL8188E
387         case RTL8188E:
388                 map = &rtl8188e_pg_txpwr_def_info;
389                 break;
390 #endif
391 #ifdef CONFIG_RTL8188F
392         case RTL8188F:
393                 map = &rtl8188f_pg_txpwr_def_info;
394                 break;
395 #endif
396 #ifdef CONFIG_RTL8812A
397         case RTL8812:
398                 map = &rtl8812a_pg_txpwr_def_info;
399                 break;
400 #endif
401 #ifdef CONFIG_RTL8821A
402         case RTL8821:
403                 map = &rtl8821a_pg_txpwr_def_info;
404                 break;
405 #endif
406 #ifdef CONFIG_RTL8192E
407         case RTL8192E:
408                 map = &rtl8192e_pg_txpwr_def_info;
409                 break;
410 #endif
411 #ifdef CONFIG_RTL8814A
412         case RTL8814A:
413                 map = &rtl8814a_pg_txpwr_def_info;
414                 break;
415 #endif
416 #ifdef CONFIG_RTL8822B
417         case RTL8822B:
418                 map = &rtl8822b_pg_txpwr_def_info;
419                 break;
420 #endif
421 #ifdef CONFIG_RTL8821C
422         case RTL8821C:
423                 map = &rtl8821c_pg_txpwr_def_info;
424                 break;
425 #endif
426         }
427
428         if (map == NULL) {
429                 RTW_ERR("%s: unknown chip_type:%u\n"
430                         , __func__, rtw_get_chip_type(adapter));
431                 rtw_warn_on(1);
432         }
433
434         return map;
435 }
436
437 static u8 hal_chk_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
438 {
439         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
440         u8 path, group, tx_idx;
441
442         if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G))
443                 return _SUCCESS;
444
445         for (path = 0; path < MAX_RF_PATH; path++) {
446                 if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
447                         continue;
448                 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
449                         if (IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexCCK_Base[path][group])
450                                 || IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group]))
451                                 return _FAIL;
452                 }
453                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
454                         if (!HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx))
455                                 continue;
456                         if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
457                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
458                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
459                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx]))
460                                 return _FAIL;
461                 }
462         }
463
464         return _SUCCESS;
465 }
466
467 static u8 hal_chk_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
468 {
469 #ifdef CONFIG_IEEE80211_BAND_5GHZ
470         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
471         u8 path, group, tx_idx;
472
473         if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
474                 return _SUCCESS;
475
476         for (path = 0; path < MAX_RF_PATH; path++) {
477                 if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
478                         continue;
479                 for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
480                         if (IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group]))
481                                 return _FAIL;
482                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
483                         if (!HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx))
484                                 continue;
485                         if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
486                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
487                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
488                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
489                                 || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx]))
490                                 return _FAIL;
491                 }
492         }
493 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
494         return _SUCCESS;
495 }
496
497 static inline void hal_init_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
498 {
499         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
500         u8 path, group, tx_idx;
501
502         if (pwr_info == NULL)
503                 return;
504
505         _rtw_memset(pwr_info, 0, sizeof(TxPowerInfo24G));
506
507         /* init with invalid value */
508         for (path = 0; path < MAX_RF_PATH; path++) {
509                 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
510                         pwr_info->IndexCCK_Base[path][group] = PG_TXPWR_INVALID_BASE;
511                         pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
512                 }
513                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
514                         pwr_info->CCK_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
515                         pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
516                         pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
517                         pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
518                 }
519         }
520
521         /* init for dummy base and diff */
522         for (path = 0; path < MAX_RF_PATH; path++) {
523                 if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
524                         break;
525                 /* 2.4G BW40 base has 1 less group than CCK base*/
526                 pwr_info->IndexBW40_Base[path][MAX_CHNL_GROUP_24G - 1] = 0;
527
528                 /* dummy diff */
529                 pwr_info->CCK_Diff[path][0] = 0; /* 2.4G CCK-1TX */
530                 pwr_info->BW40_Diff[path][0] = 0; /* 2.4G BW40-1S */
531         }
532 }
533
534 static inline void hal_init_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
535 {
536 #ifdef CONFIG_IEEE80211_BAND_5GHZ
537         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
538         u8 path, group, tx_idx;
539
540         if (pwr_info == NULL)
541                 return;
542
543         _rtw_memset(pwr_info, 0, sizeof(TxPowerInfo5G));
544
545         /* init with invalid value */
546         for (path = 0; path < MAX_RF_PATH; path++) {
547                 for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
548                         pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
549                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
550                         pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
551                         pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
552                         pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
553                         pwr_info->BW80_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
554                         pwr_info->BW160_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
555                 }
556         }
557
558         for (path = 0; path < MAX_RF_PATH; path++) {
559                 if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
560                         break;
561                 /* dummy diff */
562                 pwr_info->BW40_Diff[path][0] = 0; /* 5G BW40-1S */
563         }
564 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
565 }
566
567 #if DBG_PG_TXPWR_READ
568 #define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) 1
569 #else
570 #define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) (_txpwr_src > PG_TXPWR_SRC_PG_DATA)
571 #endif
572
573 u16 hal_load_pg_txpwr_info_path_2g(
574         _adapter *adapter,
575         TxPowerInfo24G  *pwr_info,
576         u32 path,
577         u8 txpwr_src,
578         const struct map_t *txpwr_map,
579         u16 pg_offset)
580 {
581 #define PG_TXPWR_1PATH_BYTE_NUM_2G 18
582
583         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
584         u16 offset = pg_offset;
585         u8 group, tx_idx;
586         u8 val;
587         u8 tmp_base;
588         s8 tmp_diff;
589
590         if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G)) {
591                 offset += PG_TXPWR_1PATH_BYTE_NUM_2G;
592                 goto exit;
593         }
594
595         if (DBG_PG_TXPWR_READ)
596                 RTW_INFO("%s [%c] offset:0x%03x\n", __func__, rf_path_char(path), offset);
597
598         for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
599                 if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
600                         tmp_base = map_read8(txpwr_map, offset);
601                         if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
602                                 && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexCCK_Base[path][group])
603                         ) {
604                                 pwr_info->IndexCCK_Base[path][group] = tmp_base;
605                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
606                                         RTW_INFO("[%c] 2G G%02d CCK-1T base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
607                         }
608                 }
609                 offset++;
610         }
611
612         for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
613                 if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
614                         tmp_base = map_read8(txpwr_map, offset);
615                         if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
616                                 && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group])
617                         ) {
618                                 pwr_info->IndexBW40_Base[path][group] = tmp_base;
619                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
620                                         RTW_INFO("[%c] 2G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
621                         }
622                 }
623                 offset++;
624         }
625
626         for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
627                 if (tx_idx == 0) {
628                         if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
629                                 val = map_read8(txpwr_map, offset);
630                                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
631                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
632                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
633                                 ) {
634                                         pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
635                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
636                                                 RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
637                                 }
638                                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
639                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
640                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
641                                 ) {
642                                         pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
643                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
644                                                 RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
645                                 }
646                         }
647                         offset++;
648                 } else {
649                         if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
650                                 val = map_read8(txpwr_map, offset);
651                                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
652                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
653                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
654                                 ) {
655                                         pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
656                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
657                                                 RTW_INFO("[%c] 2G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
658
659                                 }
660                                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
661                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
662                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
663                                 ) {
664                                         pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
665                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
666                                                 RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
667                                 }
668                         }
669                         offset++;
670
671                         if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
672                                 val = map_read8(txpwr_map, offset);
673                                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
674                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
675                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
676                                 ) {
677                                         pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
678                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
679                                                 RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
680                                 }
681                                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
682                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
683                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
684                                 ) {
685                                         pwr_info->CCK_Diff[path][tx_idx] =      tmp_diff;
686                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
687                                                 RTW_INFO("[%c] 2G CCK-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
688                                 }
689                         }
690                         offset++;
691                 }
692         }
693
694         if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_2G) {
695                 RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_2G);
696                 rtw_warn_on(1);
697         }
698
699 exit:   
700         return offset;
701 }
702
703 u16 hal_load_pg_txpwr_info_path_5g(
704         _adapter *adapter,
705         TxPowerInfo5G   *pwr_info,
706         u32 path,
707         u8 txpwr_src,
708         const struct map_t *txpwr_map,
709         u16 pg_offset)
710 {
711 #define PG_TXPWR_1PATH_BYTE_NUM_5G 24
712
713         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
714         u16 offset = pg_offset;
715         u8 group, tx_idx;
716         u8 val;
717         u8 tmp_base;
718         s8 tmp_diff;
719
720 #ifdef CONFIG_IEEE80211_BAND_5GHZ
721         if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
722 #endif
723         {
724                 offset += PG_TXPWR_1PATH_BYTE_NUM_5G;
725                 goto exit;
726         }
727         
728 #ifdef CONFIG_IEEE80211_BAND_5GHZ
729         if (DBG_PG_TXPWR_READ)
730                 RTW_INFO("%s[%c] eaddr:0x%03x\n", __func__, rf_path_char(path), offset);
731
732         for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
733                 if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path)) {
734                         tmp_base = map_read8(txpwr_map, offset);
735                         if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
736                                 && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group])
737                         ) {
738                                 pwr_info->IndexBW40_Base[path][group] = tmp_base;
739                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
740                                         RTW_INFO("[%c] 5G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
741                         }
742                 }
743                 offset++;
744         }
745
746         for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
747                 if (tx_idx == 0) {
748                         if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
749                                 val = map_read8(txpwr_map, offset);
750                                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
751                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
752                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
753                                 ) {
754                                         pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
755                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
756                                                 RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
757                                 }
758                                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
759                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
760                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
761                                 ) {
762                                         pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
763                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
764                                                 RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
765                                 }
766                         }
767                         offset++;
768                 } else {
769                         if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
770                                 val = map_read8(txpwr_map, offset);
771                                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
772                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
773                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
774                                 ) {
775                                         pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
776                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
777                                                 RTW_INFO("[%c] 5G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
778                                 }
779                                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
780                                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
781                                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
782                                 ) {
783                                         pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
784                                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
785                                                 RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
786                                 }
787                         }
788                         offset++;
789                 }
790         }       
791
792         /* OFDM diff 2T ~ 3T */
793         if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, 1)) {
794                 val = map_read8(txpwr_map, offset);
795                 tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
796                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
797                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][1])
798                 ) {
799                         pwr_info->OFDM_Diff[path][1] = tmp_diff;
800                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
801                                 RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 2, tmp_diff, pg_txpwr_src_str(txpwr_src));
802                 }
803                 if (HAL_SPEC_CHK_TX_CNT(hal_spec, 2)) {
804                         tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
805                         if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
806                                 && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][2])
807                         ) {
808                                 pwr_info->OFDM_Diff[path][2] = tmp_diff;
809                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
810                                         RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 3, tmp_diff, pg_txpwr_src_str(txpwr_src));
811                         }
812                 }
813         }
814         offset++;
815
816         /* OFDM diff 4T */
817         if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, 3)) {
818                 val = map_read8(txpwr_map, offset);
819                 tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
820                 if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
821                         && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][3])
822                 ) {
823                         pwr_info->OFDM_Diff[path][3] = tmp_diff;
824                         if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
825                                 RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 4, tmp_diff, pg_txpwr_src_str(txpwr_src));
826                 }
827         }
828         offset++;
829
830         for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
831                 if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
832                         val = map_read8(txpwr_map, offset);
833                         tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
834                         if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
835                                 && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
836                         ) {
837                                 pwr_info->BW80_Diff[path][tx_idx] = tmp_diff;
838                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
839                                         RTW_INFO("[%c] 5G BW80-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
840                         }
841                         tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
842                         if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
843                                 && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx])
844                         ) {
845                                 pwr_info->BW160_Diff[path][tx_idx] = tmp_diff;
846                                 if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
847                                         RTW_INFO("[%c] 5G BW160-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
848                         }
849                 }
850                 offset++;
851         }
852
853         if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_5G) {
854                 RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_5G);
855                 rtw_warn_on(1);
856         }
857
858 #endif /* #ifdef CONFIG_IEEE80211_BAND_5GHZ */
859
860 exit:
861         return offset;
862 }
863
864 void hal_load_pg_txpwr_info(
865         _adapter *adapter,
866         TxPowerInfo24G *pwr_info_2g,
867         TxPowerInfo5G *pwr_info_5g,
868         u8 *pg_data,
869         BOOLEAN AutoLoadFail
870 )
871 {
872         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
873         u8 path;
874         u16 pg_offset;
875         u8 txpwr_src = PG_TXPWR_SRC_PG_DATA;
876         struct map_t pg_data_map = MAP_ENT(184, 1, 0xFF, MAPSEG_PTR_ENT(0x00, 184, pg_data));
877         const struct map_t *txpwr_map = NULL;
878
879         /* init with invalid value and some dummy base and diff */
880         hal_init_pg_txpwr_info_2g(adapter, pwr_info_2g);
881         hal_init_pg_txpwr_info_5g(adapter, pwr_info_5g);
882
883 select_src:
884         pg_offset = 0x10;
885
886         switch (txpwr_src) {
887         case PG_TXPWR_SRC_PG_DATA:
888                 txpwr_map = &pg_data_map;
889                 break;
890         case PG_TXPWR_SRC_IC_DEF:
891                 txpwr_map = hal_pg_txpwr_def_info(adapter);
892                 break;
893         case PG_TXPWR_SRC_DEF:
894         default:
895                 txpwr_map = &pg_txpwr_def_info;
896                 break;
897         };
898
899         if (txpwr_map == NULL)
900                 goto end_parse;
901
902         for (path = 0; path < MAX_RF_PATH ; path++) {
903                 if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
904                         break;
905                 pg_offset = hal_load_pg_txpwr_info_path_2g(adapter, pwr_info_2g, path, txpwr_src, txpwr_map, pg_offset);
906                 pg_offset = hal_load_pg_txpwr_info_path_5g(adapter, pwr_info_5g, path, txpwr_src, txpwr_map, pg_offset);
907         }
908
909         if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) == _SUCCESS
910                 && hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) == _SUCCESS)
911                 goto exit;
912
913 end_parse:
914         txpwr_src++;
915         if (txpwr_src < PG_TXPWR_SRC_NUM)
916                 goto select_src;
917
918         if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) != _SUCCESS
919                 || hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) != _SUCCESS)
920                 rtw_warn_on(1);
921
922 exit:
923         if (DBG_PG_TXPWR_READ) {
924                 if (pwr_info_2g)
925                         dump_pg_txpwr_info_2g(RTW_DBGDUMP, pwr_info_2g, 4, 4);
926                 if (pwr_info_5g)
927                         dump_pg_txpwr_info_5g(RTW_DBGDUMP, pwr_info_5g, 4, 4);
928         }
929
930         return;
931 }
932
933 void hal_load_txpwr_info(
934         _adapter *adapter,
935         TxPowerInfo24G *pwr_info_2g,
936         TxPowerInfo5G *pwr_info_5g,
937         u8 *pg_data
938 )
939 {
940         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
941         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
942         u8 max_tx_cnt = hal_spec->max_tx_cnt;
943         u8 rfpath, ch_idx, group, tx_idx;
944
945         /* load from pg data (or default value) */
946         hal_load_pg_txpwr_info(adapter, pwr_info_2g, pwr_info_5g, pg_data, _FALSE);
947
948         /* transform to hal_data */
949         for (rfpath = 0; rfpath < MAX_RF_PATH; rfpath++) {
950
951                 if (!pwr_info_2g || !HAL_SPEC_CHK_RF_PATH_2G(hal_spec, rfpath))
952                         goto bypass_2g;
953
954                 /* 2.4G base */
955                 for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++) {
956                         u8 cck_group;
957
958                         if (rtw_get_ch_group(ch_idx + 1, &group, &cck_group) != BAND_ON_2_4G)
959                                 continue;
960
961                         hal_data->Index24G_CCK_Base[rfpath][ch_idx] = pwr_info_2g->IndexCCK_Base[rfpath][cck_group];
962                         hal_data->Index24G_BW40_Base[rfpath][ch_idx] = pwr_info_2g->IndexBW40_Base[rfpath][group];
963                 }
964
965                 /* 2.4G diff */
966                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
967                         if (tx_idx >= max_tx_cnt)
968                                 break;
969
970                         hal_data->CCK_24G_Diff[rfpath][tx_idx] = pwr_info_2g->CCK_Diff[rfpath][tx_idx];
971                         hal_data->OFDM_24G_Diff[rfpath][tx_idx] = pwr_info_2g->OFDM_Diff[rfpath][tx_idx];
972                         hal_data->BW20_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW20_Diff[rfpath][tx_idx];
973                         hal_data->BW40_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW40_Diff[rfpath][tx_idx];
974                 }
975 bypass_2g:
976                 ;
977
978 #ifdef CONFIG_IEEE80211_BAND_5GHZ
979                 if (!pwr_info_5g || !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, rfpath))
980                         goto bypass_5g;
981
982                 /* 5G base */
983                 for (ch_idx = 0; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
984                         if (rtw_get_ch_group(center_ch_5g_all[ch_idx], &group, NULL) != BAND_ON_5G)
985                                 continue;
986                         hal_data->Index5G_BW40_Base[rfpath][ch_idx] = pwr_info_5g->IndexBW40_Base[rfpath][group];
987                 }
988
989                 for (ch_idx = 0 ; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++) {
990                         u8 upper, lower;
991
992                         if (rtw_get_ch_group(center_ch_5g_80m[ch_idx], &group, NULL) != BAND_ON_5G)
993                                 continue;
994
995                         upper = pwr_info_5g->IndexBW40_Base[rfpath][group];
996                         lower = pwr_info_5g->IndexBW40_Base[rfpath][group + 1];
997                         hal_data->Index5G_BW80_Base[rfpath][ch_idx] = (upper + lower) / 2;
998                 }
999
1000                 /* 5G diff */
1001                 for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
1002                         if (tx_idx >= max_tx_cnt)
1003                                 break;
1004
1005                         hal_data->OFDM_5G_Diff[rfpath][tx_idx] = pwr_info_5g->OFDM_Diff[rfpath][tx_idx];
1006                         hal_data->BW20_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW20_Diff[rfpath][tx_idx];
1007                         hal_data->BW40_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW40_Diff[rfpath][tx_idx];
1008                         hal_data->BW80_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW80_Diff[rfpath][tx_idx];
1009                 }
1010 bypass_5g:
1011                 ;
1012 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
1013         }
1014 }
1015
1016 void dump_hal_txpwr_info_2g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
1017 {
1018         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1019         int path, ch_idx, tx_idx;
1020
1021         RTW_PRINT_SEL(sel, "2.4G\n");
1022         RTW_PRINT_SEL(sel, "CCK-1T base:\n");
1023         RTW_PRINT_SEL(sel, "%4s ", "");
1024         for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1025                 _RTW_PRINT_SEL(sel, "%2d ", center_ch_2g[ch_idx]);
1026         _RTW_PRINT_SEL(sel, "\n");
1027         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1028                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1029                 for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1030                         _RTW_PRINT_SEL(sel, "%2u ", hal_data->Index24G_CCK_Base[path][ch_idx]);
1031                 _RTW_PRINT_SEL(sel, "\n");
1032         }
1033         RTW_PRINT_SEL(sel, "\n");
1034
1035         RTW_PRINT_SEL(sel, "CCK diff:\n");
1036         RTW_PRINT_SEL(sel, "%4s ", "");
1037         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1038                 _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1039         _RTW_PRINT_SEL(sel, "\n");
1040         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1041                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1042                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1043                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->CCK_24G_Diff[path][tx_idx]);
1044                 _RTW_PRINT_SEL(sel, "\n");
1045         }
1046         RTW_PRINT_SEL(sel, "\n");
1047
1048         RTW_PRINT_SEL(sel, "BW40-1S base:\n");
1049         RTW_PRINT_SEL(sel, "%4s ", "");
1050         for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1051                 _RTW_PRINT_SEL(sel, "%2d ", center_ch_2g[ch_idx]);
1052         _RTW_PRINT_SEL(sel, "\n");
1053         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1054                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1055                 for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
1056                         _RTW_PRINT_SEL(sel, "%2u ", hal_data->Index24G_BW40_Base[path][ch_idx]);
1057                 _RTW_PRINT_SEL(sel, "\n");
1058         }
1059         RTW_PRINT_SEL(sel, "\n");
1060
1061         RTW_PRINT_SEL(sel, "OFDM diff:\n");
1062         RTW_PRINT_SEL(sel, "%4s ", "");
1063         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1064                 _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1065         _RTW_PRINT_SEL(sel, "\n");
1066         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1067                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1068                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1069                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_24G_Diff[path][tx_idx]);
1070                 _RTW_PRINT_SEL(sel, "\n");
1071         }
1072         RTW_PRINT_SEL(sel, "\n");
1073
1074         RTW_PRINT_SEL(sel, "BW20 diff:\n");
1075         RTW_PRINT_SEL(sel, "%4s ", "");
1076         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1077                 _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1078         _RTW_PRINT_SEL(sel, "\n");
1079         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1080                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1081                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1082                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_24G_Diff[path][tx_idx]);
1083                 _RTW_PRINT_SEL(sel, "\n");
1084         }
1085         RTW_PRINT_SEL(sel, "\n");
1086
1087         RTW_PRINT_SEL(sel, "BW40 diff:\n");
1088         RTW_PRINT_SEL(sel, "%4s ", "");
1089         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1090                 _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1091         _RTW_PRINT_SEL(sel, "\n");
1092         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1093                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1094                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1095                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_24G_Diff[path][tx_idx]);
1096                 _RTW_PRINT_SEL(sel, "\n");
1097         }
1098         RTW_PRINT_SEL(sel, "\n");
1099 }
1100
1101 void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
1102 {
1103 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1104         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1105         int path, ch_idx, tx_idx;
1106         u8 dump_section = 0;
1107         u8 ch_idx_s = 0;
1108
1109         RTW_PRINT_SEL(sel, "5G\n");
1110         RTW_PRINT_SEL(sel, "BW40-1S base:\n");
1111         do {
1112                 #define DUMP_5G_BW40_BASE_SECTION_NUM 3
1113                 u8 end[DUMP_5G_BW40_BASE_SECTION_NUM] = {64, 144, 177};
1114
1115                 RTW_PRINT_SEL(sel, "%4s ", "");
1116                 for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
1117                         _RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_all[ch_idx]);
1118                         if (end[dump_section] == center_ch_5g_all[ch_idx])
1119                                 break;
1120                 }
1121                 _RTW_PRINT_SEL(sel, "\n");
1122                 for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1123                         RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1124                         for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
1125                                 _RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW40_Base[path][ch_idx]);
1126                                 if (end[dump_section] == center_ch_5g_all[ch_idx])
1127                                         break;
1128                         }
1129                         _RTW_PRINT_SEL(sel, "\n");
1130                 }
1131                 RTW_PRINT_SEL(sel, "\n");
1132
1133                 ch_idx_s = ch_idx + 1;
1134                 dump_section++;
1135                 if (dump_section >= DUMP_5G_BW40_BASE_SECTION_NUM)
1136                         break;
1137         } while (1);
1138
1139         RTW_PRINT_SEL(sel, "BW80-1S base:\n");
1140         RTW_PRINT_SEL(sel, "%4s ", "");
1141         for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
1142                 _RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_80m[ch_idx]);
1143         _RTW_PRINT_SEL(sel, "\n");
1144         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1145                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1146                 for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
1147                         _RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW80_Base[path][ch_idx]);
1148                 _RTW_PRINT_SEL(sel, "\n");
1149         }
1150         RTW_PRINT_SEL(sel, "\n");
1151
1152         RTW_PRINT_SEL(sel, "OFDM diff:\n");
1153         RTW_PRINT_SEL(sel, "%4s ", "");
1154         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1155                 _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
1156         _RTW_PRINT_SEL(sel, "\n");
1157         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1158                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1159                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1160                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_5G_Diff[path][tx_idx]);
1161                 _RTW_PRINT_SEL(sel, "\n");
1162         }
1163         RTW_PRINT_SEL(sel, "\n");
1164
1165         RTW_PRINT_SEL(sel, "BW20 diff:\n");
1166         RTW_PRINT_SEL(sel, "%4s ", "");
1167         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1168                 _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1169         _RTW_PRINT_SEL(sel, "\n");
1170         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1171                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1172                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1173                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_5G_Diff[path][tx_idx]);
1174                 _RTW_PRINT_SEL(sel, "\n");
1175         }
1176         RTW_PRINT_SEL(sel, "\n");
1177
1178         RTW_PRINT_SEL(sel, "BW40 diff:\n");
1179         RTW_PRINT_SEL(sel, "%4s ", "");
1180         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1181                 _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1182         _RTW_PRINT_SEL(sel, "\n");
1183         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1184                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1185                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1186                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_5G_Diff[path][tx_idx]);
1187                 _RTW_PRINT_SEL(sel, "\n");
1188         }
1189         RTW_PRINT_SEL(sel, "\n");
1190
1191         RTW_PRINT_SEL(sel, "BW80 diff:\n");
1192         RTW_PRINT_SEL(sel, "%4s ", "");
1193         for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1194                 _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
1195         _RTW_PRINT_SEL(sel, "\n");
1196         for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
1197                 RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
1198                 for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
1199                         _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW80_5G_Diff[path][tx_idx]);
1200                 _RTW_PRINT_SEL(sel, "\n");
1201         }
1202         RTW_PRINT_SEL(sel, "\n");
1203 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
1204 }
1205
1206 /*
1207 * rtw_regsty_get_target_tx_power -
1208 *
1209 * Return dBm or -1 for undefined
1210 */
1211 s8 rtw_regsty_get_target_tx_power(
1212         IN      PADAPTER                Adapter,
1213         IN      u8                              Band,
1214         IN      u8                              RfPath,
1215         IN      RATE_SECTION    RateSection
1216 )
1217 {
1218         struct registry_priv *regsty = adapter_to_regsty(Adapter);
1219         s8 value = 0;
1220
1221         if (RfPath > RF_PATH_D) {
1222                 RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1223                 return -1;
1224         }
1225
1226         if (Band != BAND_ON_2_4G
1227                 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1228                 && Band != BAND_ON_5G
1229                 #endif
1230         ) {
1231                 RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1232                 return -1;
1233         }
1234
1235         if (RateSection >= RATE_SECTION_NUM
1236                 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1237                 || (Band == BAND_ON_5G && RateSection == CCK)
1238                 #endif
1239         ) {
1240                 RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d\n", __func__
1241                         , RateSection, Band, RfPath);
1242                 return -1;
1243         }
1244
1245         if (Band == BAND_ON_2_4G)
1246                 value = regsty->target_tx_pwr_2g[RfPath][RateSection];
1247 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1248         else /* BAND_ON_5G */
1249                 value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1];
1250 #endif
1251
1252         return value;
1253 }
1254
1255 bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter)
1256 {
1257         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1258         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1259         int path, tx_num, band, rs;
1260         s8 target;
1261
1262         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1263                 if (!hal_is_band_support(adapter, band))
1264                         continue;
1265
1266                 for (path = 0; path < RF_PATH_MAX; path++) {
1267                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1268                                 break;
1269
1270                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
1271                                 tx_num = rate_section_to_tx_num(rs);
1272                                 if (tx_num >= hal_spec->tx_nss_num)
1273                                         continue;
1274
1275                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
1276                                         continue;
1277
1278                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
1279                                         continue;
1280
1281                                 target = rtw_regsty_get_target_tx_power(adapter, band, path, rs);
1282                                 if (target == -1) {
1283                                         RTW_PRINT("%s return _FALSE for band:%d, path:%d, rs:%d, t:%d\n", __func__, band, path, rs, target);
1284                                         return _FALSE;
1285                                 }
1286                         }
1287                 }
1288         }
1289
1290         return _TRUE;
1291 }
1292
1293 /*
1294 * PHY_GetTxPowerByRateBase -
1295 *
1296 * Return 2 times of dBm
1297 */
1298 u8
1299 PHY_GetTxPowerByRateBase(
1300         IN      PADAPTER                Adapter,
1301         IN      u8                              Band,
1302         IN      u8                              RfPath,
1303         IN      u8                              TxNum,
1304         IN      RATE_SECTION    RateSection
1305 )
1306 {
1307         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
1308         u8 value = 0;
1309
1310         if (RfPath > RF_PATH_D) {
1311                 RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1312                 return 0;
1313         }
1314
1315         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1316                 RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1317                 return 0;
1318         }
1319
1320         if (RateSection >= RATE_SECTION_NUM
1321                 || (Band == BAND_ON_5G && RateSection == CCK)
1322         ) {
1323                 RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d, TxNum:%d\n", __func__
1324                         , RateSection, Band, RfPath, TxNum);
1325                 return 0;
1326         }
1327
1328         if (Band == BAND_ON_2_4G)
1329                 value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection];
1330         else /* BAND_ON_5G */
1331                 value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1];
1332
1333         return value;
1334 }
1335
1336 VOID
1337 phy_SetTxPowerByRateBase(
1338         IN      PADAPTER                Adapter,
1339         IN      u8                              Band,
1340         IN      u8                              RfPath,
1341         IN      RATE_SECTION    RateSection,
1342         IN      u8                              TxNum,
1343         IN      u8                              Value
1344 )
1345 {
1346         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
1347
1348         if (RfPath > RF_PATH_D) {
1349                 RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
1350                 return;
1351         }
1352
1353         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1354                 RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
1355                 return;
1356         }
1357
1358         if (RateSection >= RATE_SECTION_NUM
1359                 || (Band == BAND_ON_5G && RateSection == CCK)
1360         ) {
1361                 RTW_PRINT("%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
1362                         , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
1363                 return;
1364         }
1365
1366         if (Band == BAND_ON_2_4G)
1367                 pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection] = Value;
1368         else /* BAND_ON_5G */
1369                 pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1] = Value;
1370 }
1371
1372 static inline BOOLEAN phy_is_txpwr_by_rate_undefined_of_band_path(_adapter *adapter, u8 band, u8 path)
1373 {
1374         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1375         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1376         u8 tx_num = 0, rate_idx = 0;
1377
1378         for (tx_num = 0; tx_num < TX_PWR_BY_RATE_NUM_RF; tx_num++) {
1379                 if (tx_num >= hal_spec->max_tx_cnt || tx_num >= hal_spec->tx_nss_num)
1380                         goto exit;
1381                 for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++) {
1382                         if (hal_data->TxPwrByRateOffset[band][path][tx_num][rate_idx] != 0)
1383                                 goto exit;
1384                 }
1385         }
1386
1387 exit:
1388         return (tx_num >= hal_spec->max_tx_cnt || tx_num >= hal_spec->tx_nss_num) ? _TRUE : _FALSE;
1389 }
1390
1391 static inline void phy_txpwr_by_rate_duplicate_band_path(_adapter *adapter, u8 band, u8 s_path, u8 t_path)
1392 {
1393         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1394         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1395         u8 tx_num = 0, rate_idx = 0;
1396
1397         for (tx_num = 0; tx_num < TX_PWR_BY_RATE_NUM_RF; tx_num++)
1398                 for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++)
1399                         hal_data->TxPwrByRateOffset[band][t_path][tx_num][rate_idx] = hal_data->TxPwrByRateOffset[band][s_path][tx_num][rate_idx];
1400 }
1401
1402 static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter)
1403 {
1404         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1405         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1406         u8 band, path;
1407         s8 src_path;
1408
1409         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++)
1410                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++)
1411                         hal_data->txpwr_by_rate_undefined_band_path[band][path] = 0;
1412
1413         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1414                 if (!hal_is_band_support(adapter, band))
1415                         continue;
1416
1417                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1418                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1419                                 continue;
1420
1421                         if (phy_is_txpwr_by_rate_undefined_of_band_path(adapter, band, path))
1422                                 hal_data->txpwr_by_rate_undefined_band_path[band][path] = 1;
1423                 }
1424         }
1425
1426         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1427                 if (!hal_is_band_support(adapter, band))
1428                         continue;
1429
1430                 src_path = -1;
1431                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1432                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1433                                 continue;
1434
1435                         /* find src */
1436                         if (src_path == -1 && hal_data->txpwr_by_rate_undefined_band_path[band][path] == 0)
1437                                 src_path = path;
1438                 }
1439
1440                 if (src_path == -1) {
1441                         RTW_ERR("%s all power by rate undefined\n", __func__);
1442                         continue;
1443                 }
1444
1445                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1446                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1447                                 continue;
1448
1449                         /* duplicate src to undefined one */
1450                         if (hal_data->txpwr_by_rate_undefined_band_path[band][path] == 1) {
1451                                 RTW_INFO("%s duplicate %s [%c] to [%c]\n", __func__
1452                                         , band_str(band), rf_path_char(src_path), rf_path_char(path));
1453                                 phy_txpwr_by_rate_duplicate_band_path(adapter, band, src_path, path);
1454                         }
1455                 }
1456         }
1457 }
1458
1459 VOID
1460 phy_StoreTxPowerByRateBase(
1461         IN      PADAPTER        pAdapter
1462 )
1463 {
1464         struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
1465         struct registry_priv *regsty = adapter_to_regsty(pAdapter);
1466
1467         u8 rate_sec_base[RATE_SECTION_NUM] = {
1468                 MGN_11M,
1469                 MGN_54M,
1470                 MGN_MCS7,
1471                 MGN_MCS15,
1472                 MGN_MCS23,
1473                 MGN_MCS31,
1474                 MGN_VHT1SS_MCS7,
1475                 MGN_VHT2SS_MCS7,
1476                 MGN_VHT3SS_MCS7,
1477                 MGN_VHT4SS_MCS7,
1478         };
1479
1480         u8 band, path, rs, tx_num, base, index;
1481
1482         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
1483                 if (!hal_is_band_support(pAdapter, band))
1484                         continue;
1485
1486                 for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
1487                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
1488                                 break;
1489
1490                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
1491                                 tx_num = rate_section_to_tx_num(rs);
1492                                 if (tx_num >= hal_spec->tx_nss_num)
1493                                         continue;
1494
1495                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
1496                                         continue;
1497
1498                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter))
1499                                         continue;
1500
1501                                 if (regsty->target_tx_pwr_valid == _TRUE)
1502                                         base = 2 * rtw_regsty_get_target_tx_power(pAdapter, band, path, rs);
1503                                 else
1504                                         base = _PHY_GetTxPowerByRate(pAdapter, band, path, tx_num, rate_sec_base[rs]);
1505                                 phy_SetTxPowerByRateBase(pAdapter, band, path, rs, tx_num, base);
1506                         }
1507                 }
1508         }
1509 }
1510
1511 VOID
1512 PHY_GetRateValuesOfTxPowerByRate(
1513         IN      PADAPTER pAdapter,
1514         IN      u32 RegAddr,
1515         IN      u32 BitMask,
1516         IN      u32 Value,
1517         OUT     u8 *Rate,
1518         OUT     s8 *PwrByRateVal,
1519         OUT     u8 *RateNum
1520 )
1521 {
1522         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1523         struct PHY_DM_STRUCT            *pDM_Odm = &pHalData->odmpriv;
1524         u8                              index = 0, i = 0;
1525
1526         switch (RegAddr) {
1527         case rTxAGC_A_Rate18_06:
1528         case rTxAGC_B_Rate18_06:
1529                 Rate[0] = MGN_6M;
1530                 Rate[1] = MGN_9M;
1531                 Rate[2] = MGN_12M;
1532                 Rate[3] = MGN_18M;
1533                 for (i = 0; i < 4; ++i) {
1534                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1535                                                ((Value >> (i * 8)) & 0xF));
1536                 }
1537                 *RateNum = 4;
1538                 break;
1539
1540         case rTxAGC_A_Rate54_24:
1541         case rTxAGC_B_Rate54_24:
1542                 Rate[0] = MGN_24M;
1543                 Rate[1] = MGN_36M;
1544                 Rate[2] = MGN_48M;
1545                 Rate[3] = MGN_54M;
1546                 for (i = 0; i < 4; ++i) {
1547                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1548                                                ((Value >> (i * 8)) & 0xF));
1549                 }
1550                 *RateNum = 4;
1551                 break;
1552
1553         case rTxAGC_A_CCK1_Mcs32:
1554                 Rate[0] = MGN_1M;
1555                 PwrByRateVal[0] = (s8)((((Value >> (8 + 4)) & 0xF)) * 10 +
1556                                        ((Value >> 8) & 0xF));
1557                 *RateNum = 1;
1558                 break;
1559
1560         case rTxAGC_B_CCK11_A_CCK2_11:
1561                 if (BitMask == 0xffffff00) {
1562                         Rate[0] = MGN_2M;
1563                         Rate[1] = MGN_5_5M;
1564                         Rate[2] = MGN_11M;
1565                         for (i = 1; i < 4; ++i) {
1566                                 PwrByRateVal[i - 1] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1567                                                    ((Value >> (i * 8)) & 0xF));
1568                         }
1569                         *RateNum = 3;
1570                 } else if (BitMask == 0x000000ff) {
1571                         Rate[0] = MGN_11M;
1572                         PwrByRateVal[0] = (s8)((((Value >> 4) & 0xF)) * 10 +
1573                                                (Value & 0xF));
1574                         *RateNum = 1;
1575                 }
1576                 break;
1577
1578         case rTxAGC_A_Mcs03_Mcs00:
1579         case rTxAGC_B_Mcs03_Mcs00:
1580                 Rate[0] = MGN_MCS0;
1581                 Rate[1] = MGN_MCS1;
1582                 Rate[2] = MGN_MCS2;
1583                 Rate[3] = MGN_MCS3;
1584                 for (i = 0; i < 4; ++i) {
1585                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1586                                                ((Value >> (i * 8)) & 0xF));
1587                 }
1588                 *RateNum = 4;
1589                 break;
1590
1591         case rTxAGC_A_Mcs07_Mcs04:
1592         case rTxAGC_B_Mcs07_Mcs04:
1593                 Rate[0] = MGN_MCS4;
1594                 Rate[1] = MGN_MCS5;
1595                 Rate[2] = MGN_MCS6;
1596                 Rate[3] = MGN_MCS7;
1597                 for (i = 0; i < 4; ++i) {
1598                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1599                                                ((Value >> (i * 8)) & 0xF));
1600                 }
1601                 *RateNum = 4;
1602                 break;
1603
1604         case rTxAGC_A_Mcs11_Mcs08:
1605         case rTxAGC_B_Mcs11_Mcs08:
1606                 Rate[0] = MGN_MCS8;
1607                 Rate[1] = MGN_MCS9;
1608                 Rate[2] = MGN_MCS10;
1609                 Rate[3] = MGN_MCS11;
1610                 for (i = 0; i < 4; ++i) {
1611                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1612                                                ((Value >> (i * 8)) & 0xF));
1613                 }
1614                 *RateNum = 4;
1615                 break;
1616
1617         case rTxAGC_A_Mcs15_Mcs12:
1618         case rTxAGC_B_Mcs15_Mcs12:
1619                 Rate[0] = MGN_MCS12;
1620                 Rate[1] = MGN_MCS13;
1621                 Rate[2] = MGN_MCS14;
1622                 Rate[3] = MGN_MCS15;
1623                 for (i = 0; i < 4; ++i) {
1624                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1625                                                ((Value >> (i * 8)) & 0xF));
1626                 }
1627                 *RateNum = 4;
1628
1629                 break;
1630
1631         case rTxAGC_B_CCK1_55_Mcs32:
1632                 Rate[0] = MGN_1M;
1633                 Rate[1] = MGN_2M;
1634                 Rate[2] = MGN_5_5M;
1635                 for (i = 1; i < 4; ++i) {
1636                         PwrByRateVal[i - 1] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1637                                                    ((Value >> (i * 8)) & 0xF));
1638                 }
1639                 *RateNum = 3;
1640                 break;
1641
1642         case 0xC20:
1643         case 0xE20:
1644         case 0x1820:
1645         case 0x1a20:
1646                 Rate[0] = MGN_1M;
1647                 Rate[1] = MGN_2M;
1648                 Rate[2] = MGN_5_5M;
1649                 Rate[3] = MGN_11M;
1650                 for (i = 0; i < 4; ++i) {
1651                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1652                                                ((Value >> (i * 8)) & 0xF));
1653                 }
1654                 *RateNum = 4;
1655                 break;
1656
1657         case 0xC24:
1658         case 0xE24:
1659         case 0x1824:
1660         case 0x1a24:
1661                 Rate[0] = MGN_6M;
1662                 Rate[1] = MGN_9M;
1663                 Rate[2] = MGN_12M;
1664                 Rate[3] = MGN_18M;
1665                 for (i = 0; i < 4; ++i) {
1666                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1667                                                ((Value >> (i * 8)) & 0xF));
1668                 }
1669                 *RateNum = 4;
1670                 break;
1671
1672         case 0xC28:
1673         case 0xE28:
1674         case 0x1828:
1675         case 0x1a28:
1676                 Rate[0] = MGN_24M;
1677                 Rate[1] = MGN_36M;
1678                 Rate[2] = MGN_48M;
1679                 Rate[3] = MGN_54M;
1680                 for (i = 0; i < 4; ++i) {
1681                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1682                                                ((Value >> (i * 8)) & 0xF));
1683                 }
1684                 *RateNum = 4;
1685                 break;
1686
1687         case 0xC2C:
1688         case 0xE2C:
1689         case 0x182C:
1690         case 0x1a2C:
1691                 Rate[0] = MGN_MCS0;
1692                 Rate[1] = MGN_MCS1;
1693                 Rate[2] = MGN_MCS2;
1694                 Rate[3] = MGN_MCS3;
1695                 for (i = 0; i < 4; ++i) {
1696                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1697                                                ((Value >> (i * 8)) & 0xF));
1698                 }
1699                 *RateNum = 4;
1700                 break;
1701
1702         case 0xC30:
1703         case 0xE30:
1704         case 0x1830:
1705         case 0x1a30:
1706                 Rate[0] = MGN_MCS4;
1707                 Rate[1] = MGN_MCS5;
1708                 Rate[2] = MGN_MCS6;
1709                 Rate[3] = MGN_MCS7;
1710                 for (i = 0; i < 4; ++i) {
1711                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1712                                                ((Value >> (i * 8)) & 0xF));
1713                 }
1714                 *RateNum = 4;
1715                 break;
1716
1717         case 0xC34:
1718         case 0xE34:
1719         case 0x1834:
1720         case 0x1a34:
1721                 Rate[0] = MGN_MCS8;
1722                 Rate[1] = MGN_MCS9;
1723                 Rate[2] = MGN_MCS10;
1724                 Rate[3] = MGN_MCS11;
1725                 for (i = 0; i < 4; ++i) {
1726                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1727                                                ((Value >> (i * 8)) & 0xF));
1728                 }
1729                 *RateNum = 4;
1730                 break;
1731
1732         case 0xC38:
1733         case 0xE38:
1734         case 0x1838:
1735         case 0x1a38:
1736                 Rate[0] = MGN_MCS12;
1737                 Rate[1] = MGN_MCS13;
1738                 Rate[2] = MGN_MCS14;
1739                 Rate[3] = MGN_MCS15;
1740                 for (i = 0; i < 4; ++i) {
1741                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1742                                                ((Value >> (i * 8)) & 0xF));
1743                 }
1744                 *RateNum = 4;
1745                 break;
1746
1747         case 0xC3C:
1748         case 0xE3C:
1749         case 0x183C:
1750         case 0x1a3C:
1751                 Rate[0] = MGN_VHT1SS_MCS0;
1752                 Rate[1] = MGN_VHT1SS_MCS1;
1753                 Rate[2] = MGN_VHT1SS_MCS2;
1754                 Rate[3] = MGN_VHT1SS_MCS3;
1755                 for (i = 0; i < 4; ++i) {
1756                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1757                                                ((Value >> (i * 8)) & 0xF));
1758                 }
1759                 *RateNum = 4;
1760                 break;
1761
1762         case 0xC40:
1763         case 0xE40:
1764         case 0x1840:
1765         case 0x1a40:
1766                 Rate[0] = MGN_VHT1SS_MCS4;
1767                 Rate[1] = MGN_VHT1SS_MCS5;
1768                 Rate[2] = MGN_VHT1SS_MCS6;
1769                 Rate[3] = MGN_VHT1SS_MCS7;
1770                 for (i = 0; i < 4; ++i) {
1771                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1772                                                ((Value >> (i * 8)) & 0xF));
1773                 }
1774                 *RateNum = 4;
1775                 break;
1776
1777         case 0xC44:
1778         case 0xE44:
1779         case 0x1844:
1780         case 0x1a44:
1781                 Rate[0] = MGN_VHT1SS_MCS8;
1782                 Rate[1] = MGN_VHT1SS_MCS9;
1783                 Rate[2] = MGN_VHT2SS_MCS0;
1784                 Rate[3] = MGN_VHT2SS_MCS1;
1785                 for (i = 0; i < 4; ++i) {
1786                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1787                                                ((Value >> (i * 8)) & 0xF));
1788                 }
1789                 *RateNum = 4;
1790                 break;
1791
1792         case 0xC48:
1793         case 0xE48:
1794         case 0x1848:
1795         case 0x1a48:
1796                 Rate[0] = MGN_VHT2SS_MCS2;
1797                 Rate[1] = MGN_VHT2SS_MCS3;
1798                 Rate[2] = MGN_VHT2SS_MCS4;
1799                 Rate[3] = MGN_VHT2SS_MCS5;
1800                 for (i = 0; i < 4; ++i) {
1801                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1802                                                ((Value >> (i * 8)) & 0xF));
1803                 }
1804                 *RateNum = 4;
1805                 break;
1806
1807         case 0xC4C:
1808         case 0xE4C:
1809         case 0x184C:
1810         case 0x1a4C:
1811                 Rate[0] = MGN_VHT2SS_MCS6;
1812                 Rate[1] = MGN_VHT2SS_MCS7;
1813                 Rate[2] = MGN_VHT2SS_MCS8;
1814                 Rate[3] = MGN_VHT2SS_MCS9;
1815                 for (i = 0; i < 4; ++i) {
1816                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1817                                                ((Value >> (i * 8)) & 0xF));
1818                 }
1819                 *RateNum = 4;
1820                 break;
1821
1822         case 0xCD8:
1823         case 0xED8:
1824         case 0x18D8:
1825         case 0x1aD8:
1826                 Rate[0] = MGN_MCS16;
1827                 Rate[1] = MGN_MCS17;
1828                 Rate[2] = MGN_MCS18;
1829                 Rate[3] = MGN_MCS19;
1830                 for (i = 0; i < 4; ++i) {
1831                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1832                                                ((Value >> (i * 8)) & 0xF));
1833                 }
1834                 *RateNum = 4;
1835                 break;
1836
1837         case 0xCDC:
1838         case 0xEDC:
1839         case 0x18DC:
1840         case 0x1aDC:
1841                 Rate[0] = MGN_MCS20;
1842                 Rate[1] = MGN_MCS21;
1843                 Rate[2] = MGN_MCS22;
1844                 Rate[3] = MGN_MCS23;
1845                 for (i = 0; i < 4; ++i) {
1846                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1847                                                ((Value >> (i * 8)) & 0xF));
1848                 }
1849                 *RateNum = 4;
1850                 break;
1851
1852         case 0xCE0:
1853         case 0xEE0:
1854         case 0x18E0:
1855         case 0x1aE0:
1856                 Rate[0] = MGN_VHT3SS_MCS0;
1857                 Rate[1] = MGN_VHT3SS_MCS1;
1858                 Rate[2] = MGN_VHT3SS_MCS2;
1859                 Rate[3] = MGN_VHT3SS_MCS3;
1860                 for (i = 0; i < 4; ++i) {
1861                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1862                                                ((Value >> (i * 8)) & 0xF));
1863                 }
1864                 *RateNum = 4;
1865                 break;
1866
1867         case 0xCE4:
1868         case 0xEE4:
1869         case 0x18E4:
1870         case 0x1aE4:
1871                 Rate[0] = MGN_VHT3SS_MCS4;
1872                 Rate[1] = MGN_VHT3SS_MCS5;
1873                 Rate[2] = MGN_VHT3SS_MCS6;
1874                 Rate[3] = MGN_VHT3SS_MCS7;
1875                 for (i = 0; i < 4; ++i) {
1876                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1877                                                ((Value >> (i * 8)) & 0xF));
1878                 }
1879                 *RateNum = 4;
1880                 break;
1881
1882         case 0xCE8:
1883         case 0xEE8:
1884         case 0x18E8:
1885         case 0x1aE8:
1886                 Rate[0] = MGN_VHT3SS_MCS8;
1887                 Rate[1] = MGN_VHT3SS_MCS9;
1888                 for (i = 0; i < 2; ++i) {
1889                         PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
1890                                                ((Value >> (i * 8)) & 0xF));
1891                 }
1892                 *RateNum = 2;
1893                 break;
1894
1895         default:
1896                 RTW_PRINT("Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
1897                 break;
1898         };
1899 }
1900
1901 void
1902 PHY_StoreTxPowerByRateNew(
1903         IN      PADAPTER        pAdapter,
1904         IN      u32                     Band,
1905         IN      u32                     RfPath,
1906         IN      u32                     TxNum,
1907         IN      u32                     RegAddr,
1908         IN      u32                     BitMask,
1909         IN      u32                     Data
1910 )
1911 {
1912         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
1913         u8      i = 0, rates[4] = {0}, rateNum = 0;
1914         s8      PwrByRateVal[4] = {0};
1915
1916         PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum);
1917
1918         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
1919                 RTW_PRINT("Invalid Band %d\n", Band);
1920                 return;
1921         }
1922
1923         if (RfPath > ODM_RF_PATH_D) {
1924                 RTW_PRINT("Invalid RfPath %d\n", RfPath);
1925                 return;
1926         }
1927
1928         if (TxNum > ODM_RF_PATH_D) {
1929                 RTW_PRINT("Invalid TxNum %d\n", TxNum);
1930                 return;
1931         }
1932
1933         for (i = 0; i < rateNum; ++i) {
1934                 u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]);
1935
1936                 if (IS_1T_RATE(rates[i]))
1937                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_1TX][rate_idx] = PwrByRateVal[i];
1938                 else if (IS_2T_RATE(rates[i]))
1939                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_2TX][rate_idx] = PwrByRateVal[i];
1940                 else if (IS_3T_RATE(rates[i]))
1941                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_3TX][rate_idx] = PwrByRateVal[i];
1942                 else if (IS_4T_RATE(rates[i]))
1943                         pHalData->TxPwrByRateOffset[Band][RfPath][RF_4TX][rate_idx] = PwrByRateVal[i];
1944                 else
1945                         rtw_warn_on(1);
1946         }
1947 }
1948
1949 VOID
1950 PHY_InitTxPowerByRate(
1951         IN      PADAPTER        pAdapter
1952 )
1953 {
1954         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1955         u8      band = 0, rfPath = 0, TxNum = 0, rate = 0, i = 0, j = 0;
1956
1957         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
1958                 for (rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath)
1959                         for (TxNum = 0; TxNum < TX_PWR_BY_RATE_NUM_RF; ++TxNum)
1960                                 for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate)
1961                                         pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0;
1962 }
1963
1964 VOID
1965 phy_store_tx_power_by_rate(
1966         IN      PADAPTER        pAdapter,
1967         IN      u32                     Band,
1968         IN      u32                     RfPath,
1969         IN      u32                     TxNum,
1970         IN      u32                     RegAddr,
1971         IN      u32                     BitMask,
1972         IN      u32                     Data
1973 )
1974 {
1975         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1976         struct PHY_DM_STRUCT            *pDM_Odm = &pHalData->odmpriv;
1977
1978         if (pDM_Odm->phy_reg_pg_version > 0)
1979                 PHY_StoreTxPowerByRateNew(pAdapter, Band, RfPath, TxNum, RegAddr, BitMask, Data);
1980         else
1981                 RTW_INFO("Invalid PHY_REG_PG.txt version %d\n",  pDM_Odm->phy_reg_pg_version);
1982
1983 }
1984
1985 VOID
1986 phy_ConvertTxPowerByRateInDbmToRelativeValues(
1987         IN      PADAPTER        pAdapter
1988 )
1989 {
1990         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1991         u8                      base = 0, i = 0, value = 0,
1992                                 band = 0, path = 0, txNum = 0, index = 0,
1993                                 startIndex = 0, endIndex = 0;
1994         u8      cckRates[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M},
1995                 ofdmRates[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M},
1996                 mcs0_7Rates[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7},
1997                 mcs8_15Rates[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15},
1998                 mcs16_23Rates[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23},
1999                 vht1ssRates[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
2000                         MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9},
2001                 vht2ssRates[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
2002                         MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9},
2003                 vht3ssRates[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
2004                         MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
2005
2006         /* RTW_INFO("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); */
2007
2008         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
2009                 for (path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path) {
2010                         for (txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum) {
2011                                 /* CCK */
2012                                 if (band == BAND_ON_2_4G) {
2013                                         base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, CCK);
2014                                         for (i = 0; i < sizeof(cckRates); ++i) {
2015                                                 value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, cckRates[i]);
2016                                                 PHY_SetTxPowerByRate(pAdapter, band, path, txNum, cckRates[i], value - base);
2017                                         }
2018                                 }
2019
2020                                 /* OFDM */
2021                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, OFDM);
2022                                 for (i = 0; i < sizeof(ofdmRates); ++i) {
2023                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, ofdmRates[i]);
2024                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, ofdmRates[i], value - base);
2025                                 }
2026
2027                                 /* HT MCS0~7 */
2028                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_1SS);
2029                                 for (i = 0; i < sizeof(mcs0_7Rates); ++i) {
2030                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs0_7Rates[i]);
2031                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs0_7Rates[i], value - base);
2032                                 }
2033
2034                                 /* HT MCS8~15 */
2035                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_2SS);
2036                                 for (i = 0; i < sizeof(mcs8_15Rates); ++i) {
2037                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs8_15Rates[i]);
2038                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs8_15Rates[i], value - base);
2039                                 }
2040
2041                                 /* HT MCS16~23 */
2042                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_3SS);
2043                                 for (i = 0; i < sizeof(mcs16_23Rates); ++i) {
2044                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs16_23Rates[i]);
2045                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs16_23Rates[i], value - base);
2046                                 }
2047
2048                                 /* VHT 1SS */
2049                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_1SS);
2050                                 for (i = 0; i < sizeof(vht1ssRates); ++i) {
2051                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht1ssRates[i]);
2052                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht1ssRates[i], value - base);
2053                                 }
2054
2055                                 /* VHT 2SS */
2056                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_2SS);
2057                                 for (i = 0; i < sizeof(vht2ssRates); ++i) {
2058                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht2ssRates[i]);
2059                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht2ssRates[i], value - base);
2060                                 }
2061
2062                                 /* VHT 3SS */
2063                                 base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_3SS);
2064                                 for (i = 0; i < sizeof(vht3ssRates); ++i) {
2065                                         value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht3ssRates[i]);
2066                                         PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht3ssRates[i], value - base);
2067                                 }
2068                         }
2069                 }
2070         }
2071
2072         /* RTW_INFO("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); */
2073 }
2074
2075 /*
2076   * This function must be called if the value in the PHY_REG_PG.txt(or header)
2077   * is exact dBm values
2078   */
2079 VOID
2080 PHY_TxPowerByRateConfiguration(
2081         IN  PADAPTER                    pAdapter
2082 )
2083 {
2084         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
2085
2086         phy_txpwr_by_rate_chk_for_path_dup(pAdapter);
2087         phy_StoreTxPowerByRateBase(pAdapter);
2088         phy_ConvertTxPowerByRateInDbmToRelativeValues(pAdapter);
2089 }
2090
2091 VOID
2092 phy_set_tx_power_index_by_rate_section(
2093         IN      PADAPTER                pAdapter,
2094         IN      u8                              RFPath,
2095         IN      u8                              Channel,
2096         IN      u8                              RateSection
2097 )
2098 {
2099         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(pAdapter);
2100
2101         if (RateSection >= RATE_SECTION_NUM) {
2102                 RTW_INFO("Invalid RateSection %d in %s", RateSection, __func__);
2103                 rtw_warn_on(1);
2104                 goto exit;
2105         }
2106
2107         if (RateSection == CCK && pHalData->current_band_type != BAND_ON_2_4G)
2108                 goto exit;
2109
2110         PHY_SetTxPowerIndexByRateArray(pAdapter, RFPath, pHalData->current_channel_bw, Channel,
2111                 rates_by_sections[RateSection].rates, rates_by_sections[RateSection].rate_num);
2112
2113 exit:
2114         return;
2115 }
2116
2117 BOOLEAN
2118 phy_GetChnlIndex(
2119         IN      u8      Channel,
2120         OUT u8  *ChannelIdx
2121 )
2122 {
2123         u8  i = 0;
2124         BOOLEAN bIn24G = _TRUE;
2125
2126         if (Channel <= 14) {
2127                 bIn24G = _TRUE;
2128                 *ChannelIdx = Channel - 1;
2129         } else {
2130                 bIn24G = _FALSE;
2131
2132                 for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
2133                         if (center_ch_5g_all[i] == Channel) {
2134                                 *ChannelIdx = i;
2135                                 return bIn24G;
2136                         }
2137                 }
2138         }
2139
2140         return bIn24G;
2141 }
2142
2143 u8
2144 PHY_GetTxPowerIndexBase(
2145         IN      PADAPTER                pAdapter,
2146         IN      u8                              RFPath,
2147         IN      u8                              Rate,
2148         IN      CHANNEL_WIDTH   BandWidth,
2149         IN      u8                              Channel,
2150         OUT PBOOLEAN            bIn24G
2151 )
2152 {
2153         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(pAdapter);
2154         struct PHY_DM_STRUCT                    *pDM_Odm = &pHalData->odmpriv;
2155         u8                                      i = 0;  /* default set to 1S */
2156         u8                                      txPower = 0;
2157         u8                                      chnlIdx = (Channel - 1);
2158
2159         if (HAL_IsLegalChannel(pAdapter, Channel) == _FALSE) {
2160                 chnlIdx = 0;
2161                 RTW_INFO("Illegal channel!!\n");
2162         }
2163
2164         *bIn24G = phy_GetChnlIndex(Channel, &chnlIdx);
2165
2166         /* RTW_INFO("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx); */
2167
2168         if (*bIn24G) { /* 3 ============================== 2.4 G ============================== */
2169                 if (IS_CCK_RATE(Rate))
2170                         txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];
2171                 else if (MGN_6M <= Rate)
2172                         txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
2173                 else
2174                         RTW_INFO("PHY_GetTxPowerIndexBase: INVALID Rate(0x%02x).\n", Rate);
2175
2176                 /* RTW_INFO("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n",  */
2177                 /*              ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); */
2178
2179                 /* OFDM-1T */
2180                 if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
2181                         txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
2182                         /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]); */
2183                 }
2184                 /* BW20-1S, BW20-2S */
2185                 if (BandWidth == CHANNEL_WIDTH_20) {
2186                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2187                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
2188                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2189                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S];
2190                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2191                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S];
2192                         if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2193                                 txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S];
2194
2195                         /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2196                         /*      pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S],  */
2197                         /*      pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]); */
2198                 }
2199                 /* BW40-1S, BW40-2S */
2200                 else if (BandWidth == CHANNEL_WIDTH_40) {
2201                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2202                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
2203                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2204                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
2205                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2206                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
2207                         if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2208                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
2209
2210                         /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2211                         /*      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
2212                         /*      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
2213                 }
2214                 /* Willis suggest adopt BW 40M power index while in BW 80 mode */
2215                 else if (BandWidth == CHANNEL_WIDTH_80) {
2216                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2217                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
2218                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2219                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
2220                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2221                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
2222                         if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2223                                 txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
2224
2225                         /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4T) = (%d, %d, %d, %d) P.S. Current is in BW 80MHz\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2226                         /*      pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
2227                         /*      pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
2228                 }
2229         }
2230 #ifdef CONFIG_IEEE80211_BAND_5GHZ
2231         else { /* 3 ============================== 5 G ============================== */
2232                 if (MGN_6M <= Rate)
2233                         txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
2234                 else
2235                         RTW_INFO("===>PHY_GetTxPowerIndexBase: INVALID Rate(0x%02x).\n", Rate);
2236
2237                 /* RTW_INFO("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n",  */
2238                 /*      ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); */
2239
2240                 /* OFDM-1T */
2241                 if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
2242                         txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S];
2243                         /* RTW_INFO("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]); */
2244                 }
2245
2246                 /* BW20-1S, BW20-2S */
2247                 if (BandWidth == CHANNEL_WIDTH_20) {
2248                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2249                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S];
2250                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2251                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S];
2252                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2253                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S];
2254                         if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2255                                 txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S];
2256
2257                         /* RTW_INFO("+PowerDiff 5G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2258                         /*      pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S], */
2259                         /*      pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]); */
2260                 }
2261                 /* BW40-1S, BW40-2S */
2262                 else if (BandWidth == CHANNEL_WIDTH_40) {
2263                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2264                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S];
2265                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2266                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S];
2267                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2268                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S];
2269                         if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2270                                 txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S];
2271
2272                         /* RTW_INFO("+PowerDiff 5G(RF-%c): (BW40-1S, BW40-2S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2273                         /*      pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S], */
2274                         /*      pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]); */
2275                 }
2276                 /* BW80-1S, BW80-2S */
2277                 else if (BandWidth == CHANNEL_WIDTH_80) {
2278                         /* <20121220, Kordan> Get the index of array "Index5G_BW80_Base". */
2279                         for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i)
2280                                 if (center_ch_5g_80m[i] == Channel)
2281                                         chnlIdx = i;
2282
2283                         txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
2284
2285                         if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2286                                 txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S];
2287                         if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2288                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S];
2289                         if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2290                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S];
2291                         if ((MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
2292                                 txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S];
2293
2294                         /* RTW_INFO("+PowerDiff 5G(RF-%c): (BW80-1S, BW80-2S, BW80-3S, BW80-4S) = (%d, %d, %d, %d)\n",((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'),  */
2295                         /*      pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S], */
2296                         /*      pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]); */
2297                 }
2298         }
2299 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
2300
2301         return txPower;
2302 }
2303
2304 s8
2305 PHY_GetTxPowerTrackingOffset(
2306         PADAPTER        pAdapter,
2307         u8                      RFPath,
2308         u8                      Rate
2309 )
2310 {
2311         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(pAdapter);
2312         struct PHY_DM_STRUCT                    *pDM_Odm = &pHalData->odmpriv;
2313         s8      offset = 0;
2314
2315         if (pDM_Odm->rf_calibrate_info.txpowertrack_control  == _FALSE)
2316                 return offset;
2317
2318         if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M)) {
2319                 offset = pDM_Odm->rf_calibrate_info.remnant_cck_swing_idx;
2320                 /*RTW_INFO("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/
2321         } else {
2322                 offset = pDM_Odm->rf_calibrate_info.remnant_ofdm_swing_idx[RFPath];
2323                 /*RTW_INFO("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]);      */
2324
2325         }
2326
2327         return offset;
2328 }
2329
2330 /*The same as MRateToHwRate in hal_com.c*/
2331 u8
2332 PHY_GetRateIndexOfTxPowerByRate(
2333         IN      u8              Rate
2334 )
2335 {
2336         u8      index = 0;
2337         switch (Rate) {
2338         case MGN_1M:
2339                 index = 0;
2340                 break;
2341         case MGN_2M:
2342                 index = 1;
2343                 break;
2344         case MGN_5_5M:
2345                 index = 2;
2346                 break;
2347         case MGN_11M:
2348                 index = 3;
2349                 break;
2350         case MGN_6M:
2351                 index = 4;
2352                 break;
2353         case MGN_9M:
2354                 index = 5;
2355                 break;
2356         case MGN_12M:
2357                 index = 6;
2358                 break;
2359         case MGN_18M:
2360                 index = 7;
2361                 break;
2362         case MGN_24M:
2363                 index = 8;
2364                 break;
2365         case MGN_36M:
2366                 index = 9;
2367                 break;
2368         case MGN_48M:
2369                 index = 10;
2370                 break;
2371         case MGN_54M:
2372                 index = 11;
2373                 break;
2374         case MGN_MCS0:
2375                 index = 12;
2376                 break;
2377         case MGN_MCS1:
2378                 index = 13;
2379                 break;
2380         case MGN_MCS2:
2381                 index = 14;
2382                 break;
2383         case MGN_MCS3:
2384                 index = 15;
2385                 break;
2386         case MGN_MCS4:
2387                 index = 16;
2388                 break;
2389         case MGN_MCS5:
2390                 index = 17;
2391                 break;
2392         case MGN_MCS6:
2393                 index = 18;
2394                 break;
2395         case MGN_MCS7:
2396                 index = 19;
2397                 break;
2398         case MGN_MCS8:
2399                 index = 20;
2400                 break;
2401         case MGN_MCS9:
2402                 index = 21;
2403                 break;
2404         case MGN_MCS10:
2405                 index = 22;
2406                 break;
2407         case MGN_MCS11:
2408                 index = 23;
2409                 break;
2410         case MGN_MCS12:
2411                 index = 24;
2412                 break;
2413         case MGN_MCS13:
2414                 index = 25;
2415                 break;
2416         case MGN_MCS14:
2417                 index = 26;
2418                 break;
2419         case MGN_MCS15:
2420                 index = 27;
2421                 break;
2422         case MGN_MCS16:
2423                 index = 28;
2424                 break;
2425         case MGN_MCS17:
2426                 index = 29;
2427                 break;
2428         case MGN_MCS18:
2429                 index = 30;
2430                 break;
2431         case MGN_MCS19:
2432                 index = 31;
2433                 break;
2434         case MGN_MCS20:
2435                 index = 32;
2436                 break;
2437         case MGN_MCS21:
2438                 index = 33;
2439                 break;
2440         case MGN_MCS22:
2441                 index = 34;
2442                 break;
2443         case MGN_MCS23:
2444                 index = 35;
2445                 break;
2446         case MGN_MCS24:
2447                 index = 36;
2448                 break;
2449         case MGN_MCS25:
2450                 index = 37;
2451                 break;
2452         case MGN_MCS26:
2453                 index = 38;
2454                 break;
2455         case MGN_MCS27:
2456                 index = 39;
2457                 break;
2458         case MGN_MCS28:
2459                 index = 40;
2460                 break;
2461         case MGN_MCS29:
2462                 index = 41;
2463                 break;
2464         case MGN_MCS30:
2465                 index = 42;
2466                 break;
2467         case MGN_MCS31:
2468                 index = 43;
2469                 break;
2470         case MGN_VHT1SS_MCS0:
2471                 index = 44;
2472                 break;
2473         case MGN_VHT1SS_MCS1:
2474                 index = 45;
2475                 break;
2476         case MGN_VHT1SS_MCS2:
2477                 index = 46;
2478                 break;
2479         case MGN_VHT1SS_MCS3:
2480                 index = 47;
2481                 break;
2482         case MGN_VHT1SS_MCS4:
2483                 index = 48;
2484                 break;
2485         case MGN_VHT1SS_MCS5:
2486                 index = 49;
2487                 break;
2488         case MGN_VHT1SS_MCS6:
2489                 index = 50;
2490                 break;
2491         case MGN_VHT1SS_MCS7:
2492                 index = 51;
2493                 break;
2494         case MGN_VHT1SS_MCS8:
2495                 index = 52;
2496                 break;
2497         case MGN_VHT1SS_MCS9:
2498                 index = 53;
2499                 break;
2500         case MGN_VHT2SS_MCS0:
2501                 index = 54;
2502                 break;
2503         case MGN_VHT2SS_MCS1:
2504                 index = 55;
2505                 break;
2506         case MGN_VHT2SS_MCS2:
2507                 index = 56;
2508                 break;
2509         case MGN_VHT2SS_MCS3:
2510                 index = 57;
2511                 break;
2512         case MGN_VHT2SS_MCS4:
2513                 index = 58;
2514                 break;
2515         case MGN_VHT2SS_MCS5:
2516                 index = 59;
2517                 break;
2518         case MGN_VHT2SS_MCS6:
2519                 index = 60;
2520                 break;
2521         case MGN_VHT2SS_MCS7:
2522                 index = 61;
2523                 break;
2524         case MGN_VHT2SS_MCS8:
2525                 index = 62;
2526                 break;
2527         case MGN_VHT2SS_MCS9:
2528                 index = 63;
2529                 break;
2530         case MGN_VHT3SS_MCS0:
2531                 index = 64;
2532                 break;
2533         case MGN_VHT3SS_MCS1:
2534                 index = 65;
2535                 break;
2536         case MGN_VHT3SS_MCS2:
2537                 index = 66;
2538                 break;
2539         case MGN_VHT3SS_MCS3:
2540                 index = 67;
2541                 break;
2542         case MGN_VHT3SS_MCS4:
2543                 index = 68;
2544                 break;
2545         case MGN_VHT3SS_MCS5:
2546                 index = 69;
2547                 break;
2548         case MGN_VHT3SS_MCS6:
2549                 index = 70;
2550                 break;
2551         case MGN_VHT3SS_MCS7:
2552                 index = 71;
2553                 break;
2554         case MGN_VHT3SS_MCS8:
2555                 index = 72;
2556                 break;
2557         case MGN_VHT3SS_MCS9:
2558                 index = 73;
2559                 break;
2560         case MGN_VHT4SS_MCS0:
2561                 index = 74;
2562                 break;
2563         case MGN_VHT4SS_MCS1:
2564                 index = 75;
2565                 break;
2566         case MGN_VHT4SS_MCS2:
2567                 index = 76;
2568                 break;
2569         case MGN_VHT4SS_MCS3:
2570                 index = 77;
2571                 break;
2572         case MGN_VHT4SS_MCS4:
2573                 index = 78;
2574                 break;
2575         case MGN_VHT4SS_MCS5:
2576                 index = 79;
2577                 break;
2578         case MGN_VHT4SS_MCS6:
2579                 index = 80;
2580                 break;
2581         case MGN_VHT4SS_MCS7:
2582                 index = 81;
2583                 break;
2584         case MGN_VHT4SS_MCS8:
2585                 index = 82;
2586                 break;
2587         case MGN_VHT4SS_MCS9:
2588                 index = 83;
2589                 break;
2590         default:
2591                 RTW_INFO("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__);
2592                 break;
2593         };
2594
2595         return index;
2596 }
2597
2598 s8
2599 _PHY_GetTxPowerByRate(
2600         IN      PADAPTER        pAdapter,
2601         IN      u8                      Band,
2602         IN      u8                      RFPath,
2603         IN      u8                      TxNum,
2604         IN      u8                      Rate
2605 )
2606 {
2607         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
2608         s8 value = 0;
2609         u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
2610
2611         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2612                 RTW_INFO("Invalid band %d in %s\n", Band, __func__);
2613                 goto exit;
2614         }
2615         if (RFPath > ODM_RF_PATH_D) {
2616                 RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__);
2617                 goto exit;
2618         }
2619         if (TxNum >= RF_MAX_TX_NUM) {
2620                 RTW_INFO("Invalid TxNum %d in %s\n", TxNum, __func__);
2621                 goto exit;
2622         }
2623         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
2624                 RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__);
2625                 goto exit;
2626         }
2627
2628         value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex];
2629
2630 exit:
2631         return value;
2632 }
2633
2634
2635 s8
2636 PHY_GetTxPowerByRate(
2637         IN      PADAPTER        pAdapter,
2638         IN      u8                      Band,
2639         IN      u8                      RFPath,
2640         IN      u8                      TxNum,
2641         IN      u8                      Rate
2642 )
2643 {
2644         if (!phy_is_tx_power_by_rate_needed(pAdapter))
2645                 return 0;
2646
2647         return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, TxNum, Rate);
2648 }
2649
2650 #ifdef CONFIG_PHYDM_POWERTRACK_BY_TSSI
2651 s8
2652 PHY_GetTxPowerByRateOriginal(
2653         IN      PADAPTER        pAdapter,
2654         IN      u8                      Band,
2655         IN      u8                      RFPath,
2656         IN      u8                      TxNum,
2657         IN      u8                      Rate
2658 )
2659 {
2660         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
2661         s8      value = 0, limit = 0;
2662         u8      rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
2663
2664         if ((pAdapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) ||
2665                 pAdapter->registrypriv.RegEnableTxPowerByRate == 0)
2666                 return 0;
2667
2668         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2669                 DBG_871X("Invalid band %d in %s\n", Band, __func__);
2670                 return value;
2671         }
2672         if (RFPath > ODM_RF_PATH_D) {
2673                 DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
2674                 return value;
2675         }
2676         if (TxNum >= RF_MAX_TX_NUM) {
2677                 DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
2678                 return value;
2679         }
2680         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
2681                 DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
2682                 return value;
2683         }
2684
2685         value = pHalData->TxPwrByRate[Band][RFPath][TxNum][rateIndex];
2686
2687         return value;
2688 }
2689
2690 #endif
2691
2692
2693 VOID
2694 PHY_SetTxPowerByRate(
2695         IN      PADAPTER        pAdapter,
2696         IN      u8                      Band,
2697         IN      u8                      RFPath,
2698         IN      u8                      TxNum,
2699         IN      u8                      Rate,
2700         IN      s8                      Value
2701 )
2702 {
2703         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
2704         u8      rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
2705
2706         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2707                 RTW_INFO("Invalid band %d in %s\n", Band, __FUNCTION__);
2708                 return;
2709         }
2710         if (RFPath > ODM_RF_PATH_D) {
2711                 RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__);
2712                 return;
2713         }
2714         if (TxNum >= RF_MAX_TX_NUM) {
2715                 RTW_INFO("Invalid TxNum %d in %s\n", TxNum, __FUNCTION__);
2716                 return;
2717         }
2718         if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
2719                 RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__);
2720                 return;
2721         }
2722
2723         pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value;
2724 }
2725
2726 VOID
2727 phy_set_tx_power_level_by_path(
2728         IN      PADAPTER        Adapter,
2729         IN      u8                      channel,
2730         IN      u8                      path
2731 )
2732 {
2733         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
2734         BOOLEAN bIsIn24G = (pHalData->current_band_type == BAND_ON_2_4G);
2735
2736         /* if ( pMgntInfo->RegNByteAccess == 0 ) */
2737         {
2738                 if (bIsIn24G)
2739                         phy_set_tx_power_index_by_rate_section(Adapter, path, channel, CCK);
2740
2741                 phy_set_tx_power_index_by_rate_section(Adapter, path, channel, OFDM);
2742                 phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS0_MCS7);
2743
2744                 if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
2745                         phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
2746
2747                 if (pHalData->NumTotalRFPath >= 2) {
2748                         phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS8_MCS15);
2749
2750                         if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
2751                                 phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_2SSMCS0_2SSMCS9);
2752
2753                         if (IS_HARDWARE_TYPE_8814A(Adapter)) {
2754                                 phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS16_MCS23);
2755                                 phy_set_tx_power_index_by_rate_section(Adapter, path, channel, VHT_3SSMCS0_3SSMCS9);
2756                         }
2757                 }
2758         }
2759 }
2760
2761 #ifndef DBG_TX_POWER_IDX
2762 #define DBG_TX_POWER_IDX 0
2763 #endif
2764
2765 VOID
2766 PHY_SetTxPowerIndexByRateArray(
2767         IN      PADAPTER                        pAdapter,
2768         IN      u8                                      RFPath,
2769         IN      CHANNEL_WIDTH           BandWidth,
2770         IN      u8                                      Channel,
2771         IN      u8                                      *Rates,
2772         IN      u8                                      RateArraySize
2773 )
2774 {
2775         u32     powerIndex = 0;
2776         int     i = 0;
2777
2778         for (i = 0; i < RateArraySize; ++i) {
2779 #if DBG_TX_POWER_IDX
2780                 struct txpwr_idx_comp tic;
2781
2782                 powerIndex = rtw_hal_get_tx_power_index(pAdapter, RFPath, Rates[i], BandWidth, Channel, &tic);
2783                 RTW_INFO("TXPWR: [%c][%s]ch:%u, %s, pwr_idx:%u = %u + (%d=%d:%d) + (%d) + (%d)\n"
2784                         , rf_path_char(RFPath), ch_width_str(BandWidth), Channel, MGN_RATE_STR(Rates[i])
2785                         , powerIndex, tic.base, (tic.by_rate > tic.limit ? tic.limit : tic.by_rate), tic.by_rate, tic.limit, tic.tpt, tic.ebias);
2786 #else
2787                 powerIndex = phy_get_tx_power_index(pAdapter, RFPath, Rates[i], BandWidth, Channel);
2788 #endif
2789                 PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, Rates[i]);
2790         }
2791 }
2792
2793 s8
2794 phy_GetWorldWideLimit(
2795         s8 *LimitTable
2796 )
2797 {
2798         s8      min = LimitTable[0];
2799         u8      i = 0;
2800
2801         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2802                 if (LimitTable[i] < min)
2803                         min = LimitTable[i];
2804         }
2805
2806         return min;
2807 }
2808
2809 s8
2810 phy_GetChannelIndexOfTxPowerLimit(
2811         IN      u8                      Band,
2812         IN      u8                      Channel
2813 )
2814 {
2815         s8      channelIndex = -1;
2816         u8      i = 0;
2817
2818         if (Band == BAND_ON_2_4G)
2819                 channelIndex = Channel - 1;
2820         else if (Band == BAND_ON_5G) {
2821                 for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
2822                         if (center_ch_5g_all[i] == Channel)
2823                                 channelIndex = i;
2824                 }
2825         } else
2826                 RTW_PRINT("Invalid Band %d in %s\n", Band, __func__);
2827
2828         if (channelIndex == -1)
2829                 RTW_PRINT("Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__);
2830
2831         return channelIndex;
2832 }
2833
2834 static s8 _phy_get_txpwr_lmt(
2835         IN      PADAPTER                        Adapter,
2836         IN      u32                                     RegPwrTblSel,
2837         IN      BAND_TYPE                       Band,
2838         IN      CHANNEL_WIDTH           Bandwidth,
2839         IN      u8                                      RfPath,
2840         IN      u8                                      DataRate,
2841         IN      u8                                      Channel,
2842         BOOLEAN no_sc
2843 )
2844 {
2845         struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
2846         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(Adapter);
2847         s8 regulation = -1, bw = -1, rs = -1;
2848         u8 cch = 0;
2849         u8 bw_bmp = 0;
2850         s8 min_lmt = MAX_POWER_INDEX;
2851         s8 tmp_lmt;
2852         u8 final_bw = Bandwidth, final_cch = Channel;
2853
2854         if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) ||
2855                 Adapter->registrypriv.RegEnableTxPowerLimit == 0)
2856                 goto exit;
2857
2858         switch (RegPwrTblSel) {
2859         case 1:
2860                 regulation = TXPWR_LMT_ETSI;
2861                 break;
2862         case 2:
2863                 regulation = TXPWR_LMT_MKK;
2864                 break;
2865         case 3:
2866                 regulation = TXPWR_LMT_FCC;
2867                 break;
2868         case 4:
2869                 regulation = TXPWR_LMT_WW;
2870                 break;
2871         default:
2872                 regulation = (Band == BAND_ON_2_4G) ? hal_data->Regulation2_4G : hal_data->Regulation5G;
2873                 break;
2874         }
2875
2876         if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
2877                 RTW_ERR("%s invalid band:%u\n", __func__, Band);
2878                 rtw_warn_on(1);
2879                 goto exit;
2880         }
2881
2882         if (IS_CCK_RATE(DataRate))
2883                 rs = CCK;
2884         else if (IS_OFDM_RATE(DataRate))
2885                 rs = OFDM;
2886         else if (IS_HT1SS_RATE(DataRate))
2887                 rs = HT_1SS;
2888         else if (IS_HT2SS_RATE(DataRate))
2889                 rs = HT_2SS;
2890         else if (IS_HT3SS_RATE(DataRate))
2891                 rs = HT_3SS;
2892         else if (IS_HT4SS_RATE(DataRate))
2893                 rs = HT_4SS;
2894         else if (IS_VHT1SS_RATE(DataRate))
2895                 rs = VHT_1SS;
2896         else if (IS_VHT2SS_RATE(DataRate))
2897                 rs = VHT_2SS;
2898         else if (IS_VHT3SS_RATE(DataRate))
2899                 rs = VHT_3SS;
2900         else if (IS_VHT4SS_RATE(DataRate))
2901                 rs = VHT_4SS;
2902         else {
2903                 RTW_ERR("%s invalid rate 0x%x\n", __func__, DataRate);
2904                 rtw_warn_on(1);
2905                 goto exit;
2906         }
2907
2908         if (Band == BAND_ON_5G  && rs == CCK) {
2909                 RTW_ERR("Wrong rate No CCK(0x%x) in 5G Band\n", DataRate);
2910                 goto exit;
2911         }
2912
2913         if (no_sc == _TRUE) {
2914                 /* use the input center channel and bandwidth directly */
2915                 cch = Channel;
2916                 bw_bmp = ch_width_to_bw_cap(Bandwidth);
2917         } else {
2918                 /*
2919                 * find the possible tx bandwidth bmp for this rate, and then will get center channel for each bandwidth
2920                 * if no possible tx bandwidth bmp, select valid bandwidth up to current RF bandwidth into bmp
2921                 */
2922                 if (rs == CCK || rs == OFDM)
2923                         bw_bmp = BW_CAP_20M; /* CCK, OFDM only BW 20M */
2924                 else if (IS_HT_RATE_SECTION(rs)) {
2925                         bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, DataRate, Bandwidth);
2926                         if (bw_bmp == 0)
2927                                 bw_bmp = ch_width_to_bw_cap(Bandwidth > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : Bandwidth);
2928                 } else if (IS_VHT_RATE_SECTION(rs)) {
2929                         bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, DataRate, Bandwidth);
2930                         if (bw_bmp == 0)
2931                                 bw_bmp = ch_width_to_bw_cap(Bandwidth > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : Bandwidth);
2932                 } else
2933                         rtw_warn_on(1);
2934         }
2935
2936         if (bw_bmp == 0)
2937                 goto exit;
2938
2939         /* loop for each possible tx bandwidth to find minimum limit */
2940         for (bw = CHANNEL_WIDTH_20; bw <= Bandwidth; bw++) {
2941                 s8 ch_idx;
2942
2943                 if (!(ch_width_to_bw_cap(bw) & bw_bmp))
2944                         continue;
2945
2946                 if (no_sc == _FALSE) {
2947                         if (bw == CHANNEL_WIDTH_20)
2948                                 cch = hal_data->cch_20;
2949                         else if (bw == CHANNEL_WIDTH_40)
2950                                 cch = hal_data->cch_40;
2951                         else if (bw == CHANNEL_WIDTH_80)
2952                                 cch = hal_data->cch_80;
2953                         else {
2954                                 cch = 0;
2955                                 rtw_warn_on(1);
2956                         }
2957                 }
2958
2959                 ch_idx = phy_GetChannelIndexOfTxPowerLimit(Band, cch);
2960                 if (ch_idx == -1)
2961                         continue;
2962
2963                 if (Band == BAND_ON_2_4G) {
2964                         s8 limits[MAX_REGULATION_NUM] = {0};
2965                         u8 i = 0;
2966
2967                         for (i = 0; i < MAX_REGULATION_NUM; ++i)
2968                                 limits[i] = hal_data->TxPwrLimit_2_4G[i][bw][rs][ch_idx][RfPath];
2969
2970                         tmp_lmt = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
2971                                 hal_data->TxPwrLimit_2_4G[regulation][bw][rs][ch_idx][RfPath];
2972
2973                 } else if (Band == BAND_ON_5G) {
2974                         s8 limits[MAX_REGULATION_NUM] = {0};
2975                         u8 i = 0;
2976
2977                         for (i = 0; i < MAX_REGULATION_NUM; ++i)
2978                                 limits[i] = hal_data->TxPwrLimit_5G[i][bw][rs][ch_idx][RfPath];
2979
2980                         tmp_lmt = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
2981                                 hal_data->TxPwrLimit_5G[regulation][bw][rs][ch_idx][RfPath];
2982                 } else
2983                         continue;
2984
2985                 if (min_lmt >= tmp_lmt) {
2986                         min_lmt = tmp_lmt;
2987                         final_cch = cch;
2988                         final_bw = bw;
2989                 }
2990         }
2991
2992 exit:
2993         return min_lmt;
2994 }
2995
2996 inline s8
2997 PHY_GetTxPowerLimit(
2998         IN      PADAPTER                        Adapter,
2999         IN      u32                                     RegPwrTblSel,
3000         IN      BAND_TYPE                       Band,
3001         IN      CHANNEL_WIDTH           Bandwidth,
3002         IN      u8                                      RfPath,
3003         IN      u8                                      DataRate,
3004         IN      u8                                      Channel
3005 )
3006 {
3007         BOOLEAN no_sc = _FALSE;
3008
3009         /* MP mode channel don't use secondary channel */
3010         if (rtw_mi_mp_mode_check(Adapter) == _TRUE)
3011                 no_sc = _TRUE;
3012
3013         return _phy_get_txpwr_lmt(Adapter, RegPwrTblSel, Band, Bandwidth, RfPath, DataRate, Channel, no_sc);
3014 }
3015
3016 inline s8
3017 PHY_GetTxPowerLimit_no_sc(
3018         IN      PADAPTER                        Adapter,
3019         IN      u32                                     RegPwrTblSel,
3020         IN      BAND_TYPE                       Band,
3021         IN      CHANNEL_WIDTH           Bandwidth,
3022         IN      u8                                      RfPath,
3023         IN      u8                                      DataRate,
3024         IN      u8                                      Channel
3025 )
3026 {
3027         return _phy_get_txpwr_lmt(Adapter, RegPwrTblSel, Band, Bandwidth, RfPath, DataRate, Channel, _TRUE);
3028 }
3029
3030 #ifdef CONFIG_PHYDM_POWERTRACK_BY_TSSI
3031 s8
3032 PHY_GetTxPowerLimitOriginal(
3033         IN      PADAPTER                        Adapter,
3034         IN      u32                                     RegPwrTblSel,
3035         IN      BAND_TYPE                       Band,
3036         IN      CHANNEL_WIDTH           Bandwidth,
3037         IN      u8                                      RfPath,
3038         IN      u8                                      DataRate,
3039         IN      u8                                      Channel
3040 )
3041 {
3042         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
3043         s16                             band = -1, regulation = -1, bandwidth = -1,
3044                                         rateSection = -1, channel = -1;
3045         s8                              powerLimit = MAX_POWER_INDEX;
3046
3047         if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1) ||
3048             Adapter->registrypriv.RegEnableTxPowerLimit == 0)
3049                 return MAX_POWER_INDEX;
3050
3051         switch (Adapter->registrypriv.RegPwrTblSel) {
3052         case 1:
3053                 regulation = TXPWR_LMT_ETSI;
3054                 break;
3055
3056         case 2:
3057                 regulation = TXPWR_LMT_MKK;
3058                 break;
3059
3060         case 3:
3061                 regulation = TXPWR_LMT_FCC;
3062                 break;
3063
3064         case 4:
3065                 regulation = TXPWR_LMT_WW;
3066                 break;
3067
3068         default:
3069                 regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G
3070                              : pHalData->Regulation5G;
3071                 break;
3072         }
3073
3074         /*DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation );*/
3075
3076
3077         if (Band == BAND_ON_2_4G)
3078                 band = 0;
3079         else if (Band == BAND_ON_5G)
3080                 band = 1;
3081
3082         if (Bandwidth == CHANNEL_WIDTH_20)
3083                 bandwidth = 0;
3084         else if (Bandwidth == CHANNEL_WIDTH_40)
3085                 bandwidth = 1;
3086         else if (Bandwidth == CHANNEL_WIDTH_80)
3087                 bandwidth = 2;
3088         else if (Bandwidth == CHANNEL_WIDTH_160)
3089                 bandwidth = 3;
3090
3091         switch (DataRate) {
3092         case MGN_1M:
3093         case MGN_2M:
3094         case MGN_5_5M:
3095         case MGN_11M:
3096                 rateSection = 0;
3097                 break;
3098
3099         case MGN_6M:
3100         case MGN_9M:
3101         case MGN_12M:
3102         case MGN_18M:
3103         case MGN_24M:
3104         case MGN_36M:
3105         case MGN_48M:
3106         case MGN_54M:
3107                 rateSection = 1;
3108                 break;
3109
3110         case MGN_MCS0:
3111         case MGN_MCS1:
3112         case MGN_MCS2:
3113         case MGN_MCS3:
3114         case MGN_MCS4:
3115         case MGN_MCS5:
3116         case MGN_MCS6:
3117         case MGN_MCS7:
3118                 rateSection = 2;
3119                 break;
3120
3121         case MGN_MCS8:
3122         case MGN_MCS9:
3123         case MGN_MCS10:
3124         case MGN_MCS11:
3125         case MGN_MCS12:
3126         case MGN_MCS13:
3127         case MGN_MCS14:
3128         case MGN_MCS15:
3129                 rateSection = 3;
3130                 break;
3131
3132         case MGN_MCS16:
3133         case MGN_MCS17:
3134         case MGN_MCS18:
3135         case MGN_MCS19:
3136         case MGN_MCS20:
3137         case MGN_MCS21:
3138         case MGN_MCS22:
3139         case MGN_MCS23:
3140                 rateSection = 4;
3141                 break;
3142
3143         case MGN_MCS24:
3144         case MGN_MCS25:
3145         case MGN_MCS26:
3146         case MGN_MCS27:
3147         case MGN_MCS28:
3148         case MGN_MCS29:
3149         case MGN_MCS30:
3150         case MGN_MCS31:
3151                 rateSection = 5;
3152                 break;
3153
3154         case MGN_VHT1SS_MCS0:
3155         case MGN_VHT1SS_MCS1:
3156         case MGN_VHT1SS_MCS2:
3157         case MGN_VHT1SS_MCS3:
3158         case MGN_VHT1SS_MCS4:
3159         case MGN_VHT1SS_MCS5:
3160         case MGN_VHT1SS_MCS6:
3161         case MGN_VHT1SS_MCS7:
3162         case MGN_VHT1SS_MCS8:
3163         case MGN_VHT1SS_MCS9:
3164                 rateSection = 6;
3165                 break;
3166
3167         case MGN_VHT2SS_MCS0:
3168         case MGN_VHT2SS_MCS1:
3169         case MGN_VHT2SS_MCS2:
3170         case MGN_VHT2SS_MCS3:
3171         case MGN_VHT2SS_MCS4:
3172         case MGN_VHT2SS_MCS5:
3173         case MGN_VHT2SS_MCS6:
3174         case MGN_VHT2SS_MCS7:
3175         case MGN_VHT2SS_MCS8:
3176         case MGN_VHT2SS_MCS9:
3177                 rateSection = 7;
3178                 break;
3179
3180         case MGN_VHT3SS_MCS0:
3181         case MGN_VHT3SS_MCS1:
3182         case MGN_VHT3SS_MCS2:
3183         case MGN_VHT3SS_MCS3:
3184         case MGN_VHT3SS_MCS4:
3185         case MGN_VHT3SS_MCS5:
3186         case MGN_VHT3SS_MCS6:
3187         case MGN_VHT3SS_MCS7:
3188         case MGN_VHT3SS_MCS8:
3189         case MGN_VHT3SS_MCS9:
3190                 rateSection = 8;
3191                 break;
3192
3193         case MGN_VHT4SS_MCS0:
3194         case MGN_VHT4SS_MCS1:
3195         case MGN_VHT4SS_MCS2:
3196         case MGN_VHT4SS_MCS3:
3197         case MGN_VHT4SS_MCS4:
3198         case MGN_VHT4SS_MCS5:
3199         case MGN_VHT4SS_MCS6:
3200         case MGN_VHT4SS_MCS7:
3201         case MGN_VHT4SS_MCS8:
3202         case MGN_VHT4SS_MCS9:
3203                 rateSection = 9;
3204                 break;
3205
3206         default:
3207                 DBG_871X("Wrong rate 0x%x\n", DataRate);
3208                 break;
3209         }
3210
3211         if (Band == BAND_ON_5G  && rateSection == 0)
3212                 DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate);
3213
3214         /*workaround for wrong index combination to obtain tx power limit,*/
3215         /*OFDM only exists in BW 20M*/
3216         if (rateSection == 1)
3217                 bandwidth = 0;
3218
3219         /*workaround for wrong index combination to obtain tx power limit,*/
3220         /*CCK table will only be given in BW 20M*/
3221         if (rateSection == 0)
3222                 bandwidth = 0;
3223
3224         /*workaround for wrong indxe combination to obtain tx power limit,*/
3225         /*HT on 80M will reference to HT on 40M*/
3226         if ((rateSection == 2 || rateSection == 3) && Band == BAND_ON_5G && bandwidth == 2)
3227                 bandwidth = 1;
3228
3229         if (Band == BAND_ON_2_4G)
3230                 channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, Channel);
3231         else if (Band == BAND_ON_5G)
3232                 channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, Channel);
3233         else if (Band == BAND_ON_BOTH)
3234                 /*BAND_ON_BOTH don't care temporarily*/
3235
3236                 if (band == -1 || regulation == -1 || bandwidth == -1 ||
3237                     rateSection == -1 || channel == -1) {
3238                         /*DBG_871X("Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnlGroup %d]\n",*/
3239                         /*        band, regulation, bandwidth, RfPath, rateSection, channelGroup );*/
3240
3241                         return MAX_POWER_INDEX;
3242                 }
3243
3244         if (Band == BAND_ON_2_4G) {
3245                 s8 limits[10] = {0};
3246                 u8 i = 0;
3247
3248                 if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM)
3249                         bandwidth = MAX_2_4G_BANDWIDTH_NUM - 1;
3250
3251                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
3252                         limits[i] = pHalData->TxPwrLimit_2_4G_Original[i][bandwidth][rateSection][channel][RfPath];
3253
3254                 powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
3255                         pHalData->TxPwrLimit_2_4G_Original[regulation][bandwidth][rateSection][channel][RfPath];
3256
3257         } else if (Band == BAND_ON_5G) {
3258                 s8 limits[10] = {0};
3259                 u8 i = 0;
3260
3261                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
3262                         limits[i] = pHalData->TxPwrLimit_5G_Original[i][bandwidth][rateSection][channel][RfPath];
3263
3264                 powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
3265                         pHalData->TxPwrLimit_5G_Original[regulation][bandwidth][rateSection][channel][RfPath];
3266         } else
3267                 DBG_871X("No power limit table of the specified band\n");
3268
3269         /*combine 5G VHT & HT rate*/
3270         /*5G 20M and 40M HT and VHT can cross reference*/
3271         /*
3272         if (Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX) {
3273                 if (bandwidth == 0 || bandwidth == 1) {
3274                         if (rateSection == 2)
3275                                 powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
3276                                                                                 [bandwidth][4][channelGroup][RfPath];
3277                         else if (rateSection == 4)
3278                                 powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
3279                                                                                 [bandwidth][2][channelGroup][RfPath];
3280                         else if (rateSection == 3)
3281                                 powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
3282                                                                                 [bandwidth][5][channelGroup][RfPath];
3283                         else if (rateSection == 5)
3284                                 powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
3285                                                                                 [bandwidth][3][channelGroup][RfPath];
3286                 }
3287         }
3288         */
3289         /*DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n",*/
3290         /*              regulation, pHalData->current_band_type, Bandwidth, RfPath, DataRate, Channel, powerLimit);*/
3291         return powerLimit;
3292 }
3293 #endif
3294
3295
3296 VOID
3297 phy_CrossReferenceHTAndVHTTxPowerLimit(
3298         IN      PADAPTER                        pAdapter
3299 )
3300 {
3301         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
3302         u8 regulation, bw, channel, rs, ref_rs;
3303         int ht_ref_vht_5g_20_40 = 0;
3304         int vht_ref_ht_5g_20_40 = 0;
3305         int ht_has_ref_5g_20_40 = 0;
3306         int vht_has_ref_5g_20_40 = 0;
3307
3308         pHalData->tx_pwr_lmt_5g_20_40_ref = 0;
3309
3310         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
3311
3312                 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
3313
3314                         for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
3315
3316                                 for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
3317
3318                                         /* 5G 20M 40M VHT and HT can cross reference */
3319                                         if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) {
3320                                                 if (rs == HT_1SS)
3321                                                         ref_rs = VHT_1SS;
3322                                                 else if (rs == HT_2SS)
3323                                                         ref_rs = VHT_2SS;
3324                                                 else if (rs == HT_3SS)
3325                                                         ref_rs = VHT_3SS;
3326                                                 else if (rs == HT_4SS)
3327                                                         ref_rs = VHT_4SS;
3328                                                 else if (rs == VHT_1SS)
3329                                                         ref_rs = HT_1SS;
3330                                                 else if (rs == VHT_2SS)
3331                                                         ref_rs = HT_2SS;
3332                                                 else if (rs == VHT_3SS)
3333                                                         ref_rs = HT_3SS;
3334                                                 else if (rs == VHT_4SS)
3335                                                         ref_rs = HT_4SS;
3336                                                 else
3337                                                         continue;
3338
3339                                                 if (pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A] == MAX_POWER_INDEX)
3340                                                         continue;
3341
3342                                                 if (IS_HT_RATE_SECTION(rs))
3343                                                         ht_has_ref_5g_20_40++;
3344                                                 else if (IS_VHT_RATE_SECTION(rs))
3345                                                         vht_has_ref_5g_20_40++;
3346                                                 else
3347                                                         continue;
3348
3349                                                 if (pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] != MAX_POWER_INDEX)
3350                                                         continue;
3351
3352                                                 if (IS_HT_RATE_SECTION(rs) && IS_VHT_RATE_SECTION(ref_rs))
3353                                                         ht_ref_vht_5g_20_40++;
3354                                                 else if (IS_VHT_RATE_SECTION(rs) && IS_HT_RATE_SECTION(ref_rs))
3355                                                         vht_ref_ht_5g_20_40++;
3356
3357                                                 if (0)
3358                                                         RTW_INFO("reg:%u, bw:%u, ch:%u, %s ref %s\n"
3359                                                                 , regulation, bw, channel
3360                                                                 , rate_section_str(rs), rate_section_str(ref_rs));
3361
3362                                                 pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] =
3363                                                         pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A];
3364                                         }
3365
3366                                 }
3367                         }
3368                 }
3369         }
3370
3371         if (0) {
3372                 RTW_INFO("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40);
3373                 RTW_INFO("vht_ref_hht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40);
3374         }
3375
3376         /* 5G 20M&40M HT all come from VHT*/
3377         if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40)
3378                 pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_HT_FROM_VHT;
3379
3380         /* 5G 20M&40M VHT all come from HT*/
3381         if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40)
3382                 pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_VHT_FROM_HT;
3383 }
3384
3385 VOID
3386 PHY_ConvertTxPowerLimitToPowerIndex(
3387         IN      PADAPTER                        Adapter
3388 )
3389 {
3390         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3391         u8 base;
3392         u8 regulation, bw, channel, rateSection;
3393         s8 tempValue = 0, tempPwrLmt = 0;
3394         u8 rfPath = 0;
3395
3396         if (pHalData->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
3397                 rtw_warn_on(1);
3398                 return;
3399         }
3400
3401         phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
3402
3403         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
3404
3405                 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
3406
3407                         for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
3408
3409                                 for (rateSection = CCK; rateSection <= HT_4SS; ++rateSection) {
3410                                         tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A];
3411
3412                                         if (tempPwrLmt != MAX_POWER_INDEX) {
3413
3414                                                 for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
3415                                                         base = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, rate_section_to_tx_num(rateSection), rateSection);
3416                                                         tempValue = tempPwrLmt - base;
3417                                                         pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
3418                                                 }
3419                                         }
3420                                 }
3421                         }
3422                 }
3423         }
3424
3425         if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) {
3426
3427                 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
3428
3429                         for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
3430
3431                                 for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
3432
3433                                         for (rateSection = OFDM; rateSection <= VHT_4SS; ++rateSection) {
3434                                                 tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][RF_PATH_A];
3435
3436                                                 if (tempPwrLmt != MAX_POWER_INDEX) {
3437
3438                                                         for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
3439                                                                 base = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_5G, rfPath, rate_section_to_tx_num(rateSection), rateSection);
3440                                                                 tempValue = tempPwrLmt - base;
3441                                                                 pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][rfPath] = tempValue;
3442                                                         }
3443                                                 }
3444                                         }
3445                                 }
3446                         }
3447                 }
3448         }
3449 }
3450
3451 /*
3452 * PHY_InitTxPowerLimit - Set all hal_data.TxPwrLimit_2_4G, TxPwrLimit_5G array to MAX_POWER_INDEX
3453 */
3454 VOID
3455 PHY_InitTxPowerLimit(
3456         IN      PADAPTER                Adapter
3457 )
3458 {
3459         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3460         u8 i, j, k, l, m;
3461
3462         for (i = 0; i < MAX_REGULATION_NUM; ++i)
3463                 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
3464                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
3465                                 for (m = 0; m < CENTER_CH_2G_NUM; ++m)
3466                                         for (l = 0; l < MAX_RF_PATH; ++l)
3467                                                 pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
3468
3469         for (i = 0; i < MAX_REGULATION_NUM; ++i)
3470                 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
3471                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
3472                                 for (m = 0; m < CENTER_CH_5G_ALL_NUM; ++m)
3473                                         for (l = 0; l < MAX_RF_PATH; ++l)
3474                                                 pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX;
3475 }
3476
3477 /*
3478 * phy_set_tx_power_limit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm
3479 */
3480 VOID
3481 phy_set_tx_power_limit(
3482         IN      struct PHY_DM_STRUCT            *pDM_Odm,
3483         IN      u8                              *Regulation,
3484         IN      u8                              *Band,
3485         IN      u8                              *Bandwidth,
3486         IN      u8                              *RateSection,
3487         IN      u8                              *RfPath,
3488         IN      u8                              *Channel,
3489         IN      u8                              *PowerLimit
3490 )
3491 {
3492         PADAPTER Adapter = pDM_Odm->adapter;
3493         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3494         u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
3495         s8 powerLimit = 0, prevPowerLimit, channelIndex;
3496
3497         if (0)
3498                 RTW_INFO("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n"
3499                         , Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit);
3500
3501         if (GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) == _FALSE
3502                 || GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit) == _FALSE
3503         ) {
3504                 RTW_PRINT("Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit);
3505                 return;
3506         }
3507
3508         powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
3509
3510         if (eqNByte(Regulation, (u8 *)("FCC"), 3))
3511                 regulation = TXPWR_LMT_FCC;
3512         else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
3513                 regulation = TXPWR_LMT_MKK;
3514         else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
3515                 regulation = TXPWR_LMT_ETSI;
3516         else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
3517                 regulation = TXPWR_LMT_WW;
3518         else {
3519                 RTW_PRINT("unknown regulation:%s", Regulation);
3520                 return;
3521         }
3522
3523         if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
3524                 rateSection = CCK;
3525         else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
3526                 rateSection = OFDM;
3527         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
3528                 rateSection = HT_1SS;
3529         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2))
3530                 rateSection = HT_2SS;
3531         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2))
3532                 rateSection = HT_3SS;
3533         else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2))
3534                 rateSection = HT_4SS;
3535         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
3536                 rateSection = VHT_1SS;
3537         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2))
3538                 rateSection = VHT_2SS;
3539         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2))
3540                 rateSection = VHT_3SS;
3541         else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2))
3542                 rateSection = VHT_4SS;
3543         else {
3544                 RTW_PRINT("Wrong rate section: (%s,%s)\n", RateSection, RfPath);
3545                 return;
3546         }
3547
3548         if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
3549                 bandwidth = CHANNEL_WIDTH_20;
3550         else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
3551                 bandwidth = CHANNEL_WIDTH_40;
3552         else if (eqNByte(Bandwidth, (u8 *)("80M"), 3))
3553                 bandwidth = CHANNEL_WIDTH_80;
3554         else {
3555                 RTW_PRINT("unknown bandwidth: %s\n", Bandwidth);
3556                 return;
3557         }
3558
3559         if (eqNByte(Band, (u8 *)("2.4G"), 4)) {
3560                 channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
3561
3562                 if (channelIndex == -1) {
3563                         RTW_PRINT("unsupported channel: %d at 2.4G\n", channel);
3564                         return;
3565                 }
3566
3567                 if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) {
3568                         RTW_PRINT("unsupported bandwidth: %s at 2.4G\n", Bandwidth);
3569                         return;
3570                 }
3571
3572                 prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
3573
3574                 if (prevPowerLimit != MAX_POWER_INDEX)
3575                         RTW_PRINT("duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
3576                                 , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
3577
3578                 if (powerLimit < prevPowerLimit)
3579                         pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
3580
3581                 if (0)
3582                         RTW_INFO("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
3583                                 , regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]);
3584         } else if (eqNByte(Band, (u8 *)("5G"), 2)) {
3585
3586                 channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
3587
3588                 if (channelIndex == -1) {
3589                         RTW_PRINT("unsupported channel: %d at 5G\n", channel);
3590                         return;
3591                 }
3592
3593                 prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
3594
3595                 if (prevPowerLimit != MAX_POWER_INDEX)
3596                         RTW_PRINT("duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
3597                                 , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
3598
3599                 if (powerLimit < prevPowerLimit)
3600                         pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
3601
3602                 if (0)
3603                         RTW_INFO("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
3604                                 , regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]);
3605         } else {
3606                 RTW_PRINT("Cannot recognize the band info in %s\n", Band);
3607                 return;
3608         }
3609 }
3610
3611 u8
3612 phy_get_tx_power_index(
3613         IN      PADAPTER                        pAdapter,
3614         IN      u8                                      RFPath,
3615         IN      u8                                      Rate,
3616         IN      CHANNEL_WIDTH           BandWidth,
3617         IN      u8                                      Channel
3618 )
3619 {
3620         return rtw_hal_get_tx_power_index(pAdapter, RFPath, Rate, BandWidth, Channel, NULL);
3621 }
3622
3623 VOID
3624 PHY_SetTxPowerIndex(
3625         IN      PADAPTER                pAdapter,
3626         IN      u32                             PowerIndex,
3627         IN      u8                              RFPath,
3628         IN      u8                              Rate
3629 )
3630 {
3631         if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
3632 #if (RTL8814A_SUPPORT == 1)
3633                 PHY_SetTxPowerIndex_8814A(pAdapter, PowerIndex, RFPath, Rate);
3634 #endif
3635         } else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
3636 #if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
3637                 PHY_SetTxPowerIndex_8812A(pAdapter, PowerIndex, RFPath, Rate);
3638 #endif
3639         } else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
3640 #if (RTL8723B_SUPPORT == 1)
3641                 PHY_SetTxPowerIndex_8723B(pAdapter, PowerIndex, RFPath, Rate);
3642 #endif
3643         } else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
3644 #if (RTL8703B_SUPPORT == 1)
3645                 PHY_SetTxPowerIndex_8703B(pAdapter, PowerIndex, RFPath, Rate);
3646 #endif
3647         } else if (IS_HARDWARE_TYPE_8723D(pAdapter)) {
3648 #if (RTL8723D_SUPPORT == 1)
3649                 PHY_SetTxPowerIndex_8723D(pAdapter, PowerIndex, RFPath, Rate);
3650 #endif
3651         } else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
3652 #if (RTL8192E_SUPPORT == 1)
3653                 PHY_SetTxPowerIndex_8192E(pAdapter, PowerIndex, RFPath, Rate);
3654 #endif
3655         } else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
3656 #if (RTL8188E_SUPPORT == 1)
3657                 PHY_SetTxPowerIndex_8188E(pAdapter, PowerIndex, RFPath, Rate);
3658 #endif
3659         } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
3660 #if (RTL8188F_SUPPORT == 1)
3661                 PHY_SetTxPowerIndex_8188F(pAdapter, PowerIndex, RFPath, Rate);
3662 #endif
3663         } else if (IS_HARDWARE_TYPE_8822B(pAdapter))
3664                 rtw_hal_set_tx_power_index(pAdapter, PowerIndex, RFPath, Rate);
3665         else if (IS_HARDWARE_TYPE_8821C(pAdapter))
3666                 rtw_hal_set_tx_power_index(pAdapter, PowerIndex, RFPath, Rate);
3667 }
3668
3669 void dump_tx_power_idx_title(void *sel, _adapter *adapter)
3670 {
3671         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3672         u8 bw = hal_data->current_channel_bw;
3673
3674         RTW_PRINT_SEL(sel, "%s", ch_width_str(bw));
3675         if (bw >= CHANNEL_WIDTH_80)
3676                 _RTW_PRINT_SEL(sel, ", cch80:%u", hal_data->cch_80);
3677         if (bw >= CHANNEL_WIDTH_40)
3678                 _RTW_PRINT_SEL(sel, ", cch40:%u", hal_data->cch_40);
3679         _RTW_PRINT_SEL(sel, ", cch20:%u\n", hal_data->cch_20);
3680
3681         RTW_PRINT_SEL(sel, "%-4s %-9s %-3s %-4s %-3s %-4s %-4s %-3s %-5s\n"
3682                 , "path", "rate", "pwr", "base", "", "(byr", "lmt)", "tpt", "ebias");
3683 }
3684
3685 void dump_tx_power_idx_by_path_rs(void *sel, _adapter *adapter, u8 rfpath, u8 rs)
3686 {
3687         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3688         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3689         u8 power_idx;
3690         struct txpwr_idx_comp tic;
3691         u8 tx_num, i;
3692         u8 band = hal_data->current_band_type;
3693         u8 cch = hal_data->current_channel;
3694         u8 bw = hal_data->current_channel_bw;
3695
3696         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, rfpath))
3697                 return;
3698
3699         if (rs >= RATE_SECTION_NUM)
3700                 return;
3701
3702         tx_num = rate_section_to_tx_num(rs);
3703         if (tx_num >= hal_spec->tx_nss_num || tx_num >= hal_spec->max_tx_cnt)
3704                 return;
3705
3706         if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
3707                 return;
3708
3709         if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
3710                 return;
3711
3712         for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
3713                 power_idx = rtw_hal_get_tx_power_index(adapter, rfpath, rates_by_sections[rs].rates[i], bw, cch, &tic);
3714
3715                 RTW_PRINT_SEL(sel, "%4c %9s %3u %4u %3d (%3d %3d) %3d %5d\n"
3716                         , rf_path_char(rfpath), MGN_RATE_STR(rates_by_sections[rs].rates[i])
3717                         , power_idx, tic.base, (tic.by_rate > tic.limit ? tic.limit : tic.by_rate), tic.by_rate, tic.limit, tic.tpt, tic.ebias);
3718         }
3719 }
3720
3721 void dump_tx_power_idx(void *sel, _adapter *adapter)
3722 {
3723         u8 rfpath, rs;
3724
3725         dump_tx_power_idx_title(sel, adapter);
3726         for (rfpath = RF_PATH_A; rfpath < RF_PATH_MAX; rfpath++)
3727                 for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
3728                         dump_tx_power_idx_by_path_rs(sel, adapter, rfpath, rs);
3729 }
3730
3731 bool phy_is_tx_power_limit_needed(_adapter *adapter)
3732 {
3733         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3734         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
3735
3736         if (regsty->RegEnableTxPowerLimit == 1
3737                 || (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
3738                 return _TRUE;
3739         return _FALSE;
3740 }
3741
3742 bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
3743 {
3744         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3745         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
3746
3747         if (regsty->RegEnableTxPowerByRate == 1
3748                 || (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
3749                 return _TRUE;
3750         return _FALSE;
3751 }
3752
3753 int phy_load_tx_power_by_rate(_adapter *adapter, u8 chk_file)
3754 {
3755         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3756         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
3757         int ret = _FAIL;
3758
3759         hal_data->txpwr_by_rate_loaded = 0;
3760         PHY_InitTxPowerByRate(adapter);
3761
3762         /* tx power limit is based on tx power by rate */
3763         hal_data->txpwr_limit_loaded = 0;
3764
3765 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
3766         if (chk_file
3767                 && phy_ConfigBBWithPgParaFile(adapter, PHY_FILE_PHY_REG_PG) == _SUCCESS
3768         ) {
3769                 hal_data->txpwr_by_rate_from_file = 1;
3770                 goto post_hdl;
3771         }
3772 #endif
3773
3774 #ifdef CONFIG_EMBEDDED_FWIMG
3775         if (HAL_STATUS_SUCCESS == odm_config_bb_with_header_file(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
3776                 RTW_INFO("default power by rate loaded\n");
3777                 hal_data->txpwr_by_rate_from_file = 0;
3778                 goto post_hdl;
3779         }
3780 #endif
3781
3782         RTW_ERR("%s():Read Tx power by rate fail\n", __func__);
3783         goto exit;
3784
3785 post_hdl:
3786         if (hal_data->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
3787                 rtw_warn_on(1);
3788                 goto exit;
3789         }
3790
3791         PHY_TxPowerByRateConfiguration(adapter);
3792         hal_data->txpwr_by_rate_loaded = 1;
3793
3794         ret = _SUCCESS;
3795
3796 exit:
3797         return ret;
3798 }
3799
3800 int phy_load_tx_power_limit(_adapter *adapter, u8 chk_file)
3801 {
3802         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3803         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
3804         int ret = _FAIL;
3805
3806         hal_data->txpwr_limit_loaded = 0;
3807         PHY_InitTxPowerLimit(adapter);
3808
3809         if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) {
3810                 RTW_ERR("%s():Read Tx power limit before target tx power is specify\n", __func__);
3811                 goto exit;
3812         }
3813
3814 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
3815         if (chk_file
3816                 && PHY_ConfigRFWithPowerLimitTableParaFile(adapter, PHY_FILE_TXPWR_LMT) == _SUCCESS
3817         ) {
3818                 hal_data->txpwr_limit_from_file = 1;
3819                 goto post_hdl;
3820         }
3821 #endif
3822
3823 #ifdef CONFIG_EMBEDDED_FWIMG
3824         if (HAL_STATUS_SUCCESS == odm_config_rf_with_header_file(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, (enum odm_rf_radio_path_e)0)) {
3825                 RTW_INFO("default power limit loaded\n");
3826                 hal_data->txpwr_limit_from_file = 0;
3827                 goto post_hdl;
3828         }
3829 #endif
3830
3831         RTW_ERR("%s():Read Tx power limit fail\n", __func__);
3832         goto exit;
3833
3834 post_hdl:
3835         PHY_ConvertTxPowerLimitToPowerIndex(adapter);
3836         hal_data->txpwr_limit_loaded = 1;
3837         ret = _SUCCESS;
3838
3839 exit:
3840         return ret;
3841 }
3842
3843 void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file)
3844 {
3845         struct registry_priv *regsty = adapter_to_regsty(adapter);
3846
3847         /* check registy target tx power */
3848         regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
3849
3850         /* power by rate and limit */
3851         if (phy_is_tx_power_by_rate_needed(adapter)
3852                 || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE)
3853         )
3854                 phy_load_tx_power_by_rate(adapter, chk_file);
3855
3856         if (phy_is_tx_power_limit_needed(adapter))
3857                 phy_load_tx_power_limit(adapter, chk_file);
3858 }
3859
3860 inline void phy_reload_tx_power_ext_info(_adapter *adapter)
3861 {
3862         phy_load_tx_power_ext_info(adapter, 1);
3863 }
3864
3865 inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
3866 {
3867         phy_load_tx_power_ext_info(adapter, 0);
3868 }
3869
3870 void dump_tx_power_ext_info(void *sel, _adapter *adapter)
3871 {
3872         struct registry_priv *regsty = adapter_to_regsty(adapter);
3873         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3874
3875         if (regsty->target_tx_pwr_valid == _TRUE)
3876                 RTW_PRINT_SEL(sel, "target_tx_power: from registry\n");
3877         else if (phy_is_tx_power_by_rate_needed(adapter))
3878                 RTW_PRINT_SEL(sel, "target_tx_power: from power by rate\n"); 
3879         else
3880                 RTW_PRINT_SEL(sel, "target_tx_power: unavailable\n");
3881
3882         RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
3883                 , phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
3884                 , hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
3885                 , hal_data->txpwr_by_rate_from_file ? "file" : "default"
3886         );
3887
3888         RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
3889                 , phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
3890                 , hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
3891                 , hal_data->txpwr_limit_from_file ? "file" : "default"
3892         );
3893 }
3894
3895 void dump_target_tx_power(void *sel, _adapter *adapter)
3896 {
3897         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3898         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3899         struct registry_priv *regsty = adapter_to_regsty(adapter);
3900         int path, tx_num, band, rs;
3901         u8 target;
3902
3903         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
3904                 if (!hal_is_band_support(adapter, band))
3905                         continue;
3906
3907                 for (path = 0; path < RF_PATH_MAX; path++) {
3908                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
3909                                 break;
3910
3911                         RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
3912                                 , (regsty->target_tx_pwr_valid == _FALSE && hal_data->txpwr_by_rate_undefined_band_path[band][path]) ? "(dup)" : "");
3913
3914                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
3915                                 tx_num = rate_section_to_tx_num(rs);
3916                                 if (tx_num >= hal_spec->tx_nss_num)
3917                                         continue;
3918
3919                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
3920                                         continue;
3921
3922                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
3923                                         continue;
3924
3925                                 target = PHY_GetTxPowerByRateBase(adapter, band, path, rate_section_to_tx_num(rs), rs);
3926
3927                                 if (target % 2)
3928                                         _RTW_PRINT_SEL(sel, "%7s: %2d.5\n", rate_section_str(rs), target / 2);
3929                                 else
3930                                         _RTW_PRINT_SEL(sel, "%7s: %4d\n", rate_section_str(rs), target / 2);
3931                         }
3932                 }
3933         }
3934
3935 exit:
3936         return;
3937 }
3938
3939 void dump_tx_power_by_rate(void *sel, _adapter *adapter)
3940 {
3941         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3942         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3943         int path, tx_num, band, n, rs;
3944         u8 rate_num, max_rate_num, base;
3945         s8 by_rate_offset;
3946
3947         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
3948                 if (!hal_is_band_support(adapter, band))
3949                         continue;
3950
3951                 for (path = 0; path < RF_PATH_MAX; path++) {
3952                         if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
3953                                 break;
3954
3955                         RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
3956                                 , hal_data->txpwr_by_rate_undefined_band_path[band][path] ? "(dup)" : "");
3957
3958                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
3959                                 tx_num = rate_section_to_tx_num(rs);
3960                                 if (tx_num >= hal_spec->tx_nss_num)
3961                                         continue;
3962
3963                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
3964                                         continue;
3965
3966                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
3967                                         continue;
3968
3969                                 if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
3970                                         max_rate_num = 10;
3971                                 else
3972                                         max_rate_num = 8;
3973                                 rate_num = rate_section_rate_num(rs);
3974                                 base = PHY_GetTxPowerByRateBase(adapter, band, path, tx_num, rs);
3975
3976                                 RTW_PRINT_SEL(sel, "%7s: ", rate_section_str(rs));
3977
3978                                 /* dump power by rate in db */
3979                                 for (n = rate_num - 1; n >= 0; n--) {
3980                                         by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
3981
3982                                         if ((base + by_rate_offset) % 2)
3983                                                 _RTW_PRINT_SEL(sel, "%2d.5 ", (base + by_rate_offset) / 2);
3984                                         else
3985                                                 _RTW_PRINT_SEL(sel, "%4d ", (base + by_rate_offset) / 2);
3986                                 }
3987                                 for (n = 0; n < max_rate_num - rate_num; n++)
3988                                         _RTW_PRINT_SEL(sel, "%4s ", "");
3989
3990                                 _RTW_PRINT_SEL(sel, "|");
3991
3992                                 /* dump power by rate in offset */
3993                                 for (n = rate_num - 1; n >= 0; n--) {
3994                                         by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
3995                                         _RTW_PRINT_SEL(sel, "%3d ", by_rate_offset);
3996                                 }
3997                                 RTW_PRINT_SEL(sel, "\n");
3998
3999                         }
4000                 }
4001         }
4002 }
4003
4004 void dump_tx_power_limit(void *sel, _adapter *adapter)
4005 {
4006         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4007         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4008         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
4009
4010         int bw, band, ch_num, rs, i, path;
4011         u8 ch, n, rd, rfpath_num;
4012
4013         if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
4014                 RTW_PRINT_SEL(sel, "tx_pwr_lmt_5g_20_40_ref:0x%02x\n", hal_data->tx_pwr_lmt_5g_20_40_ref);
4015
4016         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
4017                 if (!hal_is_band_support(adapter, band))
4018                         continue;
4019
4020                 rd = (band == BAND_ON_2_4G ? hal_data->Regulation2_4G : hal_data->Regulation5G);
4021                 rfpath_num = (band == BAND_ON_2_4G ? hal_spec->rfpath_num_2g : hal_spec->rfpath_num_5g);
4022
4023                 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; bw++) {
4024
4025                         if (bw >= CHANNEL_WIDTH_160)
4026                                 break;
4027                         if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80)
4028                                 break;
4029
4030                         if (band == BAND_ON_2_4G)
4031                                 ch_num = CENTER_CH_2G_NUM;
4032                         else
4033                                 ch_num = center_chs_5g_num(bw);
4034
4035                         if (ch_num == 0) {
4036                                 rtw_warn_on(1);
4037                                 break;
4038                         }
4039
4040                         for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
4041                                 if (band == BAND_ON_2_4G && IS_VHT_RATE_SECTION(rs))
4042                                         continue;
4043                                 if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
4044                                         continue;
4045                                 if (bw > CHANNEL_WIDTH_20 && (IS_CCK_RATE_SECTION(rs) || IS_OFDM_RATE_SECTION(rs)))
4046                                         continue;
4047                                 if (bw > CHANNEL_WIDTH_40 && IS_HT_RATE_SECTION(rs))
4048                                         continue;
4049
4050                                 if (rate_section_to_tx_num(rs) >= hal_spec->tx_nss_num)
4051                                         continue;
4052
4053                                 if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
4054                                         continue;
4055
4056                                 /* by pass 5G 20M, 40M pure reference */
4057                                 if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) {
4058                                         if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_HT_FROM_VHT) {
4059                                                 if (IS_HT_RATE_SECTION(rs))
4060                                                         continue;
4061                                         } else if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_VHT_FROM_HT) {
4062                                                 if (IS_VHT_RATE_SECTION(rs) && bw <= CHANNEL_WIDTH_40)
4063                                                         continue;
4064                                         }
4065                                 }
4066
4067                                 RTW_PRINT_SEL(sel, "[%s][%s][%s]\n"
4068                                         , band_str(band)
4069                                         , ch_width_str(bw)
4070                                         , rate_section_str(rs)
4071                                 );
4072
4073                                 /* header for limit in db */
4074                                 RTW_PRINT_SEL(sel, "%3s %5s %5s %5s %5s "
4075                                         , "ch"
4076                                         , (rd == TXPWR_LMT_FCC ? "*FCC" : "FCC")
4077                                         , (rd == TXPWR_LMT_ETSI ? "*ETSI" : "ETSI")
4078                                         , (rd == TXPWR_LMT_MKK ? "*MKK" : "MKK")
4079                                         , (rd == TXPWR_LMT_WW ? "*WW" : "WW")
4080                                 );
4081
4082                                 /* header for limit offset */
4083                                 for (path = 0; path < RF_PATH_MAX; path++) {
4084                                         if (path >= rfpath_num)
4085                                                 break;
4086                                         _RTW_PRINT_SEL(sel, "|%3c %3c %3c %3c "
4087                                                 , (rd == TXPWR_LMT_FCC ? rf_path_char(path) : ' ')
4088                                                 , (rd == TXPWR_LMT_ETSI ? rf_path_char(path) : ' ')
4089                                                 , (rd == TXPWR_LMT_MKK ? rf_path_char(path) : ' ')
4090                                                 , (rd == TXPWR_LMT_WW ? rf_path_char(path) : ' ')
4091                                         );
4092                                 }
4093                                 _RTW_PRINT_SEL(sel, "\n");
4094
4095                                 for (n = 0; n < ch_num; n++) {
4096                                         s8 limit_idx[RF_PATH_MAX][MAX_REGULATION_NUM];
4097                                         s8 limit_offset[MAX_REGULATION_NUM];
4098                                         u8 base;
4099
4100                                         if (band == BAND_ON_2_4G)
4101                                                 ch = n + 1;
4102                                         else
4103                                                 ch = center_chs_5g(bw, n);
4104
4105                                         if (ch == 0) {
4106                                                 rtw_warn_on(1);
4107                                                 break;
4108                                         }
4109
4110                                         /* dump limit in db (calculate from path A) */
4111                                         limit_offset[0] = PHY_GetTxPowerLimit_no_sc(adapter, 3, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* FCC */
4112                                         limit_offset[1] = PHY_GetTxPowerLimit_no_sc(adapter, 1, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* ETSI */
4113                                         limit_offset[2] = PHY_GetTxPowerLimit_no_sc(adapter, 2, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* MKK */
4114                                         limit_offset[3] = PHY_GetTxPowerLimit_no_sc(adapter, 4, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* WW */
4115
4116                                         base = PHY_GetTxPowerByRateBase(adapter, band, RF_PATH_A, rate_section_to_tx_num(rs), rs);
4117
4118                                         RTW_PRINT_SEL(sel, "%3u ", ch);
4119                                         for (i = 0; i < MAX_REGULATION_NUM; i++) {
4120                                                 if (limit_offset[i] == MAX_POWER_INDEX) {
4121                                                         limit_idx[0][i] = MAX_POWER_INDEX;
4122                                                         _RTW_PRINT_SEL(sel, "%5s ", "NA");
4123                                                 } else {
4124                                                         limit_idx[0][i] = limit_offset[i] + base;
4125                                                         if ((limit_offset[i] + base) % 2)
4126                                                                 _RTW_PRINT_SEL(sel, "%3d.5 ", (limit_offset[i] + base) / 2);
4127                                                         else
4128                                                                 _RTW_PRINT_SEL(sel, "%5d ", (limit_offset[i] + base) / 2);
4129                                                 }
4130                                         }
4131
4132                                         /* dump limit offset of each path */
4133                                         for (path = 0; path < RF_PATH_MAX; path++) {
4134                                                 if (path >= rfpath_num)
4135                                                         break;
4136                                                 limit_offset[0] = PHY_GetTxPowerLimit_no_sc(adapter, 3, band, bw, path, rates_by_sections[rs].rates[0], ch); /* FCC */
4137                                                 limit_offset[1] = PHY_GetTxPowerLimit_no_sc(adapter, 1, band, bw, path, rates_by_sections[rs].rates[0], ch); /* ETSI */
4138                                                 limit_offset[2] = PHY_GetTxPowerLimit_no_sc(adapter, 2, band, bw, path, rates_by_sections[rs].rates[0], ch); /* MKK */
4139                                                 limit_offset[3] = PHY_GetTxPowerLimit_no_sc(adapter, 4, band, bw, path, rates_by_sections[rs].rates[0], ch); /* WW */
4140
4141                                                 base = PHY_GetTxPowerByRateBase(adapter, band, path, rate_section_to_tx_num(rs), rs);
4142
4143                                                 _RTW_PRINT_SEL(sel, "|");
4144                                                 for (i = 0; i < MAX_REGULATION_NUM; i++) {
4145                                                         if (limit_offset[i] == MAX_POWER_INDEX) {
4146                                                                 limit_idx[path][i] = MAX_POWER_INDEX;
4147                                                                 _RTW_PRINT_SEL(sel, "%3s ", "NA");
4148                                                         } else {
4149                                                                 limit_idx[path][i] = limit_offset[i] + base;
4150                                                                 _RTW_PRINT_SEL(sel, "%3d ", limit_offset[i]);
4151                                                         }
4152                                                 }
4153                                         }
4154
4155                                         /* compare limit_idx of each path, print 'x' when mismatch */
4156                                         if (rfpath_num > 1) {
4157                                                 for (i = 0; i < MAX_REGULATION_NUM; i++) {
4158                                                         for (path = 0; path < RF_PATH_MAX; path++) {
4159                                                                 if (path >= rfpath_num)
4160                                                                         break;
4161                                                                 if (limit_idx[path][i] != limit_idx[(path + 1) % rfpath_num][i])
4162                                                                         break;
4163                                                         }
4164                                                         if (path >= rfpath_num)
4165                                                                 _RTW_PRINT_SEL(sel, " ");
4166                                                         else
4167                                                                 _RTW_PRINT_SEL(sel, "x");
4168                                                 }
4169                                         }
4170                                         _RTW_PRINT_SEL(sel, "\n");
4171
4172                                 }
4173                                 RTW_PRINT_SEL(sel, "\n");
4174                         } /* loop for rate sections */
4175                 } /* loop for bandwidths */
4176         } /* loop for bands */
4177 }
4178
4179 /*
4180  * phy file path is stored in global char array rtw_phy_para_file_path
4181  * need to care about racing
4182  */
4183 int rtw_get_phy_file_path(_adapter *adapter, const char *file_name)
4184 {
4185 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4186         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4187         int len = 0;
4188
4189         if (file_name) {
4190                 len += snprintf(rtw_phy_para_file_path, PATH_LENGTH_MAX, "%s", rtw_phy_file_path);
4191                 #if defined(CONFIG_MULTIDRV) || defined(REALTEK_CONFIG_PATH_WITH_IC_NAME_FOLDER)
4192                 len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s/", hal_spec->ic_name);
4193                 #endif
4194                 len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s", file_name);
4195
4196                 return _TRUE;
4197         }
4198 #endif
4199         return _FALSE;
4200 }
4201
4202 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
4203 int
4204 phy_ConfigMACWithParaFile(
4205         IN      PADAPTER        Adapter,
4206         IN      char            *pFileName
4207 )
4208 {
4209         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
4210         int     rlen = 0, rtStatus = _FAIL;
4211         char    *szLine, *ptmp;
4212         u32     u4bRegOffset, u4bRegValue, u4bMove;
4213
4214         if (!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
4215                 return rtStatus;
4216
4217         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4218
4219         if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) {
4220                 rtw_get_phy_file_path(Adapter, pFileName);
4221                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
4222                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4223                         if (rlen > 0) {
4224                                 rtStatus = _SUCCESS;
4225                                 pHalData->mac_reg = rtw_zvmalloc(rlen);
4226                                 if (pHalData->mac_reg) {
4227                                         _rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
4228                                         pHalData->mac_reg_len = rlen;
4229                                 } else
4230                                         RTW_INFO("%s mac_reg alloc fail !\n", __FUNCTION__);
4231                         }
4232                 }
4233         } else {
4234                 if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
4235                         _rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
4236                         rtStatus = _SUCCESS;
4237                 } else
4238                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4239         }
4240
4241         if (rtStatus == _SUCCESS) {
4242                 ptmp = pHalData->para_file_buf;
4243                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4244                         if (!IsCommentString(szLine)) {
4245                                 /* Get 1st hex value as register offset */
4246                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4247                                         if (u4bRegOffset == 0xffff) {
4248                                                 /* Ending. */
4249                                                 break;
4250                                         }
4251
4252                                         /* Get 2nd hex value as register value. */
4253                                         szLine += u4bMove;
4254                                         if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
4255                                                 rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
4256                                 }
4257                         }
4258                 }
4259         } else
4260                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4261
4262         return rtStatus;
4263 }
4264
4265 int
4266 phy_ConfigBBWithParaFile(
4267         IN      PADAPTER        Adapter,
4268         IN      char            *pFileName,
4269         IN      u32                     ConfigType
4270 )
4271 {
4272         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4273         int     rlen = 0, rtStatus = _FAIL;
4274         char    *szLine, *ptmp;
4275         u32     u4bRegOffset, u4bRegValue, u4bMove;
4276         char    *pBuf = NULL;
4277         u32     *pBufLen = NULL;
4278
4279         if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
4280                 return rtStatus;
4281
4282         switch (ConfigType) {
4283         case CONFIG_BB_PHY_REG:
4284                 pBuf = pHalData->bb_phy_reg;
4285                 pBufLen = &pHalData->bb_phy_reg_len;
4286                 break;
4287         case CONFIG_BB_AGC_TAB:
4288                 pBuf = pHalData->bb_agc_tab;
4289                 pBufLen = &pHalData->bb_agc_tab_len;
4290                 break;
4291         default:
4292                 RTW_INFO("Unknown ConfigType!! %d\r\n", ConfigType);
4293                 break;
4294         }
4295
4296         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4297
4298         if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
4299                 rtw_get_phy_file_path(Adapter, pFileName);
4300                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
4301                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4302                         if (rlen > 0) {
4303                                 rtStatus = _SUCCESS;
4304                                 pBuf = rtw_zvmalloc(rlen);
4305                                 if (pBuf) {
4306                                         _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
4307                                         *pBufLen = rlen;
4308
4309                                         switch (ConfigType) {
4310                                         case CONFIG_BB_PHY_REG:
4311                                                 pHalData->bb_phy_reg = pBuf;
4312                                                 break;
4313                                         case CONFIG_BB_AGC_TAB:
4314                                                 pHalData->bb_agc_tab = pBuf;
4315                                                 break;
4316                                         }
4317                                 } else
4318                                         RTW_INFO("%s(): ConfigType %d  alloc fail !\n", __FUNCTION__, ConfigType);
4319                         }
4320                 }
4321         } else {
4322                 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
4323                         _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
4324                         rtStatus = _SUCCESS;
4325                 } else
4326                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4327         }
4328
4329         if (rtStatus == _SUCCESS) {
4330                 ptmp = pHalData->para_file_buf;
4331                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4332                         if (!IsCommentString(szLine)) {
4333                                 /* Get 1st hex value as register offset. */
4334                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4335                                         if (u4bRegOffset == 0xffff) {
4336                                                 /* Ending. */
4337                                                 break;
4338                                         } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4339 #ifdef CONFIG_LONG_DELAY_ISSUE
4340                                                 rtw_msleep_os(50);
4341 #else
4342                                                 rtw_mdelay_os(50);
4343 #endif
4344                                         } else if (u4bRegOffset == 0xfd)
4345                                                 rtw_mdelay_os(5);
4346                                         else if (u4bRegOffset == 0xfc)
4347                                                 rtw_mdelay_os(1);
4348                                         else if (u4bRegOffset == 0xfb)
4349                                                 rtw_udelay_os(50);
4350                                         else if (u4bRegOffset == 0xfa)
4351                                                 rtw_udelay_os(5);
4352                                         else if (u4bRegOffset == 0xf9)
4353                                                 rtw_udelay_os(1);
4354
4355                                         /* Get 2nd hex value as register value. */
4356                                         szLine += u4bMove;
4357                                         if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4358                                                 /* RTW_INFO("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4359                                                 phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4360
4361                                                 if (u4bRegOffset == 0xa24)
4362                                                         pHalData->odmpriv.rf_calibrate_info.rega24 = u4bRegValue;
4363
4364                                                 /* Add 1us delay between BB/RF register setting. */
4365                                                 rtw_udelay_os(1);
4366                                         }
4367                                 }
4368                         }
4369                 }
4370         } else
4371                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4372
4373         return rtStatus;
4374 }
4375
4376 VOID
4377 phy_DecryptBBPgParaFile(
4378         PADAPTER                Adapter,
4379         char                    *buffer
4380 )
4381 {
4382         u32     i = 0, j = 0;
4383         u8      map[95] = {0};
4384         u8      currentChar;
4385         char    *BufOfLines, *ptmp;
4386
4387         /* RTW_INFO("=====>phy_DecryptBBPgParaFile()\n"); */
4388         /* 32 the ascii code of the first visable char, 126 the last one */
4389         for (i = 0; i < 95; ++i)
4390                 map[i] = (u8)(94 - i);
4391
4392         ptmp = buffer;
4393         i = 0;
4394         for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) {
4395                 /* RTW_INFO("Encrypted Line: %s\n", BufOfLines); */
4396
4397                 for (j = 0; j < strlen(BufOfLines); ++j) {
4398                         currentChar = BufOfLines[j];
4399
4400                         if (currentChar == '\0')
4401                                 break;
4402
4403                         currentChar -= (u8)((((i + j) * 3) % 128));
4404
4405                         BufOfLines[j] = map[currentChar - 32] + 32;
4406                 }
4407                 /* RTW_INFO("Decrypted Line: %s\n", BufOfLines ); */
4408                 if (strlen(BufOfLines) != 0)
4409                         i++;
4410                 BufOfLines[strlen(BufOfLines)] = '\n';
4411         }
4412 }
4413
4414 int
4415 phy_ParseBBPgParaFile(
4416         PADAPTER                Adapter,
4417         char                    *buffer
4418 )
4419 {
4420         int     rtStatus = _SUCCESS;
4421         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4422         char    *szLine, *ptmp;
4423         u32     u4bRegOffset, u4bRegMask, u4bRegValue;
4424         u32     u4bMove;
4425         BOOLEAN firstLine = _TRUE;
4426         u8      tx_num = 0;
4427         u8      band = 0, rf_path = 0;
4428
4429         /* RTW_INFO("=====>phy_ParseBBPgParaFile()\n"); */
4430
4431         if (Adapter->registrypriv.RegDecryptCustomFile == 1)
4432                 phy_DecryptBBPgParaFile(Adapter, buffer);
4433
4434         ptmp = buffer;
4435         for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4436                 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
4437                         continue;
4438
4439                 if (!IsCommentString(szLine)) {
4440                         /* Get header info (relative value or exact value) */
4441                         if (firstLine) {
4442                                 if (eqNByte(szLine, (u8 *)("#[v1]"), 5)) {
4443
4444                                         pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
4445                                         /* RTW_INFO("This is a new format PHY_REG_PG.txt\n"); */
4446                                 } else if (eqNByte(szLine, (u8 *)("#[v0]"), 5)) {
4447                                         pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
4448                                         /* RTW_INFO("This is a old format PHY_REG_PG.txt ok\n"); */
4449                                 } else {
4450                                         RTW_INFO("The format in PHY_REG_PG are invalid %s\n", szLine);
4451                                         return _FAIL;
4452                                 }
4453
4454                                 if (eqNByte(szLine + 5, (u8 *)("[Exact]#"), 8)) {
4455                                         pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
4456                                         /* RTW_INFO("The values in PHY_REG_PG are exact values ok\n"); */
4457                                         firstLine = _FALSE;
4458                                         continue;
4459                                 } else if (eqNByte(szLine + 5, (pu1Byte)("[Relative]#"), 11)) {
4460                                         pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_RELATIVE_VALUE;
4461                                         /* RTW_INFO("The values in PHY_REG_PG are relative values ok\n"); */
4462                                         firstLine = _FALSE;
4463                                         continue;
4464                                 } else {
4465                                         RTW_INFO("The values in PHY_REG_PG are invalid %s\n", szLine);
4466                                         return _FAIL;
4467                                 }
4468                         }
4469
4470                         if (pHalData->odmpriv.phy_reg_pg_version == 0) {
4471                                 /* Get 1st hex value as register offset. */
4472                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4473                                         szLine += u4bMove;
4474                                         if (u4bRegOffset == 0xffff) {
4475                                                 /* Ending. */
4476                                                 break;
4477                                         }
4478
4479                                         /* Get 2nd hex value as register mask. */
4480                                         if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
4481                                                 szLine += u4bMove;
4482                                         else
4483                                                 return _FAIL;
4484
4485                                         if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_RELATIVE_VALUE) {
4486                                                 /* Get 3rd hex value as register value. */
4487                                                 if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4488                                                         phy_store_tx_power_by_rate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue);
4489                                                         /* RTW_INFO("[ADDR] %03X=%08X Mask=%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask); */
4490                                                 } else
4491                                                         return _FAIL;
4492                                         } else if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
4493                                                 u32     combineValue = 0;
4494                                                 u8      integer = 0, fraction = 0;
4495
4496                                                 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4497                                                         szLine += u4bMove;
4498                                                 else
4499                                                         return _FAIL;
4500
4501                                                 integer *= 2;
4502                                                 if (fraction == 5)
4503                                                         integer += 1;
4504                                                 combineValue |= (((integer / 10) << 4) + (integer % 10));
4505                                                 /* RTW_INFO(" %d", integer ); */
4506
4507                                                 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4508                                                         szLine += u4bMove;
4509                                                 else
4510                                                         return _FAIL;
4511
4512                                                 integer *= 2;
4513                                                 if (fraction == 5)
4514                                                         integer += 1;
4515                                                 combineValue <<= 8;
4516                                                 combineValue |= (((integer / 10) << 4) + (integer % 10));
4517                                                 /* RTW_INFO(" %d", integer ); */
4518
4519                                                 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4520                                                         szLine += u4bMove;
4521                                                 else
4522                                                         return _FAIL;
4523
4524                                                 integer *= 2;
4525                                                 if (fraction == 5)
4526                                                         integer += 1;
4527                                                 combineValue <<= 8;
4528                                                 combineValue |= (((integer / 10) << 4) + (integer % 10));
4529                                                 /* RTW_INFO(" %d", integer ); */
4530
4531                                                 if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4532                                                         szLine += u4bMove;
4533                                                 else
4534                                                         return _FAIL;
4535
4536                                                 integer *= 2;
4537                                                 if (fraction == 5)
4538                                                         integer += 1;
4539                                                 combineValue <<= 8;
4540                                                 combineValue |= (((integer / 10) << 4) + (integer % 10));
4541                                                 /* RTW_INFO(" %d", integer ); */
4542                                                 phy_store_tx_power_by_rate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue);
4543
4544                                                 /* RTW_INFO("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue ); */
4545                                         }
4546                                 }
4547                         } else if (pHalData->odmpriv.phy_reg_pg_version > 0) {
4548                                 u32     index = 0, cnt = 0;
4549
4550                                 if (eqNByte(szLine, "0xffff", 6))
4551                                         break;
4552
4553                                 if (!eqNByte("#[END]#", szLine, 7)) {
4554                                         /* load the table label info */
4555                                         if (szLine[0] == '#') {
4556                                                 index = 0;
4557                                                 if (eqNByte(szLine, "#[2.4G]" , 7)) {
4558                                                         band = BAND_ON_2_4G;
4559                                                         index += 8;
4560                                                 } else if (eqNByte(szLine, "#[5G]", 5)) {
4561                                                         band = BAND_ON_5G;
4562                                                         index += 6;
4563                                                 } else {
4564                                                         RTW_INFO("Invalid band %s in PHY_REG_PG.txt\n", szLine);
4565                                                         return _FAIL;
4566                                                 }
4567
4568                                                 rf_path = szLine[index] - 'A';
4569                                                 /* RTW_INFO(" Table label Band %d, RfPath %d\n", band, rf_path ); */
4570                                         } else { /* load rows of tables */
4571                                                 if (szLine[1] == '1')
4572                                                         tx_num = RF_1TX;
4573                                                 else if (szLine[1] == '2')
4574                                                         tx_num = RF_2TX;
4575                                                 else if (szLine[1] == '3')
4576                                                         tx_num = RF_3TX;
4577                                                 else if (szLine[1] == '4')
4578                                                         tx_num = RF_4TX;
4579                                                 else {
4580                                                         RTW_INFO("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
4581                                                         return _FAIL;
4582                                                 }
4583
4584                                                 while (szLine[index] != ']')
4585                                                         ++index;
4586                                                 ++index;/* skip ] */
4587
4588                                                 /* Get 2nd hex value as register offset. */
4589                                                 szLine += index;
4590                                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
4591                                                         szLine += u4bMove;
4592                                                 else
4593                                                         return _FAIL;
4594
4595                                                 /* Get 2nd hex value as register mask. */
4596                                                 if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
4597                                                         szLine += u4bMove;
4598                                                 else
4599                                                         return _FAIL;
4600
4601                                                 if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_RELATIVE_VALUE) {
4602                                                         /* Get 3rd hex value as register value. */
4603                                                         if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4604                                                                 phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue);
4605                                                                 /* RTW_INFO("[ADDR] %03X (tx_num %d) =%08X Mask=%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask); */
4606                                                         } else
4607                                                                 return _FAIL;
4608                                                 } else if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
4609                                                         u32     combineValue = 0;
4610                                                         u8      integer = 0, fraction = 0;
4611
4612                                                         if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4613                                                                 szLine += u4bMove;
4614                                                         else
4615                                                                 return _FAIL;
4616
4617                                                         integer *= 2;
4618                                                         if (fraction == 5)
4619                                                                 integer += 1;
4620                                                         combineValue |= (((integer / 10) << 4) + (integer % 10));
4621                                                         /* RTW_INFO(" %d", integer ); */
4622
4623                                                         if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4624                                                                 szLine += u4bMove;
4625                                                         else
4626                                                                 return _FAIL;
4627
4628                                                         integer *= 2;
4629                                                         if (fraction == 5)
4630                                                                 integer += 1;
4631                                                         combineValue <<= 8;
4632                                                         combineValue |= (((integer / 10) << 4) + (integer % 10));
4633                                                         /* RTW_INFO(" %d", integer ); */
4634
4635                                                         if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4636                                                                 szLine += u4bMove;
4637                                                         else
4638                                                                 return _FAIL;
4639
4640                                                         integer *= 2;
4641                                                         if (fraction == 5)
4642                                                                 integer += 1;
4643                                                         combineValue <<= 8;
4644                                                         combineValue |= (((integer / 10) << 4) + (integer % 10));
4645                                                         /* RTW_INFO(" %d", integer ); */
4646
4647                                                         if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
4648                                                                 szLine += u4bMove;
4649                                                         else
4650                                                                 return _FAIL;
4651
4652                                                         integer *= 2;
4653                                                         if (fraction == 5)
4654                                                                 integer += 1;
4655                                                         combineValue <<= 8;
4656                                                         combineValue |= (((integer / 10) << 4) + (integer % 10));
4657                                                         /* RTW_INFO(" %d", integer ); */
4658                                                         phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
4659
4660                                                         /* RTW_INFO("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue ); */
4661                                                 }
4662                                         }
4663                                 }
4664                         }
4665                 }
4666         }
4667         /* RTW_INFO("<=====phy_ParseBBPgParaFile()\n"); */
4668         return rtStatus;
4669 }
4670
4671 int
4672 phy_ConfigBBWithPgParaFile(
4673         IN      PADAPTER        Adapter,
4674         IN      const char      *pFileName)
4675 {
4676         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4677         int     rlen = 0, rtStatus = _FAIL;
4678
4679         if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
4680                 return rtStatus;
4681
4682         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4683
4684         if (pHalData->bb_phy_reg_pg == NULL) {
4685                 rtw_get_phy_file_path(Adapter, pFileName);
4686                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
4687                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4688                         if (rlen > 0) {
4689                                 rtStatus = _SUCCESS;
4690                                 pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
4691                                 if (pHalData->bb_phy_reg_pg) {
4692                                         _rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
4693                                         pHalData->bb_phy_reg_pg_len = rlen;
4694                                 } else
4695                                         RTW_INFO("%s bb_phy_reg_pg alloc fail !\n", __FUNCTION__);
4696                         }
4697                 }
4698         } else {
4699                 if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
4700                         _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
4701                         rtStatus = _SUCCESS;
4702                 } else
4703                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4704         }
4705
4706         if (rtStatus == _SUCCESS) {
4707                 /* RTW_INFO("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); */
4708                 phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
4709         } else
4710                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4711
4712         return rtStatus;
4713 }
4714
4715 #if (MP_DRIVER == 1)
4716
4717 int
4718 phy_ConfigBBWithMpParaFile(
4719         IN      PADAPTER        Adapter,
4720         IN      char            *pFileName
4721 )
4722 {
4723         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4724         int     rlen = 0, rtStatus = _FAIL;
4725         char    *szLine, *ptmp;
4726         u32     u4bRegOffset, u4bRegValue, u4bMove;
4727
4728         if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
4729                 return rtStatus;
4730
4731         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4732
4733         if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL)) {
4734                 rtw_get_phy_file_path(Adapter, pFileName);
4735                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
4736                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4737                         if (rlen > 0) {
4738                                 rtStatus = _SUCCESS;
4739                                 pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
4740                                 if (pHalData->bb_phy_reg_mp) {
4741                                         _rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
4742                                         pHalData->bb_phy_reg_mp_len = rlen;
4743                                 } else
4744                                         RTW_INFO("%s bb_phy_reg_mp alloc fail !\n", __FUNCTION__);
4745                         }
4746                 }
4747         } else {
4748                 if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
4749                         _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
4750                         rtStatus = _SUCCESS;
4751                 } else
4752                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4753         }
4754
4755         if (rtStatus == _SUCCESS) {
4756                 /* RTW_INFO("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName); */
4757
4758                 ptmp = pHalData->para_file_buf;
4759                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4760                         if (!IsCommentString(szLine)) {
4761                                 /* Get 1st hex value as register offset. */
4762                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4763                                         if (u4bRegOffset == 0xffff) {
4764                                                 /* Ending. */
4765                                                 break;
4766                                         } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4767 #ifdef CONFIG_LONG_DELAY_ISSUE
4768                                                 rtw_msleep_os(50);
4769 #else
4770                                                 rtw_mdelay_os(50);
4771 #endif
4772                                         } else if (u4bRegOffset == 0xfd)
4773                                                 rtw_mdelay_os(5);
4774                                         else if (u4bRegOffset == 0xfc)
4775                                                 rtw_mdelay_os(1);
4776                                         else if (u4bRegOffset == 0xfb)
4777                                                 rtw_udelay_os(50);
4778                                         else if (u4bRegOffset == 0xfa)
4779                                                 rtw_udelay_os(5);
4780                                         else if (u4bRegOffset == 0xf9)
4781                                                 rtw_udelay_os(1);
4782
4783                                         /* Get 2nd hex value as register value. */
4784                                         szLine += u4bMove;
4785                                         if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4786                                                 /* RTW_INFO("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
4787                                                 phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
4788
4789                                                 /* Add 1us delay between BB/RF register setting. */
4790                                                 rtw_udelay_os(1);
4791                                         }
4792                                 }
4793                         }
4794                 }
4795         } else
4796                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4797
4798         return rtStatus;
4799 }
4800
4801 #endif
4802
4803 int
4804 PHY_ConfigRFWithParaFile(
4805         IN      PADAPTER        Adapter,
4806         IN      char            *pFileName,
4807         IN      u8                      eRFPath
4808 )
4809 {
4810         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4811         int     rlen = 0, rtStatus = _FAIL;
4812         char    *szLine, *ptmp;
4813         u32     u4bRegOffset, u4bRegValue, u4bMove;
4814         u16     i;
4815         char    *pBuf = NULL;
4816         u32     *pBufLen = NULL;
4817
4818         if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
4819                 return rtStatus;
4820
4821         switch (eRFPath) {
4822         case ODM_RF_PATH_A:
4823                 pBuf = pHalData->rf_radio_a;
4824                 pBufLen = &pHalData->rf_radio_a_len;
4825                 break;
4826         case ODM_RF_PATH_B:
4827                 pBuf = pHalData->rf_radio_b;
4828                 pBufLen = &pHalData->rf_radio_b_len;
4829                 break;
4830         default:
4831                 RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
4832                 break;
4833         }
4834
4835         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
4836
4837         if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
4838                 rtw_get_phy_file_path(Adapter, pFileName);
4839                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
4840                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
4841                         if (rlen > 0) {
4842                                 rtStatus = _SUCCESS;
4843                                 pBuf = rtw_zvmalloc(rlen);
4844                                 if (pBuf) {
4845                                         _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
4846                                         *pBufLen = rlen;
4847
4848                                         switch (eRFPath) {
4849                                         case ODM_RF_PATH_A:
4850                                                 pHalData->rf_radio_a = pBuf;
4851                                                 break;
4852                                         case ODM_RF_PATH_B:
4853                                                 pHalData->rf_radio_b = pBuf;
4854                                                 break;
4855                                         }
4856                                 } else
4857                                         RTW_INFO("%s(): eRFPath=%d  alloc fail !\n", __FUNCTION__, eRFPath);
4858                         }
4859                 }
4860         } else {
4861                 if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
4862                         _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
4863                         rtStatus = _SUCCESS;
4864                 } else
4865                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
4866         }
4867
4868         if (rtStatus == _SUCCESS) {
4869                 /* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
4870
4871                 ptmp = pHalData->para_file_buf;
4872                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
4873                         if (!IsCommentString(szLine)) {
4874                                 /* Get 1st hex value as register offset. */
4875                                 if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
4876                                         if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
4877                                                 /* Deay specific ms. Only RF configuration require delay.                                                                                                */
4878 #ifdef CONFIG_LONG_DELAY_ISSUE
4879                                                 rtw_msleep_os(50);
4880 #else
4881                                                 rtw_mdelay_os(50);
4882 #endif
4883                                         } else if (u4bRegOffset == 0xfd) {
4884                                                 /* delay_ms(5); */
4885                                                 for (i = 0; i < 100; i++)
4886                                                         rtw_udelay_os(MAX_STALL_TIME);
4887                                         } else if (u4bRegOffset == 0xfc) {
4888                                                 /* delay_ms(1); */
4889                                                 for (i = 0; i < 20; i++)
4890                                                         rtw_udelay_os(MAX_STALL_TIME);
4891                                         } else if (u4bRegOffset == 0xfb)
4892                                                 rtw_udelay_os(50);
4893                                         else if (u4bRegOffset == 0xfa)
4894                                                 rtw_udelay_os(5);
4895                                         else if (u4bRegOffset == 0xf9)
4896                                                 rtw_udelay_os(1);
4897                                         else if (u4bRegOffset == 0xffff)
4898                                                 break;
4899
4900                                         /* Get 2nd hex value as register value. */
4901                                         szLine += u4bMove;
4902                                         if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
4903                                                 phy_set_rf_reg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
4904
4905                                                 /* Temp add, for frequency lock, if no delay, that may cause */
4906                                                 /* frequency shift, ex: 2412MHz => 2417MHz */
4907                                                 /* If frequency shift, the following action may works. */
4908                                                 /* Fractional-N table in radio_a.txt */
4909                                                 /* 0x2a 0x00001          */ /* channel 1 */
4910                                                 /* 0x2b 0x00808         frequency divider. */
4911                                                 /* 0x2b 0x53333 */
4912                                                 /* 0x2c 0x0000c */
4913                                                 rtw_udelay_os(1);
4914                                         }
4915                                 }
4916                         }
4917                 }
4918         } else
4919                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
4920
4921         return rtStatus;
4922 }
4923
4924 VOID
4925 initDeltaSwingIndexTables(
4926         PADAPTER        Adapter,
4927         char            *Band,
4928         char            *Path,
4929         char            *Sign,
4930         char            *Channel,
4931         char            *Rate,
4932         char            *Data
4933 )
4934 {
4935 #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
4936         ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
4937          (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
4938         )
4939 #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
4940         ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
4941          (strcmp(Rate, _rate) == 0)\
4942         )
4943
4944 #define STORE_SWING_TABLE(_array, _iteratedIdx) \
4945         do {    \
4946         for (token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim)) {\
4947                 sscanf(token, "%d", &idx);\
4948                 _array[_iteratedIdx++] = (u8)idx;\
4949         } } while (0)\
4950
4951         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4952         struct PHY_DM_STRUCT            *pDM_Odm = &pHalData->odmpriv;
4953         struct odm_rf_calibration_structure     *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
4954         u32     j = 0;
4955         char    *token;
4956         char    delim[] = ",";
4957         u32     idx = 0;
4958
4959         /* RTW_INFO("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n",  */
4960         /*      Band, Path, Sign, Channel, Rate, Data); */
4961
4962         if (STR_EQUAL_2G("2G", "A", "+", "CCK"))
4963                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p, j);
4964         else if (STR_EQUAL_2G("2G", "A", "-", "CCK"))
4965                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n, j);
4966         else if (STR_EQUAL_2G("2G", "B", "+", "CCK"))
4967                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p, j);
4968         else if (STR_EQUAL_2G("2G", "B", "-", "CCK"))
4969                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n, j);
4970         else if (STR_EQUAL_2G("2G", "A", "+", "ALL"))
4971                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_p, j);
4972         else if (STR_EQUAL_2G("2G", "A", "-", "ALL"))
4973                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_n, j);
4974         else if (STR_EQUAL_2G("2G", "B", "+", "ALL"))
4975                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_p, j);
4976         else if (STR_EQUAL_2G("2G", "B", "-", "ALL"))
4977                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_n, j);
4978         else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0"))
4979                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[0], j);
4980         else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0"))
4981                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[0], j);
4982         else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0"))
4983                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[0], j);
4984         else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0"))
4985                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[0], j);
4986         else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1"))
4987                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[1], j);
4988         else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1"))
4989                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[1], j);
4990         else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1"))
4991                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[1], j);
4992         else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1"))
4993                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[1], j);
4994         else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2"))
4995                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[2], j);
4996         else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2"))
4997                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[2], j);
4998         else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2"))
4999                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[2], j);
5000         else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2"))
5001                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[2], j);
5002         else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3"))
5003                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[3], j);
5004         else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3"))
5005                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[3], j);
5006         else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3"))
5007                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[3], j);
5008         else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3"))
5009                 STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[3], j);
5010         else
5011                 RTW_INFO("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
5012 }
5013
5014 int
5015 PHY_ConfigRFWithTxPwrTrackParaFile(
5016         IN      PADAPTER                Adapter,
5017         IN      char                    *pFileName
5018 )
5019 {
5020         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
5021         struct PHY_DM_STRUCT                    *pDM_Odm = &pHalData->odmpriv;
5022         struct odm_rf_calibration_structure             *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
5023         int     rlen = 0, rtStatus = _FAIL;
5024         char    *szLine, *ptmp;
5025         u32     i = 0, j = 0;
5026         char    c = 0;
5027
5028         if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
5029                 return rtStatus;
5030
5031         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5032
5033         if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) {
5034                 rtw_get_phy_file_path(Adapter, pFileName);
5035                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
5036                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5037                         if (rlen > 0) {
5038                                 rtStatus = _SUCCESS;
5039                                 pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
5040                                 if (pHalData->rf_tx_pwr_track) {
5041                                         _rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
5042                                         pHalData->rf_tx_pwr_track_len = rlen;
5043                                 } else
5044                                         RTW_INFO("%s rf_tx_pwr_track alloc fail !\n", __FUNCTION__);
5045                         }
5046                 }
5047         } else {
5048                 if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
5049                         _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5050                         rtStatus = _SUCCESS;
5051                 } else
5052                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5053         }
5054
5055         if (rtStatus == _SUCCESS) {
5056                 /* RTW_INFO("%s(): read %s successfully\n", __FUNCTION__, pFileName); */
5057
5058                 ptmp = pHalData->para_file_buf;
5059                 for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5060                         if (!IsCommentString(szLine)) {
5061                                 char    band[5] = "", path[5] = "", sign[5]  = "";
5062                                 char    chnl[5] = "", rate[10] = "";
5063                                 char    data[300] = ""; /* 100 is too small */
5064
5065                                 if (strlen(szLine) < 10 || szLine[0] != '[')
5066                                         continue;
5067
5068                                 strncpy(band, szLine + 1, 2);
5069                                 strncpy(path, szLine + 5, 1);
5070                                 strncpy(sign, szLine + 8, 1);
5071
5072                                 i = 10; /* szLine+10 */
5073                                 if (!ParseQualifiedString(szLine, &i, rate, '[', ']')) {
5074                                         /* RTW_INFO("Fail to parse rate!\n"); */
5075                                 }
5076                                 if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
5077                                         /* RTW_INFO("Fail to parse channel group!\n"); */
5078                                 }
5079                                 while (szLine[i] != '{' && i < strlen(szLine))
5080                                         i++;
5081                                 if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
5082                                         /* RTW_INFO("Fail to parse data!\n"); */
5083                                 }
5084
5085                                 initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
5086                         }
5087                 }
5088         } else
5089                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5090 #if 0
5091         for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i) {
5092                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_p[i]);
5093                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2ga_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2ga_n[i]);
5094                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_p[i]);
5095                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2gb_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2gb_n[i]);
5096                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p[i]);
5097                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n[i]);
5098                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p[i]);
5099                 RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n[%d] = %d\n", i, pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n[i]);
5100
5101                 for (j = 0; j < 3; ++j) {
5102                         RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_p[j][i]);
5103                         RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5ga_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5ga_n[j][i]);
5104                         RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_p[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_p[j][i]);
5105                         RTW_INFO("pRFCalibrateInfo->delta_swing_table_idx_5gb_n[%d][%d] = %d\n", j, i, pRFCalibrateInfo->delta_swing_table_idx_5gb_n[j][i]);
5106                 }
5107         }
5108 #endif
5109         return rtStatus;
5110 }
5111
5112 int
5113 phy_ParsePowerLimitTableFile(
5114         PADAPTER                Adapter,
5115         char                    *buffer
5116 )
5117 {
5118         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
5119         struct PHY_DM_STRUCT    *pDM_Odm = &(pHalData->odmpriv);
5120         u32     i = 0, forCnt = 0;
5121         u8      loadingStage = 0, limitValue = 0, fraction = 0;
5122         char    *szLine, *ptmp;
5123         int     rtStatus = _SUCCESS;
5124         char band[10], bandwidth[10], rateSection[10],
5125              regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10], colNumBuf[10];
5126         u8      colNum = 0;
5127
5128         RTW_INFO("===>phy_ParsePowerLimitTableFile()\n");
5129
5130         if (Adapter->registrypriv.RegDecryptCustomFile == 1)
5131                 phy_DecryptBBPgParaFile(Adapter, buffer);
5132
5133         ptmp = buffer;
5134         for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
5135                 if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
5136                         continue;
5137
5138                 /* skip comment */
5139                 if (IsCommentString(szLine))
5140                         continue;
5141
5142                 if (loadingStage == 0) {
5143                         for (forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt)
5144                                 _rtw_memset((PVOID) regulation[forCnt], 0, 10);
5145                         _rtw_memset((PVOID) band, 0, 10);
5146                         _rtw_memset((PVOID) bandwidth, 0, 10);
5147                         _rtw_memset((PVOID) rateSection, 0, 10);
5148                         _rtw_memset((PVOID) rfPath, 0, 10);
5149                         _rtw_memset((PVOID) colNumBuf, 0, 10);
5150
5151                         if (szLine[0] != '#' || szLine[1] != '#')
5152                                 continue;
5153
5154                         /* skip the space */
5155                         i = 2;
5156                         while (szLine[i] == ' ' || szLine[i] == '\t')
5157                                 ++i;
5158
5159                         szLine[--i] = ' '; /* return the space in front of the regulation info */
5160
5161                         /* Parse the label of the table */
5162                         if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) {
5163                                 RTW_INFO("Fail to parse band!\n");
5164                                 return _FAIL;
5165                         }
5166                         if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) {
5167                                 RTW_INFO("Fail to parse bandwidth!\n");
5168                                 return _FAIL;
5169                         }
5170                         if (!ParseQualifiedString(szLine, &i, rfPath, ' ', ',')) {
5171                                 RTW_INFO("Fail to parse rf path!\n");
5172                                 return _FAIL;
5173                         }
5174                         if (!ParseQualifiedString(szLine, &i, rateSection, ' ', ',')) {
5175                                 RTW_INFO("Fail to parse rate!\n");
5176                                 return _FAIL;
5177                         }
5178
5179                         loadingStage = 1;
5180                 } else if (loadingStage == 1) {
5181                         if (szLine[0] != '#' || szLine[1] != '#')
5182                                 continue;
5183
5184                         /* skip the space */
5185                         i = 2;
5186                         while (szLine[i] == ' ' || szLine[i] == '\t')
5187                                 ++i;
5188
5189                         if (!eqNByte((u8 *)(szLine + i), (u8 *)("START"), 5)) {
5190                                 RTW_INFO("Lost \"##   START\" label\n");
5191                                 return _FAIL;
5192                         }
5193
5194                         loadingStage = 2;
5195                 } else if (loadingStage == 2) {
5196                         if (szLine[0] != '#' || szLine[1] != '#')
5197                                 continue;
5198
5199                         /* skip the space */
5200                         i = 2;
5201                         while (szLine[i] == ' ' || szLine[i] == '\t')
5202                                 ++i;
5203
5204                         if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) {
5205                                 RTW_INFO("Fail to parse column number!\n");
5206                                 return _FAIL;
5207                         }
5208
5209                         if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum))
5210                                 return _FAIL;
5211
5212                         if (colNum > TXPWR_LMT_MAX_REGULATION_NUM) {
5213                                 RTW_INFO("unvalid col number %d (greater than max %d)\n",
5214                                          colNum, TXPWR_LMT_MAX_REGULATION_NUM);
5215                                 return _FAIL;
5216                         }
5217
5218                         for (forCnt = 0; forCnt < colNum; ++forCnt) {
5219                                 u8      regulation_name_cnt = 0;
5220
5221                                 /* skip the space */
5222                                 while (szLine[i] == ' ' || szLine[i] == '\t')
5223                                         ++i;
5224
5225                                 while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
5226                                         regulation[forCnt][regulation_name_cnt++] = szLine[i++];
5227                                 /* RTW_INFO("regulation %s!\n", regulation[forCnt]); */
5228
5229                                 if (regulation_name_cnt == 0) {
5230                                         RTW_INFO("unvalid number of regulation!\n");
5231                                         return _FAIL;
5232                                 }
5233                         }
5234
5235                         loadingStage = 3;
5236                 } else if (loadingStage == 3) {
5237                         char    channel[10] = {0}, powerLimit[10] = {0};
5238                         u8      cnt = 0;
5239
5240                         /* the table ends */
5241                         if (szLine[0] == '#' && szLine[1] == '#') {
5242                                 i = 2;
5243                                 while (szLine[i] == ' ' || szLine[i] == '\t')
5244                                         ++i;
5245
5246                                 if (eqNByte((u8 *)(szLine + i), (u8 *)("END"), 3)) {
5247                                         loadingStage = 0;
5248                                         continue;
5249                                 } else {
5250                                         RTW_INFO("Wrong format\n");
5251                                         RTW_INFO("<===== phy_ParsePowerLimitTableFile()\n");
5252                                         return _FAIL;
5253                                 }
5254                         }
5255
5256                         if ((szLine[0] != 'c' && szLine[0] != 'C') ||
5257                             (szLine[1] != 'h' && szLine[1] != 'H')) {
5258                                 RTW_INFO("Meet wrong channel => power limt pair '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
5259                                 continue;
5260                         }
5261                         i = 2;/* move to the  location behind 'h' */
5262
5263                         /* load the channel number */
5264                         cnt = 0;
5265                         while (szLine[i] >= '0' && szLine[i] <= '9') {
5266                                 channel[cnt] = szLine[i];
5267                                 ++cnt;
5268                                 ++i;
5269                         }
5270                         /* RTW_INFO("chnl %s!\n", channel); */
5271
5272                         for (forCnt = 0; forCnt < colNum; ++forCnt) {
5273                                 /* skip the space between channel number and the power limit value */
5274                                 while (szLine[i] == ' ' || szLine[i] == '\t')
5275                                         ++i;
5276
5277                                 /* load the power limit value */
5278                                 cnt = 0;
5279                                 fraction = 0;
5280                                 _rtw_memset((PVOID) powerLimit, 0, 10);
5281                                 while ((szLine[i] >= '0' && szLine[i] <= '9') || szLine[i] == '.') {
5282                                         if (szLine[i] == '.') {
5283                                                 if ((szLine[i + 1] >= '0' && szLine[i + 1] <= '9')) {
5284                                                         fraction = szLine[i + 1];
5285                                                         i += 2;
5286                                                 } else {
5287                                                         RTW_INFO("Wrong fraction in TXPWR_LMT.txt\n");
5288                                                         return _FAIL;
5289                                                 }
5290
5291                                                 break;
5292                                         }
5293
5294                                         powerLimit[cnt] = szLine[i];
5295                                         ++cnt;
5296                                         ++i;
5297                                 }
5298
5299                                 if (powerLimit[0] == '\0') {
5300                                         powerLimit[0] = '6';
5301                                         powerLimit[1] = '3';
5302                                         i += 2;
5303                                 } else {
5304                                         if (!GetU1ByteIntegerFromStringInDecimal(powerLimit, &limitValue))
5305                                                 return _FAIL;
5306
5307                                         limitValue *= 2;
5308                                         cnt = 0;
5309                                         if (fraction == '5')
5310                                                 ++limitValue;
5311
5312                                         /* the value is greater or equal to 100 */
5313                                         if (limitValue >= 100) {
5314                                                 powerLimit[cnt++] = limitValue / 100 + '0';
5315                                                 limitValue %= 100;
5316
5317                                                 if (limitValue >= 10) {
5318                                                         powerLimit[cnt++] = limitValue / 10 + '0';
5319                                                         limitValue %= 10;
5320                                                 } else
5321                                                         powerLimit[cnt++] = '0';
5322
5323                                                 powerLimit[cnt++] = limitValue + '0';
5324                                         }
5325                                         /* the value is greater or equal to 10 */
5326                                         else if (limitValue >= 10) {
5327                                                 powerLimit[cnt++] = limitValue / 10 + '0';
5328                                                 limitValue %= 10;
5329                                                 powerLimit[cnt++] = limitValue + '0';
5330                                         }
5331                                         /* the value is less than 10 */
5332                                         else
5333                                                 powerLimit[cnt++] = limitValue + '0';
5334
5335                                         powerLimit[cnt] = '\0';
5336                                 }
5337
5338                                 /* RTW_INFO("ch%s => %s\n", channel, powerLimit); */
5339
5340                                 /* store the power limit value */
5341                                 phy_set_tx_power_limit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
5342                                         (u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit);
5343
5344                         }
5345                 } else {
5346                         RTW_INFO("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n");
5347                         rtStatus = _FAIL;
5348                         break;
5349                 }
5350         }
5351
5352         RTW_INFO("<===phy_ParsePowerLimitTableFile()\n");
5353         return rtStatus;
5354 }
5355
5356 int
5357 PHY_ConfigRFWithPowerLimitTableParaFile(
5358         IN      PADAPTER        Adapter,
5359         IN      const char      *pFileName
5360 )
5361 {
5362         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
5363         int     rlen = 0, rtStatus = _FAIL;
5364
5365         if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
5366                 return rtStatus;
5367
5368         _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
5369
5370         if (pHalData->rf_tx_pwr_lmt == NULL) {
5371                 rtw_get_phy_file_path(Adapter, pFileName);
5372                 if (rtw_is_file_readable(rtw_phy_para_file_path) == _TRUE) {
5373                         rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
5374                         if (rlen > 0) {
5375                                 rtStatus = _SUCCESS;
5376                                 pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
5377                                 if (pHalData->rf_tx_pwr_lmt) {
5378                                         _rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
5379                                         pHalData->rf_tx_pwr_lmt_len = rlen;
5380                                 } else
5381                                         RTW_INFO("%s rf_tx_pwr_lmt alloc fail !\n", __FUNCTION__);
5382                         }
5383                 }
5384         } else {
5385                 if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
5386                         _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5387                         rtStatus = _SUCCESS;
5388                 } else
5389                         RTW_INFO("%s(): Critical Error !!!\n", __FUNCTION__);
5390         }
5391
5392         if (rtStatus == _SUCCESS) {
5393                 /* RTW_INFO("%s(): read %s ok\n", __FUNCTION__, pFileName); */
5394                 rtStatus = phy_ParsePowerLimitTableFile(Adapter, pHalData->para_file_buf);
5395         } else
5396                 RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
5397
5398         return rtStatus;
5399 }
5400
5401 void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
5402 {
5403         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5404
5405         if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
5406                 rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
5407                 pHalData->mac_reg = NULL;
5408         }
5409         if (mask & LOAD_BB_PARA_FILE) {
5410                 if (pHalData->bb_phy_reg) {
5411                         rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
5412                         pHalData->bb_phy_reg = NULL;
5413                 }
5414                 if (pHalData->bb_agc_tab) {
5415                         rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
5416                         pHalData->bb_agc_tab = NULL;
5417                 }
5418         }
5419         if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
5420                 rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
5421                 pHalData->bb_phy_reg_pg = NULL;
5422         }
5423         if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
5424                 rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
5425                 pHalData->bb_phy_reg_mp = NULL;
5426         }
5427         if (mask & LOAD_RF_PARA_FILE) {
5428                 if (pHalData->rf_radio_a) {
5429                         rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
5430                         pHalData->rf_radio_a = NULL;
5431                 }
5432                 if (pHalData->rf_radio_b) {
5433                         rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
5434                         pHalData->rf_radio_b = NULL;
5435                 }
5436         }
5437         if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
5438                 rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
5439                 pHalData->rf_tx_pwr_track = NULL;
5440         }
5441         if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
5442                 rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
5443                 pHalData->rf_tx_pwr_lmt = NULL;
5444         }
5445 }
5446
5447 inline void phy_free_filebuf(_adapter *padapter)
5448 {
5449         phy_free_filebuf_mask(padapter, 0xFF);
5450 }
5451
5452 #endif