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