diff options
author | Arik Nemtsov <arik@wizery.com> | 2010-10-16 12:19:53 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-01-24 15:11:48 -0500 |
commit | e0fe371b74326a85029fe8720506e021fe73905a (patch) | |
tree | 0eb9864739ae8c876560598aefb410e7c7bec3e6 | |
parent | 05285cf9b581af05813cfaa60e23227b009b7754 (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>
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 352 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx_80211.h | 5 |
7 files changed, 317 insertions, 100 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 072bf3c2f24..c9909e09cd9 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h | |||
@@ -140,6 +140,13 @@ enum cmd_templ { | |||
140 | * For CTS-to-self (FastCTS) mechanism | 140 | * For CTS-to-self (FastCTS) mechanism |
141 | * for BT/WLAN coexistence (SoftGemini). */ | 141 | * for BT/WLAN coexistence (SoftGemini). */ |
142 | CMD_TEMPL_ARP_RSP, | 142 | CMD_TEMPL_ARP_RSP, |
143 | |||
144 | /* AP-mode specific */ | ||
145 | CMD_TEMPL_AP_BEACON = 13, | ||
146 | CMD_TEMPL_AP_PROBE_RESPONSE, | ||
147 | CMD_TEMPL_AP_ARP_RSP, | ||
148 | CMD_TEMPL_DEAUTH_AP, | ||
149 | |||
143 | CMD_TEMPL_MAX = 0xff | 150 | CMD_TEMPL_MAX = 0xff |
144 | }; | 151 | }; |
145 | 152 | ||
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 799c3691473..bdb61232f80 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 | ||
34 | static int wl1271_init_hwenc_config(struct wl1271 *wl) | 35 | int 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 | |||
53 | int 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 | ||
103 | static 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 | |||
121 | out: | ||
122 | kfree(tmpl); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static 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 | |||
150 | out: | ||
151 | kfree(nullfunc); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | static 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 | |||
179 | out: | ||
180 | kfree(qosnull); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static 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 | |||
121 | static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) | 229 | static 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 | ||
320 | static 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 | |||
373 | static 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 | |||
399 | static 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 | |||
439 | static 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 | |||
216 | int wl1271_hw_init(struct wl1271 *wl) | 458 | int 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 | ||
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h index 7762421f860..3a8bd3f426d 100644 --- a/drivers/net/wireless/wl12xx/init.h +++ b/drivers/net/wireless/wl12xx/init.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "wl12xx.h" | 27 | #include "wl12xx.h" |
28 | 28 | ||
29 | int wl1271_hw_init_power_auth(struct wl1271 *wl); | 29 | int wl1271_hw_init_power_auth(struct wl1271 *wl); |
30 | int wl1271_init_templates_config(struct wl1271 *wl); | 30 | int wl1271_sta_init_templates_config(struct wl1271 *wl); |
31 | int wl1271_init_phy_config(struct wl1271 *wl); | 31 | int wl1271_init_phy_config(struct wl1271 *wl); |
32 | int wl1271_init_pta(struct wl1271 *wl); | 32 | int wl1271_init_pta(struct wl1271 *wl); |
33 | int wl1271_init_energy_detection(struct wl1271 *wl); | 33 | int wl1271_init_energy_detection(struct wl1271 *wl); |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 9785b4c43c8..67f6db4354f 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -434,7 +434,7 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
434 | if (ret < 0) | 434 | if (ret < 0) |
435 | return ret; | 435 | return ret; |
436 | 436 | ||
437 | ret = wl1271_init_templates_config(wl); | 437 | ret = wl1271_sta_init_templates_config(wl); |
438 | if (ret < 0) | 438 | if (ret < 0) |
439 | return ret; | 439 | return ret; |
440 | 440 | ||
@@ -1363,24 +1363,6 @@ static void wl1271_set_band_rate(struct wl1271 *wl) | |||
1363 | wl->basic_rate_set = wl->conf.tx.basic_rate_5; | 1363 | wl->basic_rate_set = wl->conf.tx.basic_rate_5; |
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | static u32 wl1271_min_rate_get(struct wl1271 *wl) | ||
1367 | { | ||
1368 | int i; | ||
1369 | u32 rate = 0; | ||
1370 | |||
1371 | if (!wl->basic_rate_set) { | ||
1372 | WARN_ON(1); | ||
1373 | wl->basic_rate_set = wl->conf.tx.basic_rate; | ||
1374 | } | ||
1375 | |||
1376 | for (i = 0; !rate; i++) { | ||
1377 | if ((wl->basic_rate_set >> i) & 0x1) | ||
1378 | rate = 1 << i; | ||
1379 | } | ||
1380 | |||
1381 | return rate; | ||
1382 | } | ||
1383 | |||
1384 | static int wl1271_handle_idle(struct wl1271 *wl, bool idle) | 1366 | static int wl1271_handle_idle(struct wl1271 *wl, bool idle) |
1385 | { | 1367 | { |
1386 | int ret; | 1368 | int ret; |
@@ -1391,7 +1373,7 @@ static int wl1271_handle_idle(struct wl1271 *wl, bool idle) | |||
1391 | if (ret < 0) | 1373 | if (ret < 0) |
1392 | goto out; | 1374 | goto out; |
1393 | } | 1375 | } |
1394 | wl->rate_set = wl1271_min_rate_get(wl); | 1376 | wl->rate_set = wl1271_tx_min_rate_get(wl); |
1395 | wl->sta_rate_set = 0; | 1377 | wl->sta_rate_set = 0; |
1396 | ret = wl1271_acx_sta_rate_policies(wl); | 1378 | ret = wl1271_acx_sta_rate_policies(wl); |
1397 | if (ret < 0) | 1379 | if (ret < 0) |
@@ -1467,7 +1449,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1467 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 1449 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
1468 | wl1271_set_band_rate(wl); | 1450 | wl1271_set_band_rate(wl); |
1469 | 1451 | ||
1470 | wl->basic_rate = wl1271_min_rate_get(wl); | 1452 | wl->basic_rate = wl1271_tx_min_rate_get(wl); |
1471 | ret = wl1271_acx_sta_rate_policies(wl); | 1453 | ret = wl1271_acx_sta_rate_policies(wl); |
1472 | if (ret < 0) | 1454 | if (ret < 0) |
1473 | wl1271_warning("rate policy for update channel " | 1455 | wl1271_warning("rate policy for update channel " |
@@ -1927,7 +1909,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1927 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, | 1909 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, |
1928 | beacon->data, | 1910 | beacon->data, |
1929 | beacon->len, 0, | 1911 | beacon->len, 0, |
1930 | wl1271_min_rate_get(wl)); | 1912 | wl1271_tx_min_rate_get(wl)); |
1931 | 1913 | ||
1932 | if (ret < 0) { | 1914 | if (ret < 0) { |
1933 | dev_kfree_skb(beacon); | 1915 | dev_kfree_skb(beacon); |
@@ -1943,7 +1925,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1943 | CMD_TEMPL_PROBE_RESPONSE, | 1925 | CMD_TEMPL_PROBE_RESPONSE, |
1944 | beacon->data, | 1926 | beacon->data, |
1945 | beacon->len, 0, | 1927 | beacon->len, 0, |
1946 | wl1271_min_rate_get(wl)); | 1928 | wl1271_tx_min_rate_get(wl)); |
1947 | dev_kfree_skb(beacon); | 1929 | dev_kfree_skb(beacon); |
1948 | if (ret < 0) | 1930 | if (ret < 0) |
1949 | goto out_sleep; | 1931 | goto out_sleep; |
@@ -2016,7 +1998,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2016 | rates = bss_conf->basic_rates; | 1998 | rates = bss_conf->basic_rates; |
2017 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 1999 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, |
2018 | rates); | 2000 | rates); |
2019 | wl->basic_rate = wl1271_min_rate_get(wl); | 2001 | wl->basic_rate = wl1271_tx_min_rate_get(wl); |
2020 | ret = wl1271_acx_sta_rate_policies(wl); | 2002 | ret = wl1271_acx_sta_rate_policies(wl); |
2021 | if (ret < 0) | 2003 | if (ret < 0) |
2022 | goto out_sleep; | 2004 | goto out_sleep; |
@@ -2070,7 +2052,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2070 | 2052 | ||
2071 | /* revert back to minimum rates for the current band */ | 2053 | /* revert back to minimum rates for the current band */ |
2072 | wl1271_set_band_rate(wl); | 2054 | wl1271_set_band_rate(wl); |
2073 | wl->basic_rate = wl1271_min_rate_get(wl); | 2055 | wl->basic_rate = wl1271_tx_min_rate_get(wl); |
2074 | ret = wl1271_acx_sta_rate_policies(wl); | 2056 | ret = wl1271_acx_sta_rate_policies(wl); |
2075 | if (ret < 0) | 2057 | if (ret < 0) |
2076 | goto out_sleep; | 2058 | goto out_sleep; |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 442a7bd956e..a93fc4702f3 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -521,3 +521,21 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
521 | 521 | ||
522 | wl1271_warning("Unable to flush all TX buffers, timed out."); | 522 | wl1271_warning("Unable to flush all TX buffers, timed out."); |
523 | } | 523 | } |
524 | |||
525 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl) | ||
526 | { | ||
527 | int i; | ||
528 | u32 rate = 0; | ||
529 | |||
530 | if (!wl->basic_rate_set) { | ||
531 | WARN_ON(1); | ||
532 | wl->basic_rate_set = wl->conf.tx.basic_rate; | ||
533 | } | ||
534 | |||
535 | for (i = 0; !rate; i++) { | ||
536 | if ((wl->basic_rate_set >> i) & 0x1) | ||
537 | rate = 1 << i; | ||
538 | } | ||
539 | |||
540 | return rate; | ||
541 | } | ||
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 903e5dc69b7..5ccd22eaf07 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -146,5 +146,6 @@ void wl1271_tx_reset(struct wl1271 *wl); | |||
146 | void wl1271_tx_flush(struct wl1271 *wl); | 146 | void wl1271_tx_flush(struct wl1271 *wl); |
147 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 147 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); |
148 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); | 148 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); |
149 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl); | ||
149 | 150 | ||
150 | #endif | 151 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index e2b26fbf68c..67dcf8f28cd 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h | |||
@@ -160,4 +160,9 @@ struct wl12xx_probe_resp_template { | |||
160 | struct wl12xx_ie_country country; | 160 | struct wl12xx_ie_country country; |
161 | } __packed; | 161 | } __packed; |
162 | 162 | ||
163 | struct wl12xx_disconn_template { | ||
164 | struct ieee80211_header header; | ||
165 | __le16 disconn_reason; | ||
166 | } __packed; | ||
167 | |||
163 | #endif | 168 | #endif |