xref: /linux/drivers/net/wireless/ti/wl1251/init.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * This file is part of wl1251
4  *
5  * Copyright (C) 2009 Nokia Corporation
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 
12 #include "init.h"
13 #include "wl12xx_80211.h"
14 #include "acx.h"
15 #include "cmd.h"
16 #include "reg.h"
17 
18 int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
19 {
20 	int ret;
21 
22 	ret = wl1251_acx_feature_cfg(wl, 0);
23 	if (ret < 0) {
24 		wl1251_warning("couldn't set feature config");
25 		return ret;
26 	}
27 
28 	ret = wl1251_acx_default_key(wl, wl->default_key);
29 	if (ret < 0) {
30 		wl1251_warning("couldn't set default key");
31 		return ret;
32 	}
33 
34 	return 0;
35 }
36 
37 int wl1251_hw_init_templates_config(struct wl1251 *wl)
38 {
39 	int ret;
40 	u8 partial_vbm[PARTIAL_VBM_MAX];
41 
42 	/* send empty templates for fw memory reservation */
43 	ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
44 				      sizeof(struct wl12xx_probe_req_template));
45 	if (ret < 0)
46 		return ret;
47 
48 	ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
49 				      sizeof(struct wl12xx_null_data_template));
50 	if (ret < 0)
51 		return ret;
52 
53 	ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
54 				      sizeof(struct wl12xx_ps_poll_template));
55 	if (ret < 0)
56 		return ret;
57 
58 	ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
59 				      sizeof
60 				      (struct wl12xx_qos_null_data_template));
61 	if (ret < 0)
62 		return ret;
63 
64 	ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
65 				      sizeof
66 				      (struct wl12xx_probe_resp_template));
67 	if (ret < 0)
68 		return ret;
69 
70 	ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
71 				      sizeof
72 				      (struct wl12xx_beacon_template));
73 	if (ret < 0)
74 		return ret;
75 
76 	/* tim templates, first reserve space then allocate an empty one */
77 	memset(partial_vbm, 0, PARTIAL_VBM_MAX);
78 	ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
79 	if (ret < 0)
80 		return ret;
81 
82 	ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
83 	if (ret < 0)
84 		return ret;
85 
86 	return 0;
87 }
88 
89 int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
90 {
91 	int ret;
92 
93 	ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
94 	if (ret < 0)
95 		return ret;
96 
97 	ret = wl1251_acx_rx_config(wl, config, filter);
98 	if (ret < 0)
99 		return ret;
100 
101 	return 0;
102 }
103 
104 int wl1251_hw_init_phy_config(struct wl1251 *wl)
105 {
106 	int ret;
107 
108 	ret = wl1251_acx_pd_threshold(wl);
109 	if (ret < 0)
110 		return ret;
111 
112 	ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
113 	if (ret < 0)
114 		return ret;
115 
116 	ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0);
117 	if (ret < 0)
118 		return ret;
119 
120 	ret = wl1251_acx_service_period_timeout(wl);
121 	if (ret < 0)
122 		return ret;
123 
124 	ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
125 	if (ret < 0)
126 		return ret;
127 
128 	return 0;
129 }
130 
131 int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
132 {
133 	int ret;
134 
135 	/* disable beacon filtering at this stage */
136 	ret = wl1251_acx_beacon_filter_opt(wl, false);
137 	if (ret < 0)
138 		return ret;
139 
140 	ret = wl1251_acx_beacon_filter_table(wl);
141 	if (ret < 0)
142 		return ret;
143 
144 	return 0;
145 }
146 
147 int wl1251_hw_init_pta(struct wl1251 *wl)
148 {
149 	int ret;
150 
151 	ret = wl1251_acx_sg_enable(wl);
152 	if (ret < 0)
153 		return ret;
154 
155 	ret = wl1251_acx_sg_cfg(wl);
156 	if (ret < 0)
157 		return ret;
158 
159 	return 0;
160 }
161 
162 int wl1251_hw_init_energy_detection(struct wl1251 *wl)
163 {
164 	int ret;
165 
166 	ret = wl1251_acx_cca_threshold(wl);
167 	if (ret < 0)
168 		return ret;
169 
170 	return 0;
171 }
172 
173 int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
174 {
175 	int ret;
176 
177 	ret = wl1251_acx_bcn_dtim_options(wl);
178 	if (ret < 0)
179 		return ret;
180 
181 	return 0;
182 }
183 
184 int wl1251_hw_init_power_auth(struct wl1251 *wl)
185 {
186 	return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
187 }
188 
189 int wl1251_hw_init_mem_config(struct wl1251 *wl)
190 {
191 	int ret;
192 
193 	ret = wl1251_acx_mem_cfg(wl);
194 	if (ret < 0)
195 		return ret;
196 
197 	wl->target_mem_map = kzalloc_obj(struct wl1251_acx_mem_map);
198 	if (!wl->target_mem_map) {
199 		wl1251_error("couldn't allocate target memory map");
200 		return -ENOMEM;
201 	}
202 
203 	/* we now ask for the firmware built memory map */
204 	ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
205 				 sizeof(struct wl1251_acx_mem_map));
206 	if (ret < 0) {
207 		wl1251_error("couldn't retrieve firmware memory map");
208 		kfree(wl->target_mem_map);
209 		wl->target_mem_map = NULL;
210 		return ret;
211 	}
212 
213 	return 0;
214 }
215 
216 static int wl1251_hw_init_txq_fill(u8 qid,
217 				   struct acx_tx_queue_qos_config *config,
218 				   u32 num_blocks)
219 {
220 	config->qid = qid;
221 
222 	switch (qid) {
223 	case QOS_AC_BE:
224 		config->high_threshold =
225 			(QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
226 		config->low_threshold =
227 			(QOS_TX_LOW_BE_DEF * num_blocks) / 100;
228 		break;
229 	case QOS_AC_BK:
230 		config->high_threshold =
231 			(QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
232 		config->low_threshold =
233 			(QOS_TX_LOW_BK_DEF * num_blocks) / 100;
234 		break;
235 	case QOS_AC_VI:
236 		config->high_threshold =
237 			(QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
238 		config->low_threshold =
239 			(QOS_TX_LOW_VI_DEF * num_blocks) / 100;
240 		break;
241 	case QOS_AC_VO:
242 		config->high_threshold =
243 			(QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
244 		config->low_threshold =
245 			(QOS_TX_LOW_VO_DEF * num_blocks) / 100;
246 		break;
247 	default:
248 		wl1251_error("Invalid TX queue id: %d", qid);
249 		return -EINVAL;
250 	}
251 
252 	return 0;
253 }
254 
255 static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
256 {
257 	struct acx_tx_queue_qos_config *config;
258 	struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
259 	int ret, i;
260 
261 	wl1251_debug(DEBUG_ACX, "acx tx queue config");
262 
263 	config = kzalloc_obj(*config);
264 	if (!config) {
265 		ret = -ENOMEM;
266 		goto out;
267 	}
268 
269 	for (i = 0; i < MAX_NUM_OF_AC; i++) {
270 		ret = wl1251_hw_init_txq_fill(i, config,
271 					      wl_mem_map->num_tx_mem_blocks);
272 		if (ret < 0)
273 			goto out;
274 
275 		ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
276 					   config, sizeof(*config));
277 		if (ret < 0)
278 			goto out;
279 	}
280 
281 	wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
282 	wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
283 	wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
284 	wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
285 
286 out:
287 	kfree(config);
288 	return ret;
289 }
290 
291 static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
292 {
293 	int ret;
294 
295 	/* asking for the data path parameters */
296 	wl->data_path = kzalloc_obj(struct acx_data_path_params_resp);
297 	if (!wl->data_path)
298 		return -ENOMEM;
299 
300 	ret = wl1251_acx_data_path_params(wl, wl->data_path);
301 	if (ret < 0) {
302 		kfree(wl->data_path);
303 		wl->data_path = NULL;
304 		return ret;
305 	}
306 
307 	return 0;
308 }
309 
310 
311 int wl1251_hw_init(struct wl1251 *wl)
312 {
313 	struct wl1251_acx_mem_map *wl_mem_map;
314 	int ret;
315 
316 	ret = wl1251_hw_init_hwenc_config(wl);
317 	if (ret < 0)
318 		return ret;
319 
320 	/* Template settings */
321 	ret = wl1251_hw_init_templates_config(wl);
322 	if (ret < 0)
323 		return ret;
324 
325 	/* Default memory configuration */
326 	ret = wl1251_hw_init_mem_config(wl);
327 	if (ret < 0)
328 		return ret;
329 
330 	/* Default data path configuration  */
331 	ret = wl1251_hw_init_data_path_config(wl);
332 	if (ret < 0)
333 		goto out_free_memmap;
334 
335 	/* RX config */
336 	ret = wl1251_hw_init_rx_config(wl,
337 				       RX_CFG_PROMISCUOUS | RX_CFG_TSF,
338 				       RX_FILTER_OPTION_DEF);
339 	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
340 	   RX_FILTER_OPTION_FILTER_ALL); */
341 	if (ret < 0)
342 		goto out_free_data_path;
343 
344 	/* TX queues config */
345 	ret = wl1251_hw_init_tx_queue_config(wl);
346 	if (ret < 0)
347 		goto out_free_data_path;
348 
349 	/* PHY layer config */
350 	ret = wl1251_hw_init_phy_config(wl);
351 	if (ret < 0)
352 		goto out_free_data_path;
353 
354 	/* Initialize connection monitoring thresholds */
355 	ret = wl1251_acx_conn_monit_params(wl);
356 	if (ret < 0)
357 		goto out_free_data_path;
358 
359 	/* Beacon filtering */
360 	ret = wl1251_hw_init_beacon_filter(wl);
361 	if (ret < 0)
362 		goto out_free_data_path;
363 
364 	/* Bluetooth WLAN coexistence */
365 	ret = wl1251_hw_init_pta(wl);
366 	if (ret < 0)
367 		goto out_free_data_path;
368 
369 	/* Energy detection */
370 	ret = wl1251_hw_init_energy_detection(wl);
371 	if (ret < 0)
372 		goto out_free_data_path;
373 
374 	/* Beacons and broadcast settings */
375 	ret = wl1251_hw_init_beacon_broadcast(wl);
376 	if (ret < 0)
377 		goto out_free_data_path;
378 
379 	/* Enable rx data path */
380 	ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
381 	if (ret < 0)
382 		goto out_free_data_path;
383 
384 	/* Enable tx data path */
385 	ret = wl1251_cmd_data_path_tx(wl, wl->channel, 1);
386 	if (ret < 0)
387 		goto out_free_data_path;
388 
389 	/* Default power state */
390 	ret = wl1251_hw_init_power_auth(wl);
391 	if (ret < 0)
392 		goto out_free_data_path;
393 
394 	wl_mem_map = wl->target_mem_map;
395 	wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
396 		    wl_mem_map->num_tx_mem_blocks,
397 		    wl->data_path->tx_control_addr,
398 		    wl_mem_map->num_rx_mem_blocks,
399 		    wl->data_path->rx_control_addr);
400 
401 	return 0;
402 
403  out_free_data_path:
404 	kfree(wl->data_path);
405 
406  out_free_memmap:
407 	kfree(wl->target_mem_map);
408 
409 	return ret;
410 }
411