]> Git Repo - J-linux.git/blob - drivers/net/wireless/ti/wl1251/init.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / drivers / net / wireless / ti / wl1251 / init.c
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(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;
202         }
203
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;
212         }
213
214         return 0;
215 }
216
217 static int wl1251_hw_init_txq_fill(u8 qid,
218                                    struct acx_tx_queue_qos_config *config,
219                                    u32 num_blocks)
220 {
221         config->qid = qid;
222
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;
251         }
252
253         return 0;
254 }
255
256 static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
257 {
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;
261
262         wl1251_debug(DEBUG_ACX, "acx tx queue config");
263
264         config = kzalloc(sizeof(*config), GFP_KERNEL);
265         if (!config) {
266                 ret = -ENOMEM;
267                 goto out;
268         }
269
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;
275
276                 ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
277                                            config, sizeof(*config));
278                 if (ret < 0)
279                         goto out;
280         }
281
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);
286
287 out:
288         kfree(config);
289         return ret;
290 }
291
292 static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
293 {
294         int ret;
295
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;
301
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;
307         }
308
309         return 0;
310 }
311
312
313 int wl1251_hw_init(struct wl1251 *wl)
314 {
315         struct wl1251_acx_mem_map *wl_mem_map;
316         int ret;
317
318         ret = wl1251_hw_init_hwenc_config(wl);
319         if (ret < 0)
320                 return ret;
321
322         /* Template settings */
323         ret = wl1251_hw_init_templates_config(wl);
324         if (ret < 0)
325                 return ret;
326
327         /* Default memory configuration */
328         ret = wl1251_hw_init_mem_config(wl);
329         if (ret < 0)
330                 return ret;
331
332         /* Default data path configuration  */
333         ret = wl1251_hw_init_data_path_config(wl);
334         if (ret < 0)
335                 goto out_free_memmap;
336
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;
345
346         /* TX queues config */
347         ret = wl1251_hw_init_tx_queue_config(wl);
348         if (ret < 0)
349                 goto out_free_data_path;
350
351         /* PHY layer config */
352         ret = wl1251_hw_init_phy_config(wl);
353         if (ret < 0)
354                 goto out_free_data_path;
355
356         /* Initialize connection monitoring thresholds */
357         ret = wl1251_acx_conn_monit_params(wl);
358         if (ret < 0)
359                 goto out_free_data_path;
360
361         /* Beacon filtering */
362         ret = wl1251_hw_init_beacon_filter(wl);
363         if (ret < 0)
364                 goto out_free_data_path;
365
366         /* Bluetooth WLAN coexistence */
367         ret = wl1251_hw_init_pta(wl);
368         if (ret < 0)
369                 goto out_free_data_path;
370
371         /* Energy detection */
372         ret = wl1251_hw_init_energy_detection(wl);
373         if (ret < 0)
374                 goto out_free_data_path;
375
376         /* Beacons and broadcast settings */
377         ret = wl1251_hw_init_beacon_broadcast(wl);
378         if (ret < 0)
379                 goto out_free_data_path;
380
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;
385
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;
390
391         /* Default power state */
392         ret = wl1251_hw_init_power_auth(wl);
393         if (ret < 0)
394                 goto out_free_data_path;
395
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);
402
403         return 0;
404
405  out_free_data_path:
406         kfree(wl->data_path);
407
408  out_free_memmap:
409         kfree(wl->target_mem_map);
410
411         return ret;
412 }
This page took 0.056539 seconds and 4 git commands to generate.