gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / net / wireless / ti / wl1251 / init.c
bloba19cce3a7e6f03ea6da7429155304cb4e011944a
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * This file is part of wl1251
5 * Copyright (C) 2009 Nokia Corporation
6 */
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
12 #include "init.h"
13 #include "wl12xx_80211.h"
14 #include "acx.h"
15 #include "cmd.h"
16 #include "reg.h"
18 int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
20 int ret;
22 ret = wl1251_acx_feature_cfg(wl, 0);
23 if (ret < 0) {
24 wl1251_warning("couldn't set feature config");
25 return ret;
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;
34 return 0;
37 int wl1251_hw_init_templates_config(struct wl1251 *wl)
39 int ret;
40 u8 partial_vbm[PARTIAL_VBM_MAX];
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;
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;
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;
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;
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;
70 ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
71 sizeof
72 (struct wl12xx_beacon_template));
73 if (ret < 0)
74 return ret;
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;
82 ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
83 if (ret < 0)
84 return ret;
86 return 0;
89 int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
91 int ret;
93 ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
94 if (ret < 0)
95 return ret;
97 ret = wl1251_acx_rx_config(wl, config, filter);
98 if (ret < 0)
99 return ret;
101 return 0;
104 int wl1251_hw_init_phy_config(struct wl1251 *wl)
106 int ret;
108 ret = wl1251_acx_pd_threshold(wl);
109 if (ret < 0)
110 return ret;
112 ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
113 if (ret < 0)
114 return ret;
116 ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0);
117 if (ret < 0)
118 return ret;
120 ret = wl1251_acx_service_period_timeout(wl);
121 if (ret < 0)
122 return ret;
124 ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
125 if (ret < 0)
126 return ret;
128 return 0;
131 int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
133 int ret;
135 /* disable beacon filtering at this stage */
136 ret = wl1251_acx_beacon_filter_opt(wl, false);
137 if (ret < 0)
138 return ret;
140 ret = wl1251_acx_beacon_filter_table(wl);
141 if (ret < 0)
142 return ret;
144 return 0;
147 int wl1251_hw_init_pta(struct wl1251 *wl)
149 int ret;
151 ret = wl1251_acx_sg_enable(wl);
152 if (ret < 0)
153 return ret;
155 ret = wl1251_acx_sg_cfg(wl);
156 if (ret < 0)
157 return ret;
159 return 0;
162 int wl1251_hw_init_energy_detection(struct wl1251 *wl)
164 int ret;
166 ret = wl1251_acx_cca_threshold(wl);
167 if (ret < 0)
168 return ret;
170 return 0;
173 int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
175 int ret;
177 ret = wl1251_acx_bcn_dtim_options(wl);
178 if (ret < 0)
179 return ret;
181 return 0;
184 int wl1251_hw_init_power_auth(struct wl1251 *wl)
186 return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
189 int wl1251_hw_init_mem_config(struct wl1251 *wl)
191 int ret;
193 ret = wl1251_acx_mem_cfg(wl);
194 if (ret < 0)
195 return ret;
197 wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
198 GFP_KERNEL);
199 if (!wl->target_mem_map) {
200 wl1251_error("couldn't allocate target memory map");
201 return -ENOMEM;
204 /* we now ask for the firmware built memory map */
205 ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
206 sizeof(struct wl1251_acx_mem_map));
207 if (ret < 0) {
208 wl1251_error("couldn't retrieve firmware memory map");
209 kfree(wl->target_mem_map);
210 wl->target_mem_map = NULL;
211 return ret;
214 return 0;
217 static int wl1251_hw_init_txq_fill(u8 qid,
218 struct acx_tx_queue_qos_config *config,
219 u32 num_blocks)
221 config->qid = qid;
223 switch (qid) {
224 case QOS_AC_BE:
225 config->high_threshold =
226 (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
227 config->low_threshold =
228 (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
229 break;
230 case QOS_AC_BK:
231 config->high_threshold =
232 (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
233 config->low_threshold =
234 (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
235 break;
236 case QOS_AC_VI:
237 config->high_threshold =
238 (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
239 config->low_threshold =
240 (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
241 break;
242 case QOS_AC_VO:
243 config->high_threshold =
244 (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
245 config->low_threshold =
246 (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
247 break;
248 default:
249 wl1251_error("Invalid TX queue id: %d", qid);
250 return -EINVAL;
253 return 0;
256 static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
258 struct acx_tx_queue_qos_config *config;
259 struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
260 int ret, i;
262 wl1251_debug(DEBUG_ACX, "acx tx queue config");
264 config = kzalloc(sizeof(*config), GFP_KERNEL);
265 if (!config) {
266 ret = -ENOMEM;
267 goto out;
270 for (i = 0; i < MAX_NUM_OF_AC; i++) {
271 ret = wl1251_hw_init_txq_fill(i, config,
272 wl_mem_map->num_tx_mem_blocks);
273 if (ret < 0)
274 goto out;
276 ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
277 config, sizeof(*config));
278 if (ret < 0)
279 goto out;
282 wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
283 wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
284 wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
285 wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
287 out:
288 kfree(config);
289 return ret;
292 static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
294 int ret;
296 /* asking for the data path parameters */
297 wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
298 GFP_KERNEL);
299 if (!wl->data_path)
300 return -ENOMEM;
302 ret = wl1251_acx_data_path_params(wl, wl->data_path);
303 if (ret < 0) {
304 kfree(wl->data_path);
305 wl->data_path = NULL;
306 return ret;
309 return 0;
313 int wl1251_hw_init(struct wl1251 *wl)
315 struct wl1251_acx_mem_map *wl_mem_map;
316 int ret;
318 ret = wl1251_hw_init_hwenc_config(wl);
319 if (ret < 0)
320 return ret;
322 /* Template settings */
323 ret = wl1251_hw_init_templates_config(wl);
324 if (ret < 0)
325 return ret;
327 /* Default memory configuration */
328 ret = wl1251_hw_init_mem_config(wl);
329 if (ret < 0)
330 return ret;
332 /* Default data path configuration */
333 ret = wl1251_hw_init_data_path_config(wl);
334 if (ret < 0)
335 goto out_free_memmap;
337 /* RX config */
338 ret = wl1251_hw_init_rx_config(wl,
339 RX_CFG_PROMISCUOUS | RX_CFG_TSF,
340 RX_FILTER_OPTION_DEF);
341 /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
342 RX_FILTER_OPTION_FILTER_ALL); */
343 if (ret < 0)
344 goto out_free_data_path;
346 /* TX queues config */
347 ret = wl1251_hw_init_tx_queue_config(wl);
348 if (ret < 0)
349 goto out_free_data_path;
351 /* PHY layer config */
352 ret = wl1251_hw_init_phy_config(wl);
353 if (ret < 0)
354 goto out_free_data_path;
356 /* Initialize connection monitoring thresholds */
357 ret = wl1251_acx_conn_monit_params(wl);
358 if (ret < 0)
359 goto out_free_data_path;
361 /* Beacon filtering */
362 ret = wl1251_hw_init_beacon_filter(wl);
363 if (ret < 0)
364 goto out_free_data_path;
366 /* Bluetooth WLAN coexistence */
367 ret = wl1251_hw_init_pta(wl);
368 if (ret < 0)
369 goto out_free_data_path;
371 /* Energy detection */
372 ret = wl1251_hw_init_energy_detection(wl);
373 if (ret < 0)
374 goto out_free_data_path;
376 /* Beacons and boradcast settings */
377 ret = wl1251_hw_init_beacon_broadcast(wl);
378 if (ret < 0)
379 goto out_free_data_path;
381 /* Enable rx data path */
382 ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
383 if (ret < 0)
384 goto out_free_data_path;
386 /* Enable tx data path */
387 ret = wl1251_cmd_data_path_tx(wl, wl->channel, 1);
388 if (ret < 0)
389 goto out_free_data_path;
391 /* Default power state */
392 ret = wl1251_hw_init_power_auth(wl);
393 if (ret < 0)
394 goto out_free_data_path;
396 wl_mem_map = wl->target_mem_map;
397 wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
398 wl_mem_map->num_tx_mem_blocks,
399 wl->data_path->tx_control_addr,
400 wl_mem_map->num_rx_mem_blocks,
401 wl->data_path->rx_control_addr);
403 return 0;
405 out_free_data_path:
406 kfree(wl->data_path);
408 out_free_memmap:
409 kfree(wl->target_mem_map);
411 return ret;