1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of wl12xx
5 * Copyright (C) 2009-2010 Nokia Corporation
6 * Copyright (C) 2011 Texas Instruments Inc.
9 #include "../wlcore/cmd.h"
10 #include "../wlcore/debug.h"
15 int wl1271_cmd_ext_radio_parms(struct wl1271
*wl
)
17 struct wl1271_ext_radio_parms_cmd
*ext_radio_parms
;
18 struct wl12xx_priv
*priv
= wl
->priv
;
19 struct wl12xx_conf_rf
*rf
= &priv
->conf
.rf
;
25 ext_radio_parms
= kzalloc(sizeof(*ext_radio_parms
), GFP_KERNEL
);
29 ext_radio_parms
->test
.id
= TEST_CMD_INI_FILE_RF_EXTENDED_PARAM
;
31 memcpy(ext_radio_parms
->tx_per_channel_power_compensation_2
,
32 rf
->tx_per_channel_power_compensation_2
,
33 CONF_TX_PWR_COMPENSATION_LEN_2
);
34 memcpy(ext_radio_parms
->tx_per_channel_power_compensation_5
,
35 rf
->tx_per_channel_power_compensation_5
,
36 CONF_TX_PWR_COMPENSATION_LEN_5
);
38 wl1271_dump(DEBUG_CMD
, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
39 ext_radio_parms
, sizeof(*ext_radio_parms
));
41 ret
= wl1271_cmd_test(wl
, ext_radio_parms
, sizeof(*ext_radio_parms
), 0);
43 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
45 kfree(ext_radio_parms
);
49 int wl1271_cmd_general_parms(struct wl1271
*wl
)
51 struct wl1271_general_parms_cmd
*gen_parms
;
52 struct wl1271_ini_general_params
*gp
=
53 &((struct wl1271_nvs_file
*)wl
->nvs
)->general_params
;
54 struct wl12xx_priv
*priv
= wl
->priv
;
61 if (gp
->tx_bip_fem_manufacturer
>= WL1271_INI_FEM_MODULE_COUNT
) {
62 wl1271_warning("FEM index from INI out of bounds");
66 gen_parms
= kzalloc(sizeof(*gen_parms
), GFP_KERNEL
);
70 gen_parms
->test
.id
= TEST_CMD_INI_FILE_GENERAL_PARAM
;
72 memcpy(&gen_parms
->general_params
, gp
, sizeof(*gp
));
74 /* If we started in PLT FEM_DETECT mode, force auto detect */
75 if (wl
->plt_mode
== PLT_FEM_DETECT
)
76 gen_parms
->general_params
.tx_bip_fem_auto_detect
= true;
78 if (gen_parms
->general_params
.tx_bip_fem_auto_detect
)
81 /* Override the REF CLK from the NVS with the one from platform data */
82 gen_parms
->general_params
.ref_clock
= priv
->ref_clock
;
84 ret
= wl1271_cmd_test(wl
, gen_parms
, sizeof(*gen_parms
), answer
);
86 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
90 gp
->tx_bip_fem_manufacturer
=
91 gen_parms
->general_params
.tx_bip_fem_manufacturer
;
93 if (gp
->tx_bip_fem_manufacturer
>= WL1271_INI_FEM_MODULE_COUNT
) {
94 wl1271_warning("FEM index from FW out of bounds");
99 /* If we are in calibrator based fem auto detect - save fem nr */
100 if (wl
->plt_mode
== PLT_FEM_DETECT
)
101 wl
->fem_manuf
= gp
->tx_bip_fem_manufacturer
;
103 wl1271_debug(DEBUG_CMD
, "FEM autodetect: %s, manufacturer: %d\n",
106 wl
->plt_mode
== PLT_FEM_DETECT
?
107 "calibrator_fem_detect" :
109 gp
->tx_bip_fem_manufacturer
);
116 int wl128x_cmd_general_parms(struct wl1271
*wl
)
118 struct wl128x_general_parms_cmd
*gen_parms
;
119 struct wl128x_ini_general_params
*gp
=
120 &((struct wl128x_nvs_file
*)wl
->nvs
)->general_params
;
121 struct wl12xx_priv
*priv
= wl
->priv
;
128 if (gp
->tx_bip_fem_manufacturer
>= WL1271_INI_FEM_MODULE_COUNT
) {
129 wl1271_warning("FEM index from ini out of bounds");
133 gen_parms
= kzalloc(sizeof(*gen_parms
), GFP_KERNEL
);
137 gen_parms
->test
.id
= TEST_CMD_INI_FILE_GENERAL_PARAM
;
139 memcpy(&gen_parms
->general_params
, gp
, sizeof(*gp
));
141 /* If we started in PLT FEM_DETECT mode, force auto detect */
142 if (wl
->plt_mode
== PLT_FEM_DETECT
)
143 gen_parms
->general_params
.tx_bip_fem_auto_detect
= true;
145 if (gen_parms
->general_params
.tx_bip_fem_auto_detect
)
148 /* Replace REF and TCXO CLKs with the ones from platform data */
149 gen_parms
->general_params
.ref_clock
= priv
->ref_clock
;
150 gen_parms
->general_params
.tcxo_ref_clock
= priv
->tcxo_clock
;
152 ret
= wl1271_cmd_test(wl
, gen_parms
, sizeof(*gen_parms
), answer
);
154 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
158 gp
->tx_bip_fem_manufacturer
=
159 gen_parms
->general_params
.tx_bip_fem_manufacturer
;
161 if (gp
->tx_bip_fem_manufacturer
>= WL1271_INI_FEM_MODULE_COUNT
) {
162 wl1271_warning("FEM index from FW out of bounds");
167 /* If we are in calibrator based fem auto detect - save fem nr */
168 if (wl
->plt_mode
== PLT_FEM_DETECT
)
169 wl
->fem_manuf
= gp
->tx_bip_fem_manufacturer
;
171 wl1271_debug(DEBUG_CMD
, "FEM autodetect: %s, manufacturer: %d\n",
174 wl
->plt_mode
== PLT_FEM_DETECT
?
175 "calibrator_fem_detect" :
177 gp
->tx_bip_fem_manufacturer
);
184 int wl1271_cmd_radio_parms(struct wl1271
*wl
)
186 struct wl1271_nvs_file
*nvs
= (struct wl1271_nvs_file
*)wl
->nvs
;
187 struct wl1271_radio_parms_cmd
*radio_parms
;
188 struct wl1271_ini_general_params
*gp
= &nvs
->general_params
;
194 radio_parms
= kzalloc(sizeof(*radio_parms
), GFP_KERNEL
);
198 radio_parms
->test
.id
= TEST_CMD_INI_FILE_RADIO_PARAM
;
200 fem_idx
= WL12XX_FEM_TO_NVS_ENTRY(gp
->tx_bip_fem_manufacturer
);
202 /* 2.4GHz parameters */
203 memcpy(&radio_parms
->static_params_2
, &nvs
->stat_radio_params_2
,
204 sizeof(struct wl1271_ini_band_params_2
));
205 memcpy(&radio_parms
->dyn_params_2
,
206 &nvs
->dyn_radio_params_2
[fem_idx
].params
,
207 sizeof(struct wl1271_ini_fem_params_2
));
209 /* 5GHz parameters */
210 memcpy(&radio_parms
->static_params_5
,
211 &nvs
->stat_radio_params_5
,
212 sizeof(struct wl1271_ini_band_params_5
));
213 memcpy(&radio_parms
->dyn_params_5
,
214 &nvs
->dyn_radio_params_5
[fem_idx
].params
,
215 sizeof(struct wl1271_ini_fem_params_5
));
217 wl1271_dump(DEBUG_CMD
, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
218 radio_parms
, sizeof(*radio_parms
));
220 ret
= wl1271_cmd_test(wl
, radio_parms
, sizeof(*radio_parms
), 0);
222 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
228 int wl128x_cmd_radio_parms(struct wl1271
*wl
)
230 struct wl128x_nvs_file
*nvs
= (struct wl128x_nvs_file
*)wl
->nvs
;
231 struct wl128x_radio_parms_cmd
*radio_parms
;
232 struct wl128x_ini_general_params
*gp
= &nvs
->general_params
;
238 radio_parms
= kzalloc(sizeof(*radio_parms
), GFP_KERNEL
);
242 radio_parms
->test
.id
= TEST_CMD_INI_FILE_RADIO_PARAM
;
244 fem_idx
= WL12XX_FEM_TO_NVS_ENTRY(gp
->tx_bip_fem_manufacturer
);
246 /* 2.4GHz parameters */
247 memcpy(&radio_parms
->static_params_2
, &nvs
->stat_radio_params_2
,
248 sizeof(struct wl128x_ini_band_params_2
));
249 memcpy(&radio_parms
->dyn_params_2
,
250 &nvs
->dyn_radio_params_2
[fem_idx
].params
,
251 sizeof(struct wl128x_ini_fem_params_2
));
253 /* 5GHz parameters */
254 memcpy(&radio_parms
->static_params_5
,
255 &nvs
->stat_radio_params_5
,
256 sizeof(struct wl128x_ini_band_params_5
));
257 memcpy(&radio_parms
->dyn_params_5
,
258 &nvs
->dyn_radio_params_5
[fem_idx
].params
,
259 sizeof(struct wl128x_ini_fem_params_5
));
261 radio_parms
->fem_vendor_and_options
= nvs
->fem_vendor_and_options
;
263 wl1271_dump(DEBUG_CMD
, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
264 radio_parms
, sizeof(*radio_parms
));
266 ret
= wl1271_cmd_test(wl
, radio_parms
, sizeof(*radio_parms
), 0);
268 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
274 int wl12xx_cmd_channel_switch(struct wl1271
*wl
,
275 struct wl12xx_vif
*wlvif
,
276 struct ieee80211_channel_switch
*ch_switch
)
278 struct wl12xx_cmd_channel_switch
*cmd
;
281 wl1271_debug(DEBUG_ACX
, "cmd channel switch");
283 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
289 cmd
->role_id
= wlvif
->role_id
;
290 cmd
->channel
= ch_switch
->chandef
.chan
->hw_value
;
291 cmd
->switch_time
= ch_switch
->count
;
292 cmd
->stop_tx
= ch_switch
->block_tx
;
294 /* FIXME: control from mac80211 in the future */
295 /* Enable TX on the target channel */
296 cmd
->post_switch_tx_disable
= 0;
298 ret
= wl1271_cmd_send(wl
, CMD_CHANNEL_SWITCH
, cmd
, sizeof(*cmd
), 0);
300 wl1271_error("failed to send channel switch command");