xref: /openbmc/linux/drivers/net/wireless/ti/wl12xx/cmd.c (revision 9d68d1ee)
1 /*
2  * This file is part of wl12xx
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation
5  * Copyright (C) 2011 Texas Instruments Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA
20  *
21  */
22 
23 #include "../wlcore/cmd.h"
24 #include "../wlcore/debug.h"
25 
26 #include "cmd.h"
27 
28 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
29 {
30 	struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
31 	struct conf_rf_settings *rf = &wl->conf.rf;
32 	int ret;
33 
34 	if (!wl->nvs)
35 		return -ENODEV;
36 
37 	ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
38 	if (!ext_radio_parms)
39 		return -ENOMEM;
40 
41 	ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
42 
43 	memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
44 	       rf->tx_per_channel_power_compensation_2,
45 	       CONF_TX_PWR_COMPENSATION_LEN_2);
46 	memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
47 	       rf->tx_per_channel_power_compensation_5,
48 	       CONF_TX_PWR_COMPENSATION_LEN_5);
49 
50 	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
51 		    ext_radio_parms, sizeof(*ext_radio_parms));
52 
53 	ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
54 	if (ret < 0)
55 		wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
56 
57 	kfree(ext_radio_parms);
58 	return ret;
59 }
60 
61 int wl1271_cmd_general_parms(struct wl1271 *wl)
62 {
63 	struct wl1271_general_parms_cmd *gen_parms;
64 	struct wl1271_ini_general_params *gp =
65 		&((struct wl1271_nvs_file *)wl->nvs)->general_params;
66 	bool answer = false;
67 	int ret;
68 
69 	if (!wl->nvs)
70 		return -ENODEV;
71 
72 	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
73 		wl1271_warning("FEM index from INI out of bounds");
74 		return -EINVAL;
75 	}
76 
77 	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
78 	if (!gen_parms)
79 		return -ENOMEM;
80 
81 	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
82 
83 	memcpy(&gen_parms->general_params, gp, sizeof(*gp));
84 
85 	if (gp->tx_bip_fem_auto_detect)
86 		answer = true;
87 
88 	/* Override the REF CLK from the NVS with the one from platform data */
89 	gen_parms->general_params.ref_clock = wl->ref_clock;
90 
91 	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
92 	if (ret < 0) {
93 		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
94 		goto out;
95 	}
96 
97 	gp->tx_bip_fem_manufacturer =
98 		gen_parms->general_params.tx_bip_fem_manufacturer;
99 
100 	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
101 		wl1271_warning("FEM index from FW out of bounds");
102 		ret = -EINVAL;
103 		goto out;
104 	}
105 
106 	wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
107 		     answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
108 
109 out:
110 	kfree(gen_parms);
111 	return ret;
112 }
113 
114 int wl128x_cmd_general_parms(struct wl1271 *wl)
115 {
116 	struct wl128x_general_parms_cmd *gen_parms;
117 	struct wl128x_ini_general_params *gp =
118 		&((struct wl128x_nvs_file *)wl->nvs)->general_params;
119 	bool answer = false;
120 	int ret;
121 
122 	if (!wl->nvs)
123 		return -ENODEV;
124 
125 	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
126 		wl1271_warning("FEM index from ini out of bounds");
127 		return -EINVAL;
128 	}
129 
130 	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
131 	if (!gen_parms)
132 		return -ENOMEM;
133 
134 	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
135 
136 	memcpy(&gen_parms->general_params, gp, sizeof(*gp));
137 
138 	if (gp->tx_bip_fem_auto_detect)
139 		answer = true;
140 
141 	/* Replace REF and TCXO CLKs with the ones from platform data */
142 	gen_parms->general_params.ref_clock = wl->ref_clock;
143 	gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
144 
145 	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
146 	if (ret < 0) {
147 		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
148 		goto out;
149 	}
150 
151 	gp->tx_bip_fem_manufacturer =
152 		gen_parms->general_params.tx_bip_fem_manufacturer;
153 
154 	if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
155 		wl1271_warning("FEM index from FW out of bounds");
156 		ret = -EINVAL;
157 		goto out;
158 	}
159 
160 	wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
161 		     answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
162 
163 out:
164 	kfree(gen_parms);
165 	return ret;
166 }
167 
168 int wl1271_cmd_radio_parms(struct wl1271 *wl)
169 {
170 	struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
171 	struct wl1271_radio_parms_cmd *radio_parms;
172 	struct wl1271_ini_general_params *gp = &nvs->general_params;
173 	int ret;
174 
175 	if (!wl->nvs)
176 		return -ENODEV;
177 
178 	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
179 	if (!radio_parms)
180 		return -ENOMEM;
181 
182 	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
183 
184 	/* 2.4GHz parameters */
185 	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
186 	       sizeof(struct wl1271_ini_band_params_2));
187 	memcpy(&radio_parms->dyn_params_2,
188 	       &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
189 	       sizeof(struct wl1271_ini_fem_params_2));
190 
191 	/* 5GHz parameters */
192 	memcpy(&radio_parms->static_params_5,
193 	       &nvs->stat_radio_params_5,
194 	       sizeof(struct wl1271_ini_band_params_5));
195 	memcpy(&radio_parms->dyn_params_5,
196 	       &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
197 	       sizeof(struct wl1271_ini_fem_params_5));
198 
199 	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
200 		    radio_parms, sizeof(*radio_parms));
201 
202 	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
203 	if (ret < 0)
204 		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
205 
206 	kfree(radio_parms);
207 	return ret;
208 }
209 
210 int wl128x_cmd_radio_parms(struct wl1271 *wl)
211 {
212 	struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
213 	struct wl128x_radio_parms_cmd *radio_parms;
214 	struct wl128x_ini_general_params *gp = &nvs->general_params;
215 	int ret;
216 
217 	if (!wl->nvs)
218 		return -ENODEV;
219 
220 	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
221 	if (!radio_parms)
222 		return -ENOMEM;
223 
224 	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
225 
226 	/* 2.4GHz parameters */
227 	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
228 	       sizeof(struct wl128x_ini_band_params_2));
229 	memcpy(&radio_parms->dyn_params_2,
230 	       &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
231 	       sizeof(struct wl128x_ini_fem_params_2));
232 
233 	/* 5GHz parameters */
234 	memcpy(&radio_parms->static_params_5,
235 	       &nvs->stat_radio_params_5,
236 	       sizeof(struct wl128x_ini_band_params_5));
237 	memcpy(&radio_parms->dyn_params_5,
238 	       &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
239 	       sizeof(struct wl128x_ini_fem_params_5));
240 
241 	radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
242 
243 	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
244 		    radio_parms, sizeof(*radio_parms));
245 
246 	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
247 	if (ret < 0)
248 		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
249 
250 	kfree(radio_parms);
251 	return ret;
252 }
253