aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/init.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2010-10-16 12:19:53 -0400
committerLuciano Coelho <coelho@ti.com>2011-01-24 15:11:48 -0500
commite0fe371b74326a85029fe8720506e021fe73905a (patch)
tree0eb9864739ae8c876560598aefb410e7c7bec3e6 /drivers/net/wireless/wl12xx/init.c
parent05285cf9b581af05813cfaa60e23227b009b7754 (diff)
wl12xx: AP mode - init sequence
Split HW init sequence into AP/STA specific parts The AP specific init sequence includes configuration of templates, rate classes, power mode, etc. Also unmask AP specific events in the event mbox. Separate the differences between AP and STA init into mode specific functions called from wl1271_hw_init. The first is called after radio configuration and the second after memory configuration. Signed-off-by: Arik Nemtsov <arik@wizery.com> Reviewed-by: Luciano Coelho <coelho@ti.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/init.c')
-rw-r--r--drivers/net/wireless/wl12xx/init.c352
1 files changed, 278 insertions, 74 deletions
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 799c36914735..bdb61232f80c 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -30,27 +30,9 @@
30#include "acx.h" 30#include "acx.h"
31#include "cmd.h" 31#include "cmd.h"
32#include "reg.h" 32#include "reg.h"
33#include "tx.h"
33 34
34static int wl1271_init_hwenc_config(struct wl1271 *wl) 35int wl1271_sta_init_templates_config(struct wl1271 *wl)
35{
36 int ret;
37
38 ret = wl1271_acx_feature_cfg(wl);
39 if (ret < 0) {
40 wl1271_warning("couldn't set feature config");
41 return ret;
42 }
43
44 ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key);
45 if (ret < 0) {
46 wl1271_warning("couldn't set default key");
47 return ret;
48 }
49
50 return 0;
51}
52
53int wl1271_init_templates_config(struct wl1271 *wl)
54{ 36{
55 int ret, i; 37 int ret, i;
56 38
@@ -118,6 +100,132 @@ int wl1271_init_templates_config(struct wl1271 *wl)
118 return 0; 100 return 0;
119} 101}
120 102
103static int wl1271_ap_init_deauth_template(struct wl1271 *wl)
104{
105 struct wl12xx_disconn_template *tmpl;
106 int ret;
107
108 tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
109 if (!tmpl) {
110 ret = -ENOMEM;
111 goto out;
112 }
113
114 tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
115 IEEE80211_STYPE_DEAUTH);
116
117 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
118 tmpl, sizeof(*tmpl), 0,
119 wl1271_tx_min_rate_get(wl));
120
121out:
122 kfree(tmpl);
123 return ret;
124}
125
126static int wl1271_ap_init_null_template(struct wl1271 *wl)
127{
128 struct ieee80211_hdr_3addr *nullfunc;
129 int ret;
130
131 nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
132 if (!nullfunc) {
133 ret = -ENOMEM;
134 goto out;
135 }
136
137 nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
138 IEEE80211_STYPE_NULLFUNC |
139 IEEE80211_FCTL_FROMDS);
140
141 /* nullfunc->addr1 is filled by FW */
142
143 memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
144 memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN);
145
146 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
147 sizeof(*nullfunc), 0,
148 wl1271_tx_min_rate_get(wl));
149
150out:
151 kfree(nullfunc);
152 return ret;
153}
154
155static int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
156{
157 struct ieee80211_qos_hdr *qosnull;
158 int ret;
159
160 qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
161 if (!qosnull) {
162 ret = -ENOMEM;
163 goto out;
164 }
165
166 qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
167 IEEE80211_STYPE_QOS_NULLFUNC |
168 IEEE80211_FCTL_FROMDS);
169
170 /* qosnull->addr1 is filled by FW */
171
172 memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN);
173 memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN);
174
175 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
176 sizeof(*qosnull), 0,
177 wl1271_tx_min_rate_get(wl));
178
179out:
180 kfree(qosnull);
181 return ret;
182}
183
184static int wl1271_ap_init_templates_config(struct wl1271 *wl)
185{
186 int ret;
187
188 /*
189 * Put very large empty placeholders for all templates. These
190 * reserve memory for later.
191 */
192 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
193 sizeof
194 (struct wl12xx_probe_resp_template),
195 0, WL1271_RATE_AUTOMATIC);
196 if (ret < 0)
197 return ret;
198
199 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
200 sizeof
201 (struct wl12xx_beacon_template),
202 0, WL1271_RATE_AUTOMATIC);
203 if (ret < 0)
204 return ret;
205
206 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
207 sizeof
208 (struct wl12xx_disconn_template),
209 0, WL1271_RATE_AUTOMATIC);
210 if (ret < 0)
211 return ret;
212
213 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
214 sizeof(struct wl12xx_null_data_template),
215 0, WL1271_RATE_AUTOMATIC);
216 if (ret < 0)
217 return ret;
218
219 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
220 sizeof
221 (struct wl12xx_qos_null_data_template),
222 0, WL1271_RATE_AUTOMATIC);
223 if (ret < 0)
224 return ret;
225
226 return 0;
227}
228
121static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) 229static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
122{ 230{
123 int ret; 231 int ret;
@@ -145,10 +253,6 @@ int wl1271_init_phy_config(struct wl1271 *wl)
145 if (ret < 0) 253 if (ret < 0)
146 return ret; 254 return ret;
147 255
148 ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
149 if (ret < 0)
150 return ret;
151
152 ret = wl1271_acx_service_period_timeout(wl); 256 ret = wl1271_acx_service_period_timeout(wl);
153 if (ret < 0) 257 if (ret < 0)
154 return ret; 258 return ret;
@@ -213,11 +317,150 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
213 return 0; 317 return 0;
214} 318}
215 319
320static int wl1271_sta_hw_init(struct wl1271 *wl)
321{
322 int ret;
323
324 ret = wl1271_cmd_ext_radio_parms(wl);
325 if (ret < 0)
326 return ret;
327
328 ret = wl1271_sta_init_templates_config(wl);
329 if (ret < 0)
330 return ret;
331
332 ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
333 if (ret < 0)
334 return ret;
335
336 /* Initialize connection monitoring thresholds */
337 ret = wl1271_acx_conn_monit_params(wl, false);
338 if (ret < 0)
339 return ret;
340
341 /* Beacon filtering */
342 ret = wl1271_init_beacon_filter(wl);
343 if (ret < 0)
344 return ret;
345
346 /* Bluetooth WLAN coexistence */
347 ret = wl1271_init_pta(wl);
348 if (ret < 0)
349 return ret;
350
351 /* Beacons and broadcast settings */
352 ret = wl1271_init_beacon_broadcast(wl);
353 if (ret < 0)
354 return ret;
355
356 /* Configure for ELP power saving */
357 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
358 if (ret < 0)
359 return ret;
360
361 /* Configure rssi/snr averaging weights */
362 ret = wl1271_acx_rssi_snr_avg_weights(wl);
363 if (ret < 0)
364 return ret;
365
366 ret = wl1271_acx_sta_rate_policies(wl);
367 if (ret < 0)
368 return ret;
369
370 return 0;
371}
372
373static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
374{
375 int ret, i;
376
377 ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key);
378 if (ret < 0) {
379 wl1271_warning("couldn't set default key");
380 return ret;
381 }
382
383 /* disable all keep-alive templates */
384 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
385 ret = wl1271_acx_keep_alive_config(wl, i,
386 ACX_KEEP_ALIVE_TPL_INVALID);
387 if (ret < 0)
388 return ret;
389 }
390
391 /* disable the keep-alive feature */
392 ret = wl1271_acx_keep_alive_mode(wl, false);
393 if (ret < 0)
394 return ret;
395
396 return 0;
397}
398
399static int wl1271_ap_hw_init(struct wl1271 *wl)
400{
401 int ret, i;
402
403 ret = wl1271_ap_init_templates_config(wl);
404 if (ret < 0)
405 return ret;
406
407 /* Configure for power always on */
408 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
409 if (ret < 0)
410 return ret;
411
412 /* Configure initial TX rate classes */
413 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
414 ret = wl1271_acx_ap_rate_policy(wl,
415 &wl->conf.tx.ap_rc_conf[i], i);
416 if (ret < 0)
417 return ret;
418 }
419
420 ret = wl1271_acx_ap_rate_policy(wl,
421 &wl->conf.tx.ap_mgmt_conf,
422 ACX_TX_AP_MODE_MGMT_RATE);
423 if (ret < 0)
424 return ret;
425
426 ret = wl1271_acx_ap_rate_policy(wl,
427 &wl->conf.tx.ap_bcst_conf,
428 ACX_TX_AP_MODE_BCST_RATE);
429 if (ret < 0)
430 return ret;
431
432 ret = wl1271_acx_max_tx_retry(wl);
433 if (ret < 0)
434 return ret;
435
436 return 0;
437}
438
439static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
440{
441 int ret;
442
443 ret = wl1271_ap_init_deauth_template(wl);
444 if (ret < 0)
445 return ret;
446
447 ret = wl1271_ap_init_null_template(wl);
448 if (ret < 0)
449 return ret;
450
451 ret = wl1271_ap_init_qos_null_template(wl);
452 if (ret < 0)
453 return ret;
454
455 return 0;
456}
457
216int wl1271_hw_init(struct wl1271 *wl) 458int wl1271_hw_init(struct wl1271 *wl)
217{ 459{
218 struct conf_tx_ac_category *conf_ac; 460 struct conf_tx_ac_category *conf_ac;
219 struct conf_tx_tid *conf_tid; 461 struct conf_tx_tid *conf_tid;
220 int ret, i; 462 int ret, i;
463 bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
221 464
222 ret = wl1271_cmd_general_parms(wl); 465 ret = wl1271_cmd_general_parms(wl);
223 if (ret < 0) 466 if (ret < 0)
@@ -227,12 +470,12 @@ int wl1271_hw_init(struct wl1271 *wl)
227 if (ret < 0) 470 if (ret < 0)
228 return ret; 471 return ret;
229 472
230 ret = wl1271_cmd_ext_radio_parms(wl); 473 /* Mode specific init */
231 if (ret < 0) 474 if (is_ap)
232 return ret; 475 ret = wl1271_ap_hw_init(wl);
476 else
477 ret = wl1271_sta_hw_init(wl);
233 478
234 /* Template settings */
235 ret = wl1271_init_templates_config(wl);
236 if (ret < 0) 479 if (ret < 0)
237 return ret; 480 return ret;
238 481
@@ -259,16 +502,6 @@ int wl1271_hw_init(struct wl1271 *wl)
259 if (ret < 0) 502 if (ret < 0)
260 goto out_free_memmap; 503 goto out_free_memmap;
261 504
262 /* Initialize connection monitoring thresholds */
263 ret = wl1271_acx_conn_monit_params(wl, false);
264 if (ret < 0)
265 goto out_free_memmap;
266
267 /* Beacon filtering */
268 ret = wl1271_init_beacon_filter(wl);
269 if (ret < 0)
270 goto out_free_memmap;
271
272 /* Configure TX patch complete interrupt behavior */ 505 /* Configure TX patch complete interrupt behavior */
273 ret = wl1271_acx_tx_config_options(wl); 506 ret = wl1271_acx_tx_config_options(wl);
274 if (ret < 0) 507 if (ret < 0)
@@ -279,21 +512,11 @@ int wl1271_hw_init(struct wl1271 *wl)
279 if (ret < 0) 512 if (ret < 0)
280 goto out_free_memmap; 513 goto out_free_memmap;
281 514
282 /* Bluetooth WLAN coexistence */
283 ret = wl1271_init_pta(wl);
284 if (ret < 0)
285 goto out_free_memmap;
286
287 /* Energy detection */ 515 /* Energy detection */
288 ret = wl1271_init_energy_detection(wl); 516 ret = wl1271_init_energy_detection(wl);
289 if (ret < 0) 517 if (ret < 0)
290 goto out_free_memmap; 518 goto out_free_memmap;
291 519
292 /* Beacons and boradcast settings */
293 ret = wl1271_init_beacon_broadcast(wl);
294 if (ret < 0)
295 goto out_free_memmap;
296
297 /* Default fragmentation threshold */ 520 /* Default fragmentation threshold */
298 ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); 521 ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
299 if (ret < 0) 522 if (ret < 0)
@@ -321,23 +544,13 @@ int wl1271_hw_init(struct wl1271 *wl)
321 goto out_free_memmap; 544 goto out_free_memmap;
322 } 545 }
323 546
324 /* Configure TX rate classes */
325 ret = wl1271_acx_sta_rate_policies(wl);
326 if (ret < 0)
327 goto out_free_memmap;
328
329 /* Enable data path */ 547 /* Enable data path */
330 ret = wl1271_cmd_data_path(wl, 1); 548 ret = wl1271_cmd_data_path(wl, 1);
331 if (ret < 0) 549 if (ret < 0)
332 goto out_free_memmap; 550 goto out_free_memmap;
333 551
334 /* Configure for ELP power saving */
335 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
336 if (ret < 0)
337 goto out_free_memmap;
338
339 /* Configure HW encryption */ 552 /* Configure HW encryption */
340 ret = wl1271_init_hwenc_config(wl); 553 ret = wl1271_acx_feature_cfg(wl);
341 if (ret < 0) 554 if (ret < 0)
342 goto out_free_memmap; 555 goto out_free_memmap;
343 556
@@ -346,21 +559,12 @@ int wl1271_hw_init(struct wl1271 *wl)
346 if (ret < 0) 559 if (ret < 0)
347 goto out_free_memmap; 560 goto out_free_memmap;
348 561
349 /* disable all keep-alive templates */ 562 /* Mode specific init - post mem init */
350 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 563 if (is_ap)
351 ret = wl1271_acx_keep_alive_config(wl, i, 564 ret = wl1271_ap_hw_init_post_mem(wl);
352 ACX_KEEP_ALIVE_TPL_INVALID); 565 else
353 if (ret < 0) 566 ret = wl1271_sta_hw_init_post_mem(wl);
354 goto out_free_memmap;
355 }
356 567
357 /* disable the keep-alive feature */
358 ret = wl1271_acx_keep_alive_mode(wl, false);
359 if (ret < 0)
360 goto out_free_memmap;
361
362 /* Configure rssi/snr averaging weights */
363 ret = wl1271_acx_rssi_snr_avg_weights(wl);
364 if (ret < 0) 568 if (ret < 0)
365 goto out_free_memmap; 569 goto out_free_memmap;
366 570