aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-04-29 16:33:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-06 15:14:54 -0400
commit2f01a1f58889fbfeb68b1bc1b52e4197f3333490 (patch)
tree949cf33c4e3dcdf7abcf95c9bda4d8372da04f97 /drivers/net/wireless/wl12xx
parentd53d9e67b55f6a9fc3f836c5c392eb41ce5676f4 (diff)
wl12xx: add driver
wl12xx is a driver for TI wl1251 802.11 chipset designed for embedded devices, supporting both SDIO and SPI busses. Currently the driver supports only SPI. Adding support 1253 (the 5 GHz version) should be relatively easy. More information here: http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?contentId=4711&navigationId=12494&templateId=6123 (Collapsed original sequence of pre-merge patches into single commit for initial merge. -- JWL) Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig11
-rw-r--r--drivers/net/wireless/wl12xx/Makefile4
-rw-r--r--drivers/net/wireless/wl12xx/acx.c689
-rw-r--r--drivers/net/wireless/wl12xx/acx.h1245
-rw-r--r--drivers/net/wireless/wl12xx/boot.c295
-rw-r--r--drivers/net/wireless/wl12xx/boot.h40
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c353
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h265
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c508
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/event.c127
-rw-r--r--drivers/net/wireless/wl12xx/event.h121
-rw-r--r--drivers/net/wireless/wl12xx/init.c200
-rw-r--r--drivers/net/wireless/wl12xx/init.h40
-rw-r--r--drivers/net/wireless/wl12xx/main.c1358
-rw-r--r--drivers/net/wireless/wl12xx/ps.c151
-rw-r--r--drivers/net/wireless/wl12xx/ps.h36
-rw-r--r--drivers/net/wireless/wl12xx/reg.h745
-rw-r--r--drivers/net/wireless/wl12xx/rx.c208
-rw-r--r--drivers/net/wireless/wl12xx/rx.h122
-rw-r--r--drivers/net/wireless/wl12xx/spi.c358
-rw-r--r--drivers/net/wireless/wl12xx/spi.h109
-rw-r--r--drivers/net/wireless/wl12xx/tx.c557
-rw-r--r--drivers/net/wireless/wl12xx/tx.h215
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.c709
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h165
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h409
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h156
28 files changed, 9229 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
new file mode 100644
index 000000000000..20a9633569f2
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -0,0 +1,11 @@
1config WL12XX
2 tristate "TI wl1251/wl1271 support"
3 depends on MAC80211 && WLAN_80211 && SPI_MASTER && EXPERIMENTAL
4 select FW_LOADER
5 select CRC7
6 ---help---
7 This module adds support for wireless adapters based on
8 TI wl1251/wl1271 chipsets.
9
10 If you choose to build a module, it'll be called wl12xx. Say N if
11 unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
new file mode 100644
index 000000000000..d43de27dc54c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -0,0 +1,4 @@
1wl12xx-objs = main.o spi.o event.o tx.o rx.o \
2 ps.o cmd.o acx.o boot.o init.o wl1251.o \
3 debugfs.o
4obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
new file mode 100644
index 000000000000..1cfd458ad5ab
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -0,0 +1,689 @@
1#include "acx.h"
2
3#include <linux/module.h>
4#include <linux/crc7.h>
5#include <linux/spi/spi.h>
6
7#include "wl12xx.h"
8#include "wl12xx_80211.h"
9#include "reg.h"
10#include "spi.h"
11#include "ps.h"
12
13int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
14 u8 mgt_rate, u8 mgt_mod)
15{
16 int ret;
17 struct acx_fw_gen_frame_rates rates;
18
19 wl12xx_debug(DEBUG_ACX, "acx frame rates");
20
21 rates.header.id = ACX_FW_GEN_FRAME_RATES;
22 rates.header.len = sizeof(struct acx_fw_gen_frame_rates) -
23 sizeof(struct acx_header);
24
25 rates.tx_ctrl_frame_rate = ctrl_rate;
26 rates.tx_ctrl_frame_mod = ctrl_mod;
27 rates.tx_mgt_frame_rate = mgt_rate;
28 rates.tx_mgt_frame_mod = mgt_mod;
29
30 ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates));
31 if (ret < 0) {
32 wl12xx_error("Failed to set FW rates and modulation");
33 return ret;
34 }
35
36 return 0;
37}
38
39
40int wl12xx_acx_station_id(struct wl12xx *wl)
41{
42 int ret, i;
43 struct dot11_station_id mac;
44
45 wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
46
47 mac.header.id = DOT11_STATION_ID;
48 mac.header.len = sizeof(mac) - sizeof(struct acx_header);
49
50 for (i = 0; i < ETH_ALEN; i++)
51 mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
52
53 ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac));
54 if (ret < 0)
55 return ret;
56
57 return 0;
58}
59
60int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
61{
62 struct acx_dot11_default_key default_key;
63 int ret;
64
65 wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
66
67 default_key.header.id = DOT11_DEFAULT_KEY;
68 default_key.header.len = sizeof(default_key) -
69 sizeof(struct acx_header);
70
71 default_key.id = key_id;
72
73 ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key));
74 if (ret < 0) {
75 wl12xx_error("Couldnt set default key");
76 return ret;
77 }
78
79 wl->default_key = key_id;
80
81 return 0;
82}
83
84int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
85{
86 struct acx_wake_up_condition wake_up;
87
88 wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
89
90 wake_up.header.id = ACX_WAKE_UP_CONDITIONS;
91 wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header);
92
93 wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
94 wake_up.listen_interval = listen_interval;
95
96 return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up));
97}
98
99int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
100{
101 int ret;
102 struct acx_sleep_auth auth;
103
104 wl12xx_debug(DEBUG_ACX, "acx sleep auth");
105
106 auth.header.id = ACX_SLEEP_AUTH;
107 auth.header.len = sizeof(auth) - sizeof(struct acx_header);
108
109 auth.sleep_auth = sleep_auth;
110
111 ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth));
112 if (ret < 0)
113 return ret;
114
115 return 0;
116}
117
118int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
119{
120 struct wl12xx_command cmd;
121 struct acx_revision *rev;
122 int ret;
123
124 wl12xx_debug(DEBUG_ACX, "acx fw rev");
125
126 memset(&cmd, 0, sizeof(cmd));
127
128 ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd);
129 if (ret < 0) {
130 wl12xx_warning("ACX_FW_REV interrogate failed");
131 return ret;
132 }
133
134 rev = (struct acx_revision *) &cmd.parameters;
135
136 /* be careful with the buffer sizes */
137 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
138
139 /*
140 * if the firmware version string is exactly
141 * sizeof(rev->fw_version) long or fw_len is less than
142 * sizeof(rev->fw_version) it won't be null terminated
143 */
144 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
145
146 return 0;
147}
148
149int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
150{
151 struct acx_current_tx_power ie;
152 int ret;
153
154 wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
155
156 if (power < 0 || power > 25)
157 return -EINVAL;
158
159 memset(&ie, 0, sizeof(ie));
160
161 ie.header.id = DOT11_CUR_TX_PWR;
162 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
163 ie.current_tx_power = power * 10;
164
165 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
166 if (ret < 0) {
167 wl12xx_warning("configure of tx power failed: %d", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174int wl12xx_acx_feature_cfg(struct wl12xx *wl)
175{
176 struct acx_feature_config feature;
177 int ret;
178
179 wl12xx_debug(DEBUG_ACX, "acx feature cfg");
180
181 memset(&feature, 0, sizeof(feature));
182
183 feature.header.id = ACX_FEATURE_CFG;
184 feature.header.len = sizeof(feature) - sizeof(struct acx_header);
185
186 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
187 feature.data_flow_options = 0;
188 feature.options = 0;
189
190 ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature));
191 if (ret < 0)
192 wl12xx_error("Couldnt set HW encryption");
193
194 return ret;
195}
196
197int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len)
198{
199 struct wl12xx_command cmd;
200 int ret;
201
202 wl12xx_debug(DEBUG_ACX, "acx mem map");
203
204 ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd);
205 if (ret < 0)
206 return ret;
207 else if (cmd.status != CMD_STATUS_SUCCESS)
208 return -EIO;
209
210 memcpy(mem_map, &cmd.parameters, len);
211
212 return 0;
213}
214
215int wl12xx_acx_data_path_params(struct wl12xx *wl,
216 struct acx_data_path_params_resp *data_path)
217{
218 struct acx_data_path_params params;
219 struct wl12xx_command cmd;
220 int ret;
221
222 wl12xx_debug(DEBUG_ACX, "acx data path params");
223
224 params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
225 params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
226
227 params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
228 params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
229
230 params.tx_complete_threshold = 1;
231
232 params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
233
234 params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
235
236 params.header.id = ACX_DATA_PATH_PARAMS;
237 params.header.len = sizeof(params) - sizeof(struct acx_header);
238
239 ret = wl12xx_cmd_configure(wl, &params, sizeof(params));
240 if (ret < 0)
241 return ret;
242
243
244 ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
245 sizeof(struct acx_data_path_params_resp),
246 &cmd);
247
248 if (ret < 0) {
249 wl12xx_warning("failed to read data path parameters: %d", ret);
250 return ret;
251 } else if (cmd.status != CMD_STATUS_SUCCESS) {
252 wl12xx_warning("data path parameter acx status failed");
253 return -EIO;
254 }
255
256 memcpy(data_path, &cmd.parameters, sizeof(*data_path));
257
258 return 0;
259}
260
261int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
262{
263 struct rx_msdu_lifetime msdu_lifetime;
264 int ret;
265
266 wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
267
268 msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME;
269 msdu_lifetime.header.len = sizeof(msdu_lifetime) -
270 sizeof(struct acx_header);
271 msdu_lifetime.lifetime = life_time;
272
273 ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime));
274 if (ret < 0) {
275 wl12xx_warning("failed to set rx msdu life time: %d", ret);
276 return ret;
277 }
278
279 return 0;
280}
281
282int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
283{
284 struct acx_rx_config rx_config;
285 int ret;
286
287 wl12xx_debug(DEBUG_ACX, "acx rx config");
288
289 rx_config.header.id = ACX_RX_CFG;
290 rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header);
291 rx_config.config_options = config;
292 rx_config.filter_options = filter;
293
294 ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config));
295 if (ret < 0) {
296 wl12xx_warning("failed to set rx config: %d", ret);
297 return ret;
298 }
299
300 return 0;
301}
302
303int wl12xx_acx_pd_threshold(struct wl12xx *wl)
304{
305 struct acx_packet_detection packet_detection;
306 int ret;
307
308 wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
309
310 /* FIXME: threshold value not set */
311 packet_detection.header.id = ACX_PD_THRESHOLD;
312 packet_detection.header.len = sizeof(packet_detection) -
313 sizeof(struct acx_header);
314
315 ret = wl12xx_cmd_configure(wl, &packet_detection,
316 sizeof(packet_detection));
317 if (ret < 0) {
318 wl12xx_warning("failed to set pd threshold: %d", ret);
319 return ret;
320 }
321
322 return 0;
323}
324
325int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
326{
327 struct acx_slot slot;
328 int ret;
329
330 wl12xx_debug(DEBUG_ACX, "acx slot");
331
332 slot.header.id = ACX_SLOT;
333 slot.header.len = sizeof(slot) - sizeof(struct acx_header);
334
335 slot.wone_index = STATION_WONE_INDEX;
336 slot.slot_time = slot_time;
337
338 ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot));
339 if (ret < 0) {
340 wl12xx_warning("failed to set slot time: %d", ret);
341 return ret;
342 }
343
344 return 0;
345}
346
347int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
348{
349 struct multicast_grp_addr_start multicast;
350 int ret;
351
352 wl12xx_debug(DEBUG_ACX, "acx group address tbl");
353
354 /* MAC filtering */
355 multicast.header.id = DOT11_GROUP_ADDRESS_TBL;
356 multicast.header.len = sizeof(multicast) - sizeof(struct acx_header);
357
358 multicast.enabled = 0;
359 multicast.num_groups = 0;
360 memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN);
361
362 ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast));
363 if (ret < 0) {
364 wl12xx_warning("failed to set group addr table: %d", ret);
365 return ret;
366 }
367
368 return 0;
369}
370
371int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
372{
373 struct acx_rx_timeout rx_timeout;
374 int ret;
375
376 wl12xx_debug(DEBUG_ACX, "acx service period timeout");
377
378 /* RX timeout */
379 rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
380 rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
381
382 rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
383 rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF;
384
385 ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout));
386 if (ret < 0) {
387 wl12xx_warning("failed to set service period timeout: %d",
388 ret);
389 return ret;
390 }
391
392 return 0;
393}
394
395int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
396{
397 struct acx_rts_threshold rts;
398 int ret;
399
400 wl12xx_debug(DEBUG_ACX, "acx rts threshold");
401
402 rts.header.id = DOT11_RTS_THRESHOLD;
403 rts.header.len = sizeof(rts) - sizeof(struct acx_header);
404
405 rts.threshold = rts_threshold;
406
407 ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts));
408 if (ret < 0) {
409 wl12xx_warning("failed to set rts threshold: %d", ret);
410 return ret;
411 }
412
413 return 0;
414}
415
416int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
417{
418 struct acx_beacon_filter_option beacon_filter;
419 int ret;
420
421 wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
422
423 beacon_filter.header.id = ACX_BEACON_FILTER_OPT;
424 beacon_filter.header.len = sizeof(beacon_filter) -
425 sizeof(struct acx_header);
426
427 beacon_filter.enable = 0;
428 beacon_filter.max_num_beacons = 0;
429
430 ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter));
431 if (ret < 0) {
432 wl12xx_warning("failed to set beacon filter opt: %d", ret);
433 return ret;
434 }
435
436 return 0;
437}
438
439int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
440{
441 struct acx_beacon_filter_ie_table ie_table;
442 int ret;
443
444 wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
445
446 ie_table.header.id = ACX_BEACON_FILTER_TABLE;
447 ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header);
448
449 ie_table.num_ie = 0;
450 memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
451
452 ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table));
453 if (ret < 0) {
454 wl12xx_warning("failed to set beacon filter table: %d", ret);
455 return ret;
456 }
457
458 return 0;
459}
460
461int wl12xx_acx_sg_enable(struct wl12xx *wl)
462{
463 struct acx_bt_wlan_coex pta;
464 int ret;
465
466 wl12xx_debug(DEBUG_ACX, "acx sg enable");
467
468 pta.header.id = ACX_SG_ENABLE;
469 pta.header.len = sizeof(pta) - sizeof(struct acx_header);
470
471 pta.enable = SG_ENABLE;
472
473 ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta));
474 if (ret < 0) {
475 wl12xx_warning("failed to set softgemini enable: %d", ret);
476 return ret;
477 }
478
479 return 0;
480}
481
482int wl12xx_acx_sg_cfg(struct wl12xx *wl)
483{
484 struct acx_bt_wlan_coex_param param;
485 int ret;
486
487 wl12xx_debug(DEBUG_ACX, "acx sg cfg");
488
489 /* BT-WLAN coext parameters */
490 param.header.id = ACX_SG_CFG;
491 param.header.len = sizeof(param) - sizeof(struct acx_header);
492
493 param.min_rate = RATE_INDEX_24MBPS;
494 param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
495 param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
496 param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
497 param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
498 param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
499 param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
500 param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
501 param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
502 param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
503 param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
504 param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
505 param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
506 param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
507 param.antenna_type = PTA_ANTENNA_TYPE_DEF;
508 param.signal_type = PTA_SIGNALING_TYPE_DEF;
509 param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
510 param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
511 param.max_cts = PTA_MAX_NUM_CTS_DEF;
512 param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
513 param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
514 param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
515 param.wlan_elp_hp = PTA_ELP_HP_DEF;
516 param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
517 param.ack_mode_dual_ant = PTA_ACK_MODE_DEF;
518 param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
519 param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
520 param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
521
522 ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
523 if (ret < 0) {
524 wl12xx_warning("failed to set sg config: %d", ret);
525 return ret;
526 }
527
528 return 0;
529}
530
531int wl12xx_acx_cca_threshold(struct wl12xx *wl)
532{
533 struct acx_energy_detection detection;
534 int ret;
535
536 wl12xx_debug(DEBUG_ACX, "acx cca threshold");
537
538 detection.header.id = ACX_CCA_THRESHOLD;
539 detection.header.len = sizeof(detection) - sizeof(struct acx_header);
540
541 detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
542 detection.tx_energy_detection = 0;
543
544 ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection));
545 if (ret < 0) {
546 wl12xx_warning("failed to set cca threshold: %d", ret);
547 return ret;
548 }
549
550 return 0;
551}
552
553int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
554{
555 struct acx_beacon_broadcast bb;
556 int ret;
557
558 wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
559
560 bb.header.id = ACX_BCN_DTIM_OPTIONS;
561 bb.header.len = sizeof(bb) - sizeof(struct acx_header);
562
563 bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
564 bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
565 bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
566 bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
567
568 ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb));
569 if (ret < 0) {
570 wl12xx_warning("failed to set rx config: %d", ret);
571 return ret;
572 }
573
574 return 0;
575}
576
577int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
578{
579 struct acx_aid acx_aid;
580 int ret;
581
582 wl12xx_debug(DEBUG_ACX, "acx aid");
583
584 acx_aid.header.id = ACX_AID;
585 acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header);
586
587 acx_aid.aid = aid;
588
589 ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid));
590 if (ret < 0) {
591 wl12xx_warning("failed to set aid: %d", ret);
592 return ret;
593 }
594
595 return 0;
596}
597
598int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
599{
600 struct acx_event_mask mask;
601 int ret;
602
603 wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
604
605 mask.header.id = ACX_EVENT_MBOX_MASK;
606 mask.header.len = sizeof(mask) - sizeof(struct acx_header);
607
608 /* high event mask is unused */
609 mask.high_event_mask = 0xffffffff;
610
611 mask.event_mask = event_mask;
612
613 ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask));
614 if (ret < 0) {
615 wl12xx_warning("failed to set aid: %d", ret);
616 return ret;
617 }
618
619 return 0;
620}
621
622int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
623{
624 struct acx_preamble ie;
625 int ret;
626
627 wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
628
629 memset(&ie, 0, sizeof(ie));
630
631 ie.header.id = ACX_PREAMBLE_TYPE;
632 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
633 ie.preamble = preamble;
634 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
635 if (ret < 0) {
636 wl12xx_warning("Setting of preamble failed: %d", ret);
637 return ret;
638 }
639 return 0;
640}
641
642int wl12xx_acx_cts_protect(struct wl12xx *wl,
643 enum acx_ctsprotect_type ctsprotect)
644{
645 struct acx_ctsprotect ie;
646 int ret;
647
648 wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
649
650 memset(&ie, 0, sizeof(ie));
651
652 ie.header.id = ACX_CTS_PROTECTION;
653 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
654 ie.ctsprotect = ctsprotect;
655 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
656 if (ret < 0) {
657 wl12xx_warning("Setting of ctsprotect failed: %d", ret);
658 return ret;
659 }
660 return 0;
661}
662
663int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
664{
665 struct wl12xx_command *answer;
666 int ret;
667
668 wl12xx_debug(DEBUG_ACX, "acx statistics");
669
670 answer = kmalloc(sizeof(*answer), GFP_KERNEL);
671 if (!answer) {
672 wl12xx_warning("could not allocate memory for acx statistics");
673 ret = -ENOMEM;
674 goto out;
675 }
676
677 ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer),
678 answer);
679 if (ret < 0) {
680 wl12xx_warning("acx statistics failed: %d", ret);
681 goto out;
682 }
683
684 memcpy(stats, answer->parameters, sizeof(*stats));
685
686out:
687 kfree(answer);
688 return ret;
689}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
new file mode 100644
index 000000000000..fb2d2340993c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -0,0 +1,1245 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_ACX_H__
26#define __WL12XX_ACX_H__
27
28#include "wl12xx.h"
29
30/* Target's information element */
31struct acx_header {
32 u16 id;
33 u16 len;
34};
35
36struct acx_error_counter {
37 struct acx_header header;
38
39 /* The number of PLCP errors since the last time this */
40 /* information element was interrogated. This field is */
41 /* automatically cleared when it is interrogated.*/
42 u32 PLCP_error;
43
44 /* The number of FCS errors since the last time this */
45 /* information element was interrogated. This field is */
46 /* automatically cleared when it is interrogated.*/
47 u32 FCS_error;
48
49 /* The number of MPDUs without PLCP header errors received*/
50 /* since the last time this information element was interrogated. */
51 /* This field is automatically cleared when it is interrogated.*/
52 u32 valid_frame;
53
54 /* the number of missed sequence numbers in the squentially */
55 /* values of frames seq numbers */
56 u32 seq_num_miss;
57} __attribute__ ((packed));
58
59struct acx_revision {
60 struct acx_header header;
61
62 /*
63 * The WiLink firmware version, an ASCII string x.x.x.x,
64 * that uniquely identifies the current firmware.
65 * The left most digit is incremented each time a
66 * significant change is made to the firmware, such as
67 * code redesign or new platform support.
68 * The second digit is incremented when major enhancements
69 * are added or major fixes are made.
70 * The third digit is incremented for each GA release.
71 * The fourth digit is incremented for each build.
72 * The first two digits identify a firmware release version,
73 * in other words, a unique set of features.
74 * The first three digits identify a GA release.
75 */
76 char fw_version[20];
77
78 /*
79 * This 4 byte field specifies the WiLink hardware version.
80 * bits 0 - 15: Reserved.
81 * bits 16 - 23: Version ID - The WiLink version ID
82 * (1 = first spin, 2 = second spin, and so on).
83 * bits 24 - 31: Chip ID - The WiLink chip ID.
84 */
85 u32 hw_version;
86} __attribute__ ((packed));
87
88enum wl12xx_psm_mode {
89 /* Active mode */
90 WL12XX_PSM_CAM = 0,
91
92 /* Power save mode */
93 WL12XX_PSM_PS = 1,
94
95 /* Extreme low power */
96 WL12XX_PSM_ELP = 2,
97};
98
99struct acx_sleep_auth {
100 struct acx_header header;
101
102 /* The sleep level authorization of the device. */
103 /* 0 - Always active*/
104 /* 1 - Power down mode: light / fast sleep*/
105 /* 2 - ELP mode: Deep / Max sleep*/
106 u8 sleep_auth;
107 u8 padding[3];
108} __attribute__ ((packed));
109
110#define TIM_ELE_ID 5
111#define PARTIAL_VBM_MAX 251
112
113struct tim {
114 u8 identity;
115 u8 length;
116 u8 dtim_count;
117 u8 dtim_period;
118 u8 bitmap_ctrl;
119 u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
120} __attribute__ ((packed));
121
122/* Virtual Bit Map update */
123struct vbm_update_request {
124 __le16 len;
125 u8 padding[2];
126 struct tim tim;
127} __attribute__ ((packed));
128
129enum {
130 HOSTIF_PCI_MASTER_HOST_INDIRECT,
131 HOSTIF_PCI_MASTER_HOST_DIRECT,
132 HOSTIF_SLAVE,
133 HOSTIF_PKT_RING,
134 HOSTIF_DONTCARE = 0xFF
135};
136
137#define DEFAULT_UCAST_PRIORITY 0
138#define DEFAULT_RX_Q_PRIORITY 0
139#define DEFAULT_NUM_STATIONS 1
140#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
141#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
142#define TRACE_BUFFER_MAX_SIZE 256
143
144#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
145#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
146#define DP_RX_PACKET_RING_CHUNK_NUM 2
147#define DP_TX_PACKET_RING_CHUNK_NUM 2
148#define DP_TX_COMPLETE_TIME_OUT 20
149#define FW_TX_CMPLT_BLOCK_SIZE 16
150
151struct acx_data_path_params {
152 struct acx_header header;
153
154 u16 rx_packet_ring_chunk_size;
155 u16 tx_packet_ring_chunk_size;
156
157 u8 rx_packet_ring_chunk_num;
158 u8 tx_packet_ring_chunk_num;
159
160 /*
161 * Maximum number of packets that can be gathered
162 * in the TX complete ring before an interrupt
163 * is generated.
164 */
165 u8 tx_complete_threshold;
166
167 /* Number of pending TX complete entries in cyclic ring.*/
168 u8 tx_complete_ring_depth;
169
170 /*
171 * Max num microseconds since a packet enters the TX
172 * complete ring until an interrupt is generated.
173 */
174 u32 tx_complete_timeout;
175} __attribute__ ((packed));
176
177
178struct acx_data_path_params_resp {
179 struct acx_header header;
180
181 u16 rx_packet_ring_chunk_size;
182 u16 tx_packet_ring_chunk_size;
183
184 u8 rx_packet_ring_chunk_num;
185 u8 tx_packet_ring_chunk_num;
186
187 u8 pad[2];
188
189 u32 rx_packet_ring_addr;
190 u32 tx_packet_ring_addr;
191
192 u32 rx_control_addr;
193 u32 tx_control_addr;
194
195 u32 tx_complete_addr;
196} __attribute__ ((packed));
197
198#define TX_MSDU_LIFETIME_MIN 0
199#define TX_MSDU_LIFETIME_MAX 3000
200#define TX_MSDU_LIFETIME_DEF 512
201#define RX_MSDU_LIFETIME_MIN 0
202#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
203#define RX_MSDU_LIFETIME_DEF 512000
204
205struct rx_msdu_lifetime {
206 struct acx_header header;
207
208 /*
209 * The maximum amount of time, in TU, before the
210 * firmware discards the MSDU.
211 */
212 u32 lifetime;
213} __attribute__ ((packed));
214
215/*
216 * RX Config Options Table
217 * Bit Definition
218 * === ==========
219 * 31:14 Reserved
220 * 13 Copy RX Status - when set, write three receive status words
221 * to top of rx'd MPDUs.
222 * When cleared, do not write three status words (added rev 1.5)
223 * 12 Reserved
224 * 11 RX Complete upon FCS error - when set, give rx complete
225 * interrupt for FCS errors, after the rx filtering, e.g. unicast
226 * frames not to us with FCS error will not generate an interrupt.
227 * 10 SSID Filter Enable - When set, the WiLink discards all beacon,
228 * probe request, and probe response frames with an SSID that does
229 * not match the SSID specified by the host in the START/JOIN
230 * command.
231 * When clear, the WiLink receives frames with any SSID.
232 * 9 Broadcast Filter Enable - When set, the WiLink discards all
233 * broadcast frames. When clear, the WiLink receives all received
234 * broadcast frames.
235 * 8:6 Reserved
236 * 5 BSSID Filter Enable - When set, the WiLink discards any frames
237 * with a BSSID that does not match the BSSID specified by the
238 * host.
239 * When clear, the WiLink receives frames from any BSSID.
240 * 4 MAC Addr Filter - When set, the WiLink discards any frames
241 * with a destination address that does not match the MAC address
242 * of the adaptor.
243 * When clear, the WiLink receives frames destined to any MAC
244 * address.
245 * 3 Promiscuous - When set, the WiLink receives all valid frames
246 * (i.e., all frames that pass the FCS check).
247 * When clear, only frames that pass the other filters specified
248 * are received.
249 * 2 FCS - When set, the WiLink includes the FCS with the received
250 * frame.
251 * When cleared, the FCS is discarded.
252 * 1 PLCP header - When set, write all data from baseband to frame
253 * buffer including PHY header.
254 * 0 Reserved - Always equal to 0.
255 *
256 * RX Filter Options Table
257 * Bit Definition
258 * === ==========
259 * 31:12 Reserved - Always equal to 0.
260 * 11 Association - When set, the WiLink receives all association
261 * related frames (association request/response, reassocation
262 * request/response, and disassociation). When clear, these frames
263 * are discarded.
264 * 10 Auth/De auth - When set, the WiLink receives all authentication
265 * and de-authentication frames. When clear, these frames are
266 * discarded.
267 * 9 Beacon - When set, the WiLink receives all beacon frames.
268 * When clear, these frames are discarded.
269 * 8 Contention Free - When set, the WiLink receives all contention
270 * free frames.
271 * When clear, these frames are discarded.
272 * 7 Control - When set, the WiLink receives all control frames.
273 * When clear, these frames are discarded.
274 * 6 Data - When set, the WiLink receives all data frames.
275 * When clear, these frames are discarded.
276 * 5 FCS Error - When set, the WiLink receives frames that have FCS
277 * errors.
278 * When clear, these frames are discarded.
279 * 4 Management - When set, the WiLink receives all management
280 * frames.
281 * When clear, these frames are discarded.
282 * 3 Probe Request - When set, the WiLink receives all probe request
283 * frames.
284 * When clear, these frames are discarded.
285 * 2 Probe Response - When set, the WiLink receives all probe
286 * response frames.
287 * When clear, these frames are discarded.
288 * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
289 * frames.
290 * When clear, these frames are discarded.
291 * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
292 * that have reserved frame types and sub types as defined by the
293 * 802.11 specification.
294 * When clear, these frames are discarded.
295 */
296struct acx_rx_config {
297 struct acx_header header;
298
299 u32 config_options;
300 u32 filter_options;
301} __attribute__ ((packed));
302
303enum {
304 QOS_AC_BE = 0,
305 QOS_AC_BK,
306 QOS_AC_VI,
307 QOS_AC_VO,
308 QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
309};
310
311#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1)
312#define FIRST_AC_INDEX QOS_AC_BE
313#define MAX_NUM_OF_802_1d_TAGS 8
314#define AC_PARAMS_MAX_TSID 15
315#define MAX_APSD_CONF 0xffff
316
317#define QOS_TX_HIGH_MIN (0)
318#define QOS_TX_HIGH_MAX (100)
319
320#define QOS_TX_HIGH_BK_DEF (25)
321#define QOS_TX_HIGH_BE_DEF (35)
322#define QOS_TX_HIGH_VI_DEF (35)
323#define QOS_TX_HIGH_VO_DEF (35)
324
325#define QOS_TX_LOW_BK_DEF (15)
326#define QOS_TX_LOW_BE_DEF (25)
327#define QOS_TX_LOW_VI_DEF (25)
328#define QOS_TX_LOW_VO_DEF (25)
329
330struct acx_tx_queue_qos_config {
331 struct acx_header header;
332
333 u8 qid;
334 u8 pad[3];
335
336 /* Max number of blocks allowd in the queue */
337 u16 high_threshold;
338
339 /* Lowest memory blocks guaranteed for this queue */
340 u16 low_threshold;
341} __attribute__ ((packed));
342
343struct acx_packet_detection {
344 struct acx_header header;
345
346 u32 threshold;
347} __attribute__ ((packed));
348
349
350enum acx_slot_type {
351 SLOT_TIME_LONG = 0,
352 SLOT_TIME_SHORT = 1,
353 DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
354 MAX_SLOT_TIMES = 0xFF
355};
356
357#define STATION_WONE_INDEX 0
358
359struct acx_slot {
360 struct acx_header header;
361
362 u8 wone_index; /* Reserved */
363 u8 slot_time;
364 u8 reserved[6];
365} __attribute__ ((packed));
366
367
368#define ADDRESS_GROUP_MAX (8)
369#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
370
371struct multicast_grp_addr_start {
372 struct acx_header header;
373
374 u8 enabled;
375 u8 num_groups;
376 u8 pad[2];
377 u8 mac_table[ADDRESS_GROUP_MAX_LEN];
378} __attribute__ ((packed));
379
380
381#define RX_TIMEOUT_PS_POLL_MIN 0
382#define RX_TIMEOUT_PS_POLL_MAX (200000)
383#define RX_TIMEOUT_PS_POLL_DEF (15)
384#define RX_TIMEOUT_UPSD_MIN 0
385#define RX_TIMEOUT_UPSD_MAX (200000)
386#define RX_TIMEOUT_UPSD_DEF (15)
387
388struct acx_rx_timeout {
389 struct acx_header header;
390
391 /*
392 * The longest time the STA will wait to receive
393 * traffic from the AP after a PS-poll has been
394 * transmitted.
395 */
396 u16 ps_poll_timeout;
397
398 /*
399 * The longest time the STA will wait to receive
400 * traffic from the AP after a frame has been sent
401 * from an UPSD enabled queue.
402 */
403 u16 upsd_timeout;
404} __attribute__ ((packed));
405
406#define RTS_THRESHOLD_MIN 0
407#define RTS_THRESHOLD_MAX 4096
408#define RTS_THRESHOLD_DEF 2347
409
410struct acx_rts_threshold {
411 struct acx_header header;
412
413 u16 threshold;
414 u8 pad[2];
415} __attribute__ ((packed));
416
417struct acx_beacon_filter_option {
418 struct acx_header header;
419
420 u8 enable;
421
422 /*
423 * The number of beacons without the unicast TIM
424 * bit set that the firmware buffers before
425 * signaling the host about ready frames.
426 * When set to 0 and the filter is enabled, beacons
427 * without the unicast TIM bit set are dropped.
428 */
429 u8 max_num_beacons;
430 u8 pad[2];
431} __attribute__ ((packed));
432
433/*
434 * ACXBeaconFilterEntry (not 221)
435 * Byte Offset Size (Bytes) Definition
436 * =========== ============ ==========
437 * 0 1 IE identifier
438 * 1 1 Treatment bit mask
439 *
440 * ACXBeaconFilterEntry (221)
441 * Byte Offset Size (Bytes) Definition
442 * =========== ============ ==========
443 * 0 1 IE identifier
444 * 1 1 Treatment bit mask
445 * 2 3 OUI
446 * 5 1 Type
447 * 6 2 Version
448 *
449 *
450 * Treatment bit mask - The information element handling:
451 * bit 0 - The information element is compared and transferred
452 * in case of change.
453 * bit 1 - The information element is transferred to the host
454 * with each appearance or disappearance.
455 * Note that both bits can be set at the same time.
456 */
457#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
458#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
459#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
460#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
461#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
462 BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
463 (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
464 BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
465
466struct acx_beacon_filter_ie_table {
467 struct acx_header header;
468
469 u8 num_ie;
470 u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
471 u8 pad[3];
472} __attribute__ ((packed));
473
474enum {
475 SG_ENABLE = 0,
476 SG_DISABLE,
477 SG_SENSE_NO_ACTIVITY,
478 SG_SENSE_ACTIVE
479};
480
481struct acx_bt_wlan_coex {
482 struct acx_header header;
483
484 /*
485 * 0 -> PTA enabled
486 * 1 -> PTA disabled
487 * 2 -> sense no active mode, i.e.
488 * an interrupt is sent upon
489 * BT activity.
490 * 3 -> PTA is switched on in response
491 * to the interrupt sending.
492 */
493 u8 enable;
494 u8 pad[3];
495} __attribute__ ((packed));
496
497#define PTA_ANTENNA_TYPE_DEF (0)
498#define PTA_BT_HP_MAXTIME_DEF (2000)
499#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
500#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
501#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
502#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
503#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
504#define PTA_SIGNALING_TYPE_DEF (1)
505#define PTA_AFH_LEVERAGE_ON_DEF (0)
506#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
507#define PTA_MAX_NUM_CTS_DEF (3)
508#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
509#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
510#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
511#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
512#define PTA_CYCLE_TIME_FAST_DEF (8700)
513#define PTA_RX_FOR_AVALANCHE_DEF (5)
514#define PTA_ELP_HP_DEF (0)
515#define PTA_ANTI_STARVE_PERIOD_DEF (500)
516#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
517#define PTA_ALLOW_PA_SD_DEF (1)
518#define PTA_TIME_BEFORE_BEACON_DEF (6300)
519#define PTA_HPDM_MAX_TIME_DEF (1600)
520#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
521#define PTA_AUTO_MODE_NO_CTS_DEF (0)
522#define PTA_BT_HP_RESPECTED_DEF (3)
523#define PTA_WLAN_RX_MIN_RATE_DEF (24)
524#define PTA_ACK_MODE_DEF (1)
525
526struct acx_bt_wlan_coex_param {
527 struct acx_header header;
528
529 /*
530 * The minimum rate of a received WLAN packet in the STA,
531 * during protective mode, of which a new BT-HP request
532 * during this Rx will always be respected and gain the antenna.
533 */
534 u32 min_rate;
535
536 /* Max time the BT HP will be respected. */
537 u16 bt_hp_max_time;
538
539 /* Max time the WLAN HP will be respected. */
540 u16 wlan_hp_max_time;
541
542 /*
543 * The time between the last BT activity
544 * and the moment when the sense mode returns
545 * to SENSE_INACTIVE.
546 */
547 u16 sense_disable_timer;
548
549 /* Time before the next BT HP instance */
550 u16 rx_time_bt_hp;
551 u16 tx_time_bt_hp;
552
553 /* range: 10-20000 default: 1500 */
554 u16 rx_time_bt_hp_fast;
555 u16 tx_time_bt_hp_fast;
556
557 /* range: 2000-65535 default: 8700 */
558 u16 wlan_cycle_fast;
559
560 /* range: 0 - 15000 (Msec) default: 1000 */
561 u16 bt_anti_starvation_period;
562
563 /* range 400-10000(Usec) default: 3000 */
564 u16 next_bt_lp_packet;
565
566 /* Deafult: worst case for BT DH5 traffic */
567 u16 wake_up_beacon;
568
569 /* range: 0-50000(Usec) default: 1050 */
570 u16 hp_dm_max_guard_time;
571
572 /*
573 * This is to prevent both BT & WLAN antenna
574 * starvation.
575 * Range: 100-50000(Usec) default:2550
576 */
577 u16 next_wlan_packet;
578
579 /* 0 -> shared antenna */
580 u8 antenna_type;
581
582 /*
583 * 0 -> TI legacy
584 * 1 -> Palau
585 */
586 u8 signal_type;
587
588 /*
589 * BT AFH status
590 * 0 -> no AFH
591 * 1 -> from dedicated GPIO
592 * 2 -> AFH on (from host)
593 */
594 u8 afh_leverage_on;
595
596 /*
597 * The number of cycles during which no
598 * TX will be sent after 1 cycle of RX
599 * transaction in protective mode
600 */
601 u8 quiet_cycle_num;
602
603 /*
604 * The maximum number of CTSs that will
605 * be sent for receiving RX packet in
606 * protective mode
607 */
608 u8 max_cts;
609
610 /*
611 * The number of WLAN packets
612 * transferred in common mode before
613 * switching to BT.
614 */
615 u8 wlan_packets_num;
616
617 /*
618 * The number of BT packets
619 * transferred in common mode before
620 * switching to WLAN.
621 */
622 u8 bt_packets_num;
623
624 /* range: 1-255 default: 5 */
625 u8 missed_rx_avalanche;
626
627 /* range: 0-1 default: 1 */
628 u8 wlan_elp_hp;
629
630 /* range: 0 - 15 default: 4 */
631 u8 bt_anti_starvation_cycles;
632
633 u8 ack_mode_dual_ant;
634
635 /*
636 * Allow PA_SD assertion/de-assertion
637 * during enabled BT activity.
638 */
639 u8 pa_sd_enable;
640
641 /*
642 * Enable/Disable PTA in auto mode:
643 * Support Both Active & P.S modes
644 */
645 u8 pta_auto_mode_enable;
646
647 /* range: 0 - 20 default: 1 */
648 u8 bt_hp_respected_num;
649} __attribute__ ((packed));
650
651#define CCA_THRSH_ENABLE_ENERGY_D 0x140A
652#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF
653
654struct acx_energy_detection {
655 struct acx_header header;
656
657 /* The RX Clear Channel Assessment threshold in the PHY */
658 u16 rx_cca_threshold;
659 u8 tx_energy_detection;
660 u8 pad;
661} __attribute__ ((packed));
662
663#define BCN_RX_TIMEOUT_DEF_VALUE 10000
664#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000
665#define RX_BROADCAST_IN_PS_DEF_VALUE 1
666#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
667
668struct acx_beacon_broadcast {
669 struct acx_header header;
670
671 u16 beacon_rx_timeout;
672 u16 broadcast_timeout;
673
674 /* Enables receiving of broadcast packets in PS mode */
675 u8 rx_broadcast_in_ps;
676
677 /* Consecutive PS Poll failures before updating the host */
678 u8 ps_poll_threshold;
679 u8 pad[2];
680} __attribute__ ((packed));
681
682struct acx_event_mask {
683 struct acx_header header;
684
685 u32 event_mask;
686 u32 high_event_mask; /* Unused */
687} __attribute__ ((packed));
688
689#define CFG_RX_FCS BIT(2)
690#define CFG_RX_ALL_GOOD BIT(3)
691#define CFG_UNI_FILTER_EN BIT(4)
692#define CFG_BSSID_FILTER_EN BIT(5)
693#define CFG_MC_FILTER_EN BIT(6)
694#define CFG_MC_ADDR0_EN BIT(7)
695#define CFG_MC_ADDR1_EN BIT(8)
696#define CFG_BC_REJECT_EN BIT(9)
697#define CFG_SSID_FILTER_EN BIT(10)
698#define CFG_RX_INT_FCS_ERROR BIT(11)
699#define CFG_RX_INT_ENCRYPTED BIT(12)
700#define CFG_RX_WR_RX_STATUS BIT(13)
701#define CFG_RX_FILTER_NULTI BIT(14)
702#define CFG_RX_RESERVE BIT(15)
703#define CFG_RX_TIMESTAMP_TSF BIT(16)
704
705#define CFG_RX_RSV_EN BIT(0)
706#define CFG_RX_RCTS_ACK BIT(1)
707#define CFG_RX_PRSP_EN BIT(2)
708#define CFG_RX_PREQ_EN BIT(3)
709#define CFG_RX_MGMT_EN BIT(4)
710#define CFG_RX_FCS_ERROR BIT(5)
711#define CFG_RX_DATA_EN BIT(6)
712#define CFG_RX_CTL_EN BIT(7)
713#define CFG_RX_CF_EN BIT(8)
714#define CFG_RX_BCN_EN BIT(9)
715#define CFG_RX_AUTH_EN BIT(10)
716#define CFG_RX_ASSOC_EN BIT(11)
717
718#define SCAN_PASSIVE BIT(0)
719#define SCAN_5GHZ_BAND BIT(1)
720#define SCAN_TRIGGERED BIT(2)
721#define SCAN_PRIORITY_HIGH BIT(3)
722
723struct acx_fw_gen_frame_rates {
724 struct acx_header header;
725
726 u8 tx_ctrl_frame_rate; /* RATE_* */
727 u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
728 u8 tx_mgt_frame_rate;
729 u8 tx_mgt_frame_mod;
730} __attribute__ ((packed));
731
732/* STA MAC */
733struct dot11_station_id {
734 struct acx_header header;
735
736 u8 mac[ETH_ALEN];
737 u8 pad[2];
738} __attribute__ ((packed));
739
740/* HW encryption keys */
741#define NUM_ACCESS_CATEGORIES_COPY 4
742#define MAX_KEY_SIZE 32
743
744/* When set, disable HW encryption */
745#define DF_ENCRYPTION_DISABLE 0x01
746/* When set, disable HW decryption */
747#define DF_SNIFF_MODE_ENABLE 0x80
748
749struct acx_feature_config {
750 struct acx_header header;
751
752 u32 options;
753 u32 data_flow_options;
754} __attribute__ ((packed));
755
756enum acx_key_action {
757 KEY_ADD_OR_REPLACE = 1,
758 KEY_REMOVE = 2,
759 KEY_SET_ID = 3,
760 MAX_KEY_ACTION = 0xffff,
761};
762
763enum acx_key_type {
764 KEY_WEP_DEFAULT = 0,
765 KEY_WEP_ADDR = 1,
766 KEY_AES_GROUP = 4,
767 KEY_AES_PAIRWISE = 5,
768 KEY_WEP_GROUP = 6,
769 KEY_TKIP_MIC_GROUP = 10,
770 KEY_TKIP_MIC_PAIRWISE = 11,
771};
772
773/*
774 *
775 * key_type_e key size key format
776 * ---------- --------- ----------
777 * 0x00 5, 13, 29 Key data
778 * 0x01 5, 13, 29 Key data
779 * 0x04 16 16 bytes of key data
780 * 0x05 16 16 bytes of key data
781 * 0x0a 32 16 bytes of TKIP key data
782 * 8 bytes of RX MIC key data
783 * 8 bytes of TX MIC key data
784 * 0x0b 32 16 bytes of TKIP key data
785 * 8 bytes of RX MIC key data
786 * 8 bytes of TX MIC key data
787 *
788 */
789
790struct acx_set_key {
791 /* Ignored for default WEP key */
792 u8 addr[ETH_ALEN];
793
794 /* key_action_e */
795 u16 key_action;
796
797 u16 reserved_1;
798
799 /* key size in bytes */
800 u8 key_size;
801
802 /* key_type_e */
803 u8 key_type;
804 u8 ssid_profile;
805
806 /*
807 * TKIP, AES: frame's key id field.
808 * For WEP default key: key id;
809 */
810 u8 id;
811 u8 reserved_2[6];
812 u8 key[MAX_KEY_SIZE];
813 u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
814 u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
815} __attribute__ ((packed));
816
817struct acx_current_tx_power {
818 struct acx_header header;
819
820 u8 current_tx_power;
821 u8 padding[3];
822} __attribute__ ((packed));
823
824struct acx_dot11_default_key {
825 struct acx_header header;
826
827 u8 id;
828 u8 pad[3];
829} __attribute__ ((packed));
830
831struct acx_tsf_info {
832 struct acx_header header;
833
834 u32 current_tsf_msb;
835 u32 current_tsf_lsb;
836 u32 last_TBTT_msb;
837 u32 last_TBTT_lsb;
838 u8 last_dtim_count;
839 u8 pad[3];
840} __attribute__ ((packed));
841
842/* 802.11 PS */
843enum acx_ps_mode {
844 STATION_ACTIVE_MODE,
845 STATION_POWER_SAVE_MODE
846};
847
848struct acx_ps_params {
849 u8 ps_mode; /* STATION_* */
850 u8 send_null_data; /* Do we have to send NULL data packet ? */
851 u8 retries; /* Number of retires for the initial NULL data packet */
852
853 /*
854 * TUs during which the target stays awake after switching
855 * to power save mode.
856 */
857 u8 hang_over_period;
858 u16 null_data_rate;
859 u8 pad[2];
860} __attribute__ ((packed));
861
862enum acx_wake_up_event {
863 WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
864 WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
865 WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */
866 WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */
867 WAKE_UP_EVENT_BITS_MASK = 0x0F
868};
869
870struct acx_wake_up_condition {
871 struct acx_header header;
872
873 u8 wake_up_event; /* Only one bit can be set */
874 u8 listen_interval;
875 u8 pad[2];
876} __attribute__ ((packed));
877
878struct acx_aid {
879 struct acx_header header;
880
881 /*
882 * To be set when associated with an AP.
883 */
884 u16 aid;
885 u8 pad[2];
886} __attribute__ ((packed));
887
888enum acx_preamble_type {
889 ACX_PREAMBLE_LONG = 0,
890 ACX_PREAMBLE_SHORT = 1
891};
892
893struct acx_preamble {
894 struct acx_header header;
895 /*
896 * When set, the WiLink transmits the frames with a short preamble and
897 * when cleared, the WiLink transmits the frames with a long preamble.
898 */
899 u8 preamble;
900 u8 padding[3];
901} __attribute__ ((packed));
902
903enum acx_ctsprotect_type {
904 CTSPROTECT_DISABLE = 0,
905 CTSPROTECT_ENABLE = 1
906};
907
908struct acx_ctsprotect {
909 struct acx_header header;
910 u8 ctsprotect;
911 u8 padding[3];
912} __attribute__ ((packed));
913
914struct acx_tx_statistics {
915 u32 internal_desc_overflow;
916} __attribute__ ((packed));
917
918struct acx_rx_statistics {
919 u32 out_of_mem;
920 u32 hdr_overflow;
921 u32 hw_stuck;
922 u32 dropped;
923 u32 fcs_err;
924 u32 xfr_hint_trig;
925 u32 path_reset;
926 u32 reset_counter;
927} __attribute__ ((packed));
928
929struct acx_dma_statistics {
930 u32 rx_requested;
931 u32 rx_errors;
932 u32 tx_requested;
933 u32 tx_errors;
934} __attribute__ ((packed));
935
936struct acx_isr_statistics {
937 /* host command complete */
938 u32 cmd_cmplt;
939
940 /* fiqisr() */
941 u32 fiqs;
942
943 /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
944 u32 rx_headers;
945
946 /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
947 u32 rx_completes;
948
949 /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
950 u32 rx_mem_overflow;
951
952 /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
953 u32 rx_rdys;
954
955 /* irqisr() */
956 u32 irqs;
957
958 /* (INT_STS_ND & INT_TRIG_TX_PROC) */
959 u32 tx_procs;
960
961 /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
962 u32 decrypt_done;
963
964 /* (INT_STS_ND & INT_TRIG_DMA0) */
965 u32 dma0_done;
966
967 /* (INT_STS_ND & INT_TRIG_DMA1) */
968 u32 dma1_done;
969
970 /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
971 u32 tx_exch_complete;
972
973 /* (INT_STS_ND & INT_TRIG_COMMAND) */
974 u32 commands;
975
976 /* (INT_STS_ND & INT_TRIG_RX_PROC) */
977 u32 rx_procs;
978
979 /* (INT_STS_ND & INT_TRIG_PM_802) */
980 u32 hw_pm_mode_changes;
981
982 /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
983 u32 host_acknowledges;
984
985 /* (INT_STS_ND & INT_TRIG_PM_PCI) */
986 u32 pci_pm;
987
988 /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
989 u32 wakeups;
990
991 /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
992 u32 low_rssi;
993} __attribute__ ((packed));
994
995struct acx_wep_statistics {
996 /* WEP address keys configured */
997 u32 addr_key_count;
998
999 /* default keys configured */
1000 u32 default_key_count;
1001
1002 u32 reserved;
1003
1004 /* number of times that WEP key not found on lookup */
1005 u32 key_not_found;
1006
1007 /* number of times that WEP key decryption failed */
1008 u32 decrypt_fail;
1009
1010 /* WEP packets decrypted */
1011 u32 packets;
1012
1013 /* WEP decrypt interrupts */
1014 u32 interrupt;
1015} __attribute__ ((packed));
1016
1017#define ACX_MISSED_BEACONS_SPREAD 10
1018
1019struct acx_pwr_statistics {
1020 /* the amount of enters into power save mode (both PD & ELP) */
1021 u32 ps_enter;
1022
1023 /* the amount of enters into ELP mode */
1024 u32 elp_enter;
1025
1026 /* the amount of missing beacon interrupts to the host */
1027 u32 missing_bcns;
1028
1029 /* the amount of wake on host-access times */
1030 u32 wake_on_host;
1031
1032 /* the amount of wake on timer-expire */
1033 u32 wake_on_timer_exp;
1034
1035 /* the number of packets that were transmitted with PS bit set */
1036 u32 tx_with_ps;
1037
1038 /* the number of packets that were transmitted with PS bit clear */
1039 u32 tx_without_ps;
1040
1041 /* the number of received beacons */
1042 u32 rcvd_beacons;
1043
1044 /* the number of entering into PowerOn (power save off) */
1045 u32 power_save_off;
1046
1047 /* the number of entries into power save mode */
1048 u16 enable_ps;
1049
1050 /*
1051 * the number of exits from power save, not including failed PS
1052 * transitions
1053 */
1054 u16 disable_ps;
1055
1056 /*
1057 * the number of times the TSF counter was adjusted because
1058 * of drift
1059 */
1060 u32 fix_tsf_ps;
1061
1062 /* Gives statistics about the spread continuous missed beacons.
1063 * The 16 LSB are dedicated for the PS mode.
1064 * The 16 MSB are dedicated for the PS mode.
1065 * cont_miss_bcns_spread[0] - single missed beacon.
1066 * cont_miss_bcns_spread[1] - two continuous missed beacons.
1067 * cont_miss_bcns_spread[2] - three continuous missed beacons.
1068 * ...
1069 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
1070 */
1071 u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
1072
1073 /* the number of beacons in awake mode */
1074 u32 rcvd_awake_beacons;
1075} __attribute__ ((packed));
1076
1077struct acx_mic_statistics {
1078 u32 rx_pkts;
1079 u32 calc_failure;
1080} __attribute__ ((packed));
1081
1082struct acx_aes_statistics {
1083 u32 encrypt_fail;
1084 u32 decrypt_fail;
1085 u32 encrypt_packets;
1086 u32 decrypt_packets;
1087 u32 encrypt_interrupt;
1088 u32 decrypt_interrupt;
1089} __attribute__ ((packed));
1090
1091struct acx_event_statistics {
1092 u32 heart_beat;
1093 u32 calibration;
1094 u32 rx_mismatch;
1095 u32 rx_mem_empty;
1096 u32 rx_pool;
1097 u32 oom_late;
1098 u32 phy_transmit_error;
1099 u32 tx_stuck;
1100} __attribute__ ((packed));
1101
1102struct acx_ps_statistics {
1103 u32 pspoll_timeouts;
1104 u32 upsd_timeouts;
1105 u32 upsd_max_sptime;
1106 u32 upsd_max_apturn;
1107 u32 pspoll_max_apturn;
1108 u32 pspoll_utilization;
1109 u32 upsd_utilization;
1110} __attribute__ ((packed));
1111
1112struct acx_rxpipe_statistics {
1113 u32 rx_prep_beacon_drop;
1114 u32 descr_host_int_trig_rx_data;
1115 u32 beacon_buffer_thres_host_int_trig_rx_data;
1116 u32 missed_beacon_host_int_trig_rx_data;
1117 u32 tx_xfr_host_int_trig_rx_data;
1118} __attribute__ ((packed));
1119
1120struct acx_statistics {
1121 struct acx_header header;
1122
1123 struct acx_tx_statistics tx;
1124 struct acx_rx_statistics rx;
1125 struct acx_dma_statistics dma;
1126 struct acx_isr_statistics isr;
1127 struct acx_wep_statistics wep;
1128 struct acx_pwr_statistics pwr;
1129 struct acx_aes_statistics aes;
1130 struct acx_mic_statistics mic;
1131 struct acx_event_statistics event;
1132 struct acx_ps_statistics ps;
1133 struct acx_rxpipe_statistics rxpipe;
1134} __attribute__ ((packed));
1135
1136enum {
1137 ACX_WAKE_UP_CONDITIONS = 0x0002,
1138 ACX_MEM_CFG = 0x0003,
1139 ACX_SLOT = 0x0004,
1140 ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */
1141 ACX_AC_CFG = 0x0007,
1142 ACX_MEM_MAP = 0x0008,
1143 ACX_AID = 0x000A,
1144 ACX_RADIO_PARAM = 0x000B, /* Not used */
1145 ACX_CFG = 0x000C, /* Not used */
1146 ACX_FW_REV = 0x000D,
1147 ACX_MEDIUM_USAGE = 0x000F,
1148 ACX_RX_CFG = 0x0010,
1149 ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
1150 ACX_BSS_IN_PS = 0x0012, /* for AP only */
1151 ACX_STATISTICS = 0x0013, /* Debug API */
1152 ACX_FEATURE_CFG = 0x0015,
1153 ACX_MISC_CFG = 0x0017, /* Not used */
1154 ACX_TID_CFG = 0x001A,
1155 ACX_BEACON_FILTER_OPT = 0x001F,
1156 ACX_LOW_RSSI = 0x0020,
1157 ACX_NOISE_HIST = 0x0021,
1158 ACX_HDK_VERSION = 0x0022, /* ??? */
1159 ACX_PD_THRESHOLD = 0x0023,
1160 ACX_DATA_PATH_PARAMS = 0x0024, /* WO */
1161 ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */
1162 ACX_CCA_THRESHOLD = 0x0025,
1163 ACX_EVENT_MBOX_MASK = 0x0026,
1164#ifdef FW_RUNNING_AS_AP
1165 ACX_DTIM_PERIOD = 0x0027, /* for AP only */
1166#else
1167 ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */
1168#endif
1169 ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/
1170 ACX_GPIO_CFG = 0x002A, /* Not used */
1171 ACX_GPIO_SET = 0x002B, /* Not used */
1172 ACX_PM_CFG = 0x002C, /* To Be Documented */
1173 ACX_CONN_MONIT_PARAMS = 0x002D,
1174 ACX_AVERAGE_RSSI = 0x002E, /* Not used */
1175 ACX_CONS_TX_FAILURE = 0x002F,
1176 ACX_BCN_DTIM_OPTIONS = 0x0031,
1177 ACX_SG_ENABLE = 0x0032,
1178 ACX_SG_CFG = 0x0033,
1179 ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */
1180 ACX_LOW_SNR = 0x0037, /* To Be Documented */
1181 ACX_BEACON_FILTER_TABLE = 0x0038,
1182 ACX_ARP_IP_FILTER = 0x0039,
1183 ACX_ROAMING_STATISTICS_TBL = 0x003B,
1184 ACX_RATE_POLICY = 0x003D,
1185 ACX_CTS_PROTECTION = 0x003E,
1186 ACX_SLEEP_AUTH = 0x003F,
1187 ACX_PREAMBLE_TYPE = 0x0040,
1188 ACX_ERROR_CNT = 0x0041,
1189 ACX_FW_GEN_FRAME_RATES = 0x0042,
1190 ACX_IBSS_FILTER = 0x0044,
1191 ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
1192 ACX_TSF_INFO = 0x0046,
1193 ACX_CONFIG_PS_WMM = 0x0049,
1194 ACX_ENABLE_RX_DATA_FILTER = 0x004A,
1195 ACX_SET_RX_DATA_FILTER = 0x004B,
1196 ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
1197 ACX_POWER_LEVEL_TABLE = 0x004D,
1198 ACX_BET_ENABLE = 0x0050,
1199 DOT11_STATION_ID = 0x1001,
1200 DOT11_RX_MSDU_LIFE_TIME = 0x1004,
1201 DOT11_CUR_TX_PWR = 0x100D,
1202 DOT11_DEFAULT_KEY = 0x1010,
1203 DOT11_RX_DOT11_MODE = 0x1012,
1204 DOT11_RTS_THRESHOLD = 0x1013,
1205 DOT11_GROUP_ADDRESS_TBL = 0x1014,
1206
1207 MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
1208
1209 MAX_IE = 0xFFFF
1210};
1211
1212
1213int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
1214 u8 mgt_rate, u8 mgt_mod);
1215int wl12xx_acx_station_id(struct wl12xx *wl);
1216int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id);
1217int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval);
1218int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
1219int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
1220int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
1221int wl12xx_acx_feature_cfg(struct wl12xx *wl);
1222int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len);
1223int wl12xx_acx_data_path_params(struct wl12xx *wl,
1224 struct acx_data_path_params_resp *data_path);
1225int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
1226int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter);
1227int wl12xx_acx_pd_threshold(struct wl12xx *wl);
1228int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time);
1229int wl12xx_acx_group_address_tbl(struct wl12xx *wl);
1230int wl12xx_acx_service_period_timeout(struct wl12xx *wl);
1231int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold);
1232int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl);
1233int wl12xx_acx_beacon_filter_table(struct wl12xx *wl);
1234int wl12xx_acx_sg_enable(struct wl12xx *wl);
1235int wl12xx_acx_sg_cfg(struct wl12xx *wl);
1236int wl12xx_acx_cca_threshold(struct wl12xx *wl);
1237int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl);
1238int wl12xx_acx_aid(struct wl12xx *wl, u16 aid);
1239int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask);
1240int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
1241int wl12xx_acx_cts_protect(struct wl12xx *wl,
1242 enum acx_ctsprotect_type ctsprotect);
1243int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
1244
1245#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
new file mode 100644
index 000000000000..48ac08c429bd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -0,0 +1,295 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/gpio.h>
25
26#include "reg.h"
27#include "boot.h"
28#include "spi.h"
29#include "event.h"
30
31static void wl12xx_boot_enable_interrupts(struct wl12xx *wl)
32{
33 enable_irq(wl->irq);
34}
35
36void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl)
37{
38 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
39 wl12xx_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
40}
41
42int wl12xx_boot_soft_reset(struct wl12xx *wl)
43{
44 unsigned long timeout;
45 u32 boot_data;
46
47 /* perform soft reset */
48 wl12xx_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
49
50 /* SOFT_RESET is self clearing */
51 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
52 while (1) {
53 boot_data = wl12xx_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
54 wl12xx_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
55 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
56 break;
57
58 if (time_after(jiffies, timeout)) {
59 /* 1.2 check pWhalBus->uSelfClearTime if the
60 * timeout was reached */
61 wl12xx_error("soft reset timeout");
62 return -1;
63 }
64
65 udelay(SOFT_RESET_STALL_TIME);
66 }
67
68 /* disable Rx/Tx */
69 wl12xx_reg_write32(wl, ENABLE, 0x0);
70
71 /* disable auto calibration on start*/
72 wl12xx_reg_write32(wl, SPARE_A2, 0xffff);
73
74 return 0;
75}
76
77int wl12xx_boot_init_seq(struct wl12xx *wl)
78{
79 u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
80
81 /*
82 * col #1: INTEGER_DIVIDER
83 * col #2: FRACTIONAL_DIVIDER
84 * col #3: ATTN_BB
85 * col #4: ALPHA_BB
86 * col #5: STOP_TIME_BB
87 * col #6: BB_PLL_LOOP_FILTER
88 */
89 static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
90
91 { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/
92 { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
93 { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
94 { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
95 { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */
96 };
97
98 /* read NVS params */
99 scr_pad6 = wl12xx_reg_read32(wl, SCR_PAD6);
100 wl12xx_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
101
102 /* read ELP_CMD */
103 elp_cmd = wl12xx_reg_read32(wl, ELP_CMD);
104 wl12xx_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
105
106 /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
107 ref_freq = scr_pad6 & 0x000000FF;
108 wl12xx_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
109
110 wl12xx_reg_write32(wl, PLL_CAL_TIME, 0x9);
111
112 /*
113 * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
114 */
115 wl12xx_reg_write32(wl, CLK_BUF_TIME, 0x6);
116
117 /*
118 * set the clock detect feature to work in the restart wu procedure
119 * (ELP_CFG_MODE[14]) and Select the clock source type
120 * (ELP_CFG_MODE[13:12])
121 */
122 tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
123 wl12xx_reg_write32(wl, ELP_CFG_MODE, tmp);
124
125 /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
126 elp_cmd |= 0x00000040;
127 wl12xx_reg_write32(wl, ELP_CMD, elp_cmd);
128
129 /* PG 1.2: Set the BB PLL stable time to be 1000usec
130 * (PLL_STABLE_TIME) */
131 wl12xx_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
132
133 /* PG 1.2: read clock request time */
134 init_data = wl12xx_reg_read32(wl, CLK_REQ_TIME);
135
136 /*
137 * PG 1.2: set the clock request time to be ref_clk_settling_time -
138 * 1ms = 4ms
139 */
140 if (init_data > 0x21)
141 tmp = init_data - 0x21;
142 else
143 tmp = 0;
144 wl12xx_reg_write32(wl, CLK_REQ_TIME, tmp);
145
146 /* set BB PLL configurations in RF AFE */
147 wl12xx_reg_write32(wl, 0x003058cc, 0x4B5);
148
149 /* set RF_AFE_REG_5 */
150 wl12xx_reg_write32(wl, 0x003058d4, 0x50);
151
152 /* set RF_AFE_CTRL_REG_2 */
153 wl12xx_reg_write32(wl, 0x00305948, 0x11c001);
154
155 /*
156 * change RF PLL and BB PLL divider for VCO clock and adjust VCO
157 * bais current(RF_AFE_REG_13)
158 */
159 wl12xx_reg_write32(wl, 0x003058f4, 0x1e);
160
161 /* set BB PLL configurations */
162 tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
163 wl12xx_reg_write32(wl, 0x00305840, tmp);
164
165 /* set fractional divider according to Appendix C-BB PLL
166 * Calculations
167 */
168 tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
169 wl12xx_reg_write32(wl, 0x00305844, tmp);
170
171 /* set the initial data for the sigma delta */
172 wl12xx_reg_write32(wl, 0x00305848, 0x3039);
173
174 /*
175 * set the accumulator attenuation value, calibration loop1
176 * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
177 * the VCO gain
178 */
179 tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
180 (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
181 wl12xx_reg_write32(wl, 0x00305854, tmp);
182
183 /*
184 * set the calibration stop time after holdoff time expires and set
185 * settling time HOLD_OFF_TIME_BB
186 */
187 tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
188 wl12xx_reg_write32(wl, 0x00305858, tmp);
189
190 /*
191 * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
192 * constant leakage current to linearize PFD to 0uA -
193 * BB_ILOOPF[7:3]
194 */
195 tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
196 wl12xx_reg_write32(wl, 0x003058f8, tmp);
197
198 /*
199 * set regulator output voltage for n divider to
200 * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
201 * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
202 * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
203 */
204 wl12xx_reg_write32(wl, 0x003058f0, 0x29);
205
206 /* enable restart wakeup sequence (ELP_CMD[0]) */
207 wl12xx_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
208
209 /* restart sequence completed */
210 udelay(2000);
211
212 return 0;
213}
214
215int wl12xx_boot_run_firmware(struct wl12xx *wl)
216{
217 int loop, ret;
218 u32 chip_id, interrupt;
219
220 wl->chip.op_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
221
222 chip_id = wl12xx_reg_read32(wl, CHIP_ID_B);
223
224 wl12xx_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
225
226 if (chip_id != wl->chip.id) {
227 wl12xx_error("chip id doesn't match after firmware boot");
228 return -EIO;
229 }
230
231 /* wait for init to complete */
232 loop = 0;
233 while (loop++ < INIT_LOOP) {
234 udelay(INIT_LOOP_DELAY);
235 interrupt = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
236
237 if (interrupt == 0xffffffff) {
238 wl12xx_error("error reading hardware complete "
239 "init indication");
240 return -EIO;
241 }
242 /* check that ACX_INTR_INIT_COMPLETE is enabled */
243 else if (interrupt & wl->chip.intr_init_complete) {
244 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
245 wl->chip.intr_init_complete);
246 break;
247 }
248 }
249
250 if (loop >= INIT_LOOP) {
251 wl12xx_error("timeout waiting for the hardware to "
252 "complete initialization");
253 return -EIO;
254 }
255
256 /* get hardware config command mail box */
257 wl->cmd_box_addr = wl12xx_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
258
259 /* get hardware config event mail box */
260 wl->event_box_addr = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
261
262 /* set the working partition to its "running" mode offset */
263 wl12xx_set_partition(wl,
264 wl->chip.p_table[PART_WORK].mem.start,
265 wl->chip.p_table[PART_WORK].mem.size,
266 wl->chip.p_table[PART_WORK].reg.start,
267 wl->chip.p_table[PART_WORK].reg.size);
268
269 wl12xx_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
270 wl->cmd_box_addr, wl->event_box_addr);
271
272 /*
273 * in case of full asynchronous mode the firmware event must be
274 * ready to receive event from the command mailbox
275 */
276
277 /* enable gpio interrupts */
278 wl12xx_boot_enable_interrupts(wl);
279
280 wl->chip.op_target_enable_interrupts(wl);
281
282 /* unmask all mbox events */
283 wl->event_mask = 0xffffffff;
284
285 ret = wl12xx_event_unmask(wl);
286 if (ret < 0) {
287 wl12xx_error("EVENT mask setting failed");
288 return ret;
289 }
290
291 wl12xx_event_mbox_config(wl);
292
293 /* firmware startup completed */
294 return 0;
295}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
new file mode 100644
index 000000000000..4fa73132baae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -0,0 +1,40 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __BOOT_H__
25#define __BOOT_H__
26
27#include "wl12xx.h"
28
29int wl12xx_boot_soft_reset(struct wl12xx *wl);
30int wl12xx_boot_init_seq(struct wl12xx *wl);
31int wl12xx_boot_run_firmware(struct wl12xx *wl);
32void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl);
33
34/* number of times we try to read the INIT interrupt */
35#define INIT_LOOP 20000
36
37/* delay between retries */
38#define INIT_LOOP_DELAY 50
39
40#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
new file mode 100644
index 000000000000..f73ab602b7ae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -0,0 +1,353 @@
1#include "cmd.h"
2
3#include <linux/module.h>
4#include <linux/crc7.h>
5#include <linux/spi/spi.h>
6
7#include "wl12xx.h"
8#include "wl12xx_80211.h"
9#include "reg.h"
10#include "spi.h"
11#include "ps.h"
12
13int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len)
14{
15 struct wl12xx_command cmd;
16 unsigned long timeout;
17 size_t cmd_len;
18 u32 intr;
19 int ret = 0;
20
21 memset(&cmd, 0, sizeof(cmd));
22 cmd.id = type;
23 cmd.status = 0;
24 memcpy(cmd.parameters, buf, buf_len);
25 cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN;
26
27 wl12xx_ps_elp_wakeup(wl);
28
29 wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len);
30
31 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
32
33 timeout = jiffies + msecs_to_jiffies(WL12XX_COMMAND_TIMEOUT);
34
35 intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
36 while (!(intr & wl->chip.intr_cmd_complete)) {
37 if (time_after(jiffies, timeout)) {
38 wl12xx_error("command complete timeout");
39 ret = -ETIMEDOUT;
40 goto out;
41 }
42
43 msleep(1);
44
45 intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
46 }
47
48 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
49 wl->chip.intr_cmd_complete);
50
51out:
52 wl12xx_ps_elp_sleep(wl);
53
54 return ret;
55}
56
57int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
58{
59 int ret;
60
61 wl12xx_debug(DEBUG_CMD, "cmd test");
62
63 ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len);
64 if (ret < 0) {
65 wl12xx_warning("TEST command failed");
66 return ret;
67 }
68
69 if (answer) {
70 struct wl12xx_command *cmd_answer;
71
72 /*
73 * The test command got in, we can read the answer.
74 * The answer would be a wl12xx_command, where the
75 * parameter array contains the actual answer.
76 */
77
78 wl12xx_ps_elp_wakeup(wl);
79
80 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
81
82 wl12xx_ps_elp_sleep(wl);
83
84 cmd_answer = buf;
85 if (cmd_answer->status != CMD_STATUS_SUCCESS)
86 wl12xx_error("TEST command answer error: %d",
87 cmd_answer->status);
88 }
89
90 return 0;
91}
92
93
94int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
95 void *answer)
96{
97 struct wl12xx_command *cmd;
98 struct acx_header header;
99 int ret;
100
101 wl12xx_debug(DEBUG_CMD, "cmd interrogate");
102
103 header.id = ie_id;
104 header.len = ie_len - sizeof(header);
105
106 ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header));
107 if (ret < 0) {
108 wl12xx_error("INTERROGATE command failed");
109 return ret;
110 }
111
112 wl12xx_ps_elp_wakeup(wl);
113
114 /* the interrogate command got in, we can read the answer */
115 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer,
116 CMDMBOX_HEADER_LEN + ie_len);
117
118 wl12xx_ps_elp_sleep(wl);
119
120 cmd = answer;
121 if (cmd->status != CMD_STATUS_SUCCESS)
122 wl12xx_error("INTERROGATE command error: %d",
123 cmd->status);
124
125 return 0;
126
127}
128
129int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len)
130{
131 int ret;
132
133 wl12xx_debug(DEBUG_CMD, "cmd configure");
134
135 ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie,
136 ie_len);
137 if (ret < 0) {
138 wl12xx_warning("CONFIGURE command NOK");
139 return ret;
140 }
141
142 return 0;
143
144}
145
146int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
147 void *bitmap, u16 bitmap_len, u8 bitmap_control)
148{
149 struct vbm_update_request vbm;
150 int ret;
151
152 wl12xx_debug(DEBUG_CMD, "cmd vbm");
153
154 /* Count and period will be filled by the target */
155 vbm.tim.bitmap_ctrl = bitmap_control;
156 if (bitmap_len > PARTIAL_VBM_MAX) {
157 wl12xx_warning("cmd vbm len is %d B, truncating to %d",
158 bitmap_len, PARTIAL_VBM_MAX);
159 bitmap_len = PARTIAL_VBM_MAX;
160 }
161 memcpy(vbm.tim.pvb_field, bitmap, bitmap_len);
162 vbm.tim.identity = identity;
163 vbm.tim.length = bitmap_len + 3;
164
165 vbm.len = cpu_to_le16(bitmap_len + 5);
166
167 ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm));
168 if (ret < 0) {
169 wl12xx_error("VBM command failed");
170 return ret;
171 }
172
173 return 0;
174}
175
176int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
177{
178 int ret;
179 u16 cmd_rx, cmd_tx;
180
181 wl12xx_debug(DEBUG_CMD, "cmd data path");
182
183 if (enable) {
184 cmd_rx = CMD_ENABLE_RX;
185 cmd_tx = CMD_ENABLE_TX;
186 } else {
187 cmd_rx = CMD_DISABLE_RX;
188 cmd_tx = CMD_DISABLE_TX;
189 }
190
191 ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel));
192 if (ret < 0) {
193 wl12xx_error("rx %s cmd for channel %d failed",
194 enable ? "start" : "stop", channel);
195 return ret;
196 }
197
198 wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
199 enable ? "start" : "stop", channel);
200
201 ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel));
202 if (ret < 0) {
203 wl12xx_error("tx %s cmd for channel %d failed",
204 enable ? "start" : "stop", channel);
205 return ret;
206 }
207
208 wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
209 enable ? "start" : "stop", channel);
210
211 return 0;
212}
213
214int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
215 u16 beacon_interval, u8 wait)
216{
217 unsigned long timeout;
218 struct cmd_join join = {};
219 int ret, i;
220 u8 *bssid;
221
222 /* FIXME: this should be in main.c */
223 ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
224 DEFAULT_HW_GEN_MODULATION_TYPE,
225 wl->tx_mgmt_frm_rate,
226 wl->tx_mgmt_frm_mod);
227 if (ret < 0)
228 return ret;
229
230 wl12xx_debug(DEBUG_CMD, "cmd join");
231
232 /* Reverse order BSSID */
233 bssid = (u8 *)&join.bssid_lsb;
234 for (i = 0; i < ETH_ALEN; i++)
235 bssid[i] = wl->bssid[ETH_ALEN - i - 1];
236
237 join.rx_config_options = wl->rx_config;
238 join.rx_filter_options = wl->rx_filter;
239
240 join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
241 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
242
243 join.beacon_interval = beacon_interval;
244 join.dtim_interval = dtim_interval;
245 join.bss_type = bss_type;
246 join.channel = wl->channel;
247 join.ctrl = JOIN_CMD_CTRL_TX_FLUSH;
248
249 ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join));
250 if (ret < 0) {
251 wl12xx_error("failed to initiate cmd join");
252 return ret;
253 }
254
255 timeout = msecs_to_jiffies(JOIN_TIMEOUT);
256
257 /*
258 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
259 * simplify locking we just sleep instead, for now
260 */
261 if (wait)
262 msleep(10);
263
264 return 0;
265}
266
267int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
268{
269 int ret;
270 struct acx_ps_params ps_params;
271
272 /* FIXME: this should be in ps.c */
273 ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
274 if (ret < 0) {
275 wl12xx_error("Couldnt set wake up conditions");
276 return ret;
277 }
278
279 wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
280
281 ps_params.ps_mode = ps_mode;
282 ps_params.send_null_data = 1;
283 ps_params.retries = 5;
284 ps_params.hang_over_period = 128;
285 ps_params.null_data_rate = 1; /* 1 Mbps */
286
287 ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params,
288 sizeof(ps_params));
289 if (ret < 0) {
290 wl12xx_error("cmd set_ps_mode failed");
291 return ret;
292 }
293
294 return 0;
295}
296
297int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer)
298{
299 struct cmd_read_write_memory mem_cmd, *mem_answer;
300 struct wl12xx_command cmd;
301 int ret;
302
303 wl12xx_debug(DEBUG_CMD, "cmd read memory");
304
305 memset(&mem_cmd, 0, sizeof(mem_cmd));
306 mem_cmd.addr = addr;
307 mem_cmd.size = len;
308
309 ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd));
310 if (ret < 0) {
311 wl12xx_error("read memory command failed: %d", ret);
312 return ret;
313 }
314
315 /* the read command got in, we can now read the answer */
316 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd,
317 CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
318
319 if (cmd.status != CMD_STATUS_SUCCESS)
320 wl12xx_error("error in read command result: %d", cmd.status);
321
322 mem_answer = (struct cmd_read_write_memory *) cmd.parameters;
323 memcpy(answer, mem_answer->value, len);
324
325 return 0;
326}
327
328int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
329 void *buf, size_t buf_len)
330{
331 struct wl12xx_cmd_packet_template template;
332 int ret;
333
334 wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
335
336 memset(&template, 0, sizeof(template));
337
338 WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
339 buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
340 template.size = cpu_to_le16(buf_len);
341
342 if (buf)
343 memcpy(template.template, buf, buf_len);
344
345 ret = wl12xx_cmd_send(wl, cmd_id, &template,
346 sizeof(template.size) + buf_len);
347 if (ret < 0) {
348 wl12xx_warning("cmd set_template failed: %d", ret);
349 return ret;
350 }
351
352 return 0;
353}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
new file mode 100644
index 000000000000..aa307dcd081f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -0,0 +1,265 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_CMD_H__
26#define __WL12XX_CMD_H__
27
28#include "wl12xx.h"
29
30int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
31int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
32int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
33 void *answer);
34int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
35int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
36 void *bitmap, u16 bitmap_len, u8 bitmap_control);
37int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable);
38int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
39 u16 beacon_interval, u8 wait);
40int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
41int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer);
42int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
43 void *buf, size_t buf_len);
44
45/* unit ms */
46#define WL12XX_COMMAND_TIMEOUT 2000
47
48#define WL12XX_MAX_TEMPLATE_SIZE 300
49
50struct wl12xx_cmd_packet_template {
51 __le16 size;
52 u8 template[WL12XX_MAX_TEMPLATE_SIZE];
53} __attribute__ ((packed));
54
55enum wl12xx_commands {
56 CMD_RESET = 0,
57 CMD_INTERROGATE = 1, /*use this to read information elements*/
58 CMD_CONFIGURE = 2, /*use this to write information elements*/
59 CMD_ENABLE_RX = 3,
60 CMD_ENABLE_TX = 4,
61 CMD_DISABLE_RX = 5,
62 CMD_DISABLE_TX = 6,
63 CMD_SCAN = 8,
64 CMD_STOP_SCAN = 9,
65 CMD_VBM = 10,
66 CMD_START_JOIN = 11,
67 CMD_SET_KEYS = 12,
68 CMD_READ_MEMORY = 13,
69 CMD_WRITE_MEMORY = 14,
70 CMD_BEACON = 19,
71 CMD_PROBE_RESP = 20,
72 CMD_NULL_DATA = 21,
73 CMD_PROBE_REQ = 22,
74 CMD_TEST = 23,
75 CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */
76 CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */
77 CMD_NOISE_HIST = 28,
78 CMD_RX_RESET = 29,
79 CMD_PS_POLL = 30,
80 CMD_QOS_NULL_DATA = 31,
81 CMD_LNA_CONTROL = 32,
82 CMD_SET_BCN_MODE = 33,
83 CMD_MEASUREMENT = 34,
84 CMD_STOP_MEASUREMENT = 35,
85 CMD_DISCONNECT = 36,
86 CMD_SET_PS_MODE = 37,
87 CMD_CHANNEL_SWITCH = 38,
88 CMD_STOP_CHANNEL_SWICTH = 39,
89 CMD_AP_DISCOVERY = 40,
90 CMD_STOP_AP_DISCOVERY = 41,
91 CMD_SPS_SCAN = 42,
92 CMD_STOP_SPS_SCAN = 43,
93 CMD_HEALTH_CHECK = 45,
94 CMD_DEBUG = 46,
95 CMD_TRIGGER_SCAN_TO = 47,
96
97 NUM_COMMANDS,
98 MAX_COMMAND_ID = 0xFFFF,
99};
100
101#define MAX_CMD_PARAMS 572
102
103struct wl12xx_command {
104 u16 id;
105 u16 status;
106 u8 parameters[MAX_CMD_PARAMS];
107};
108
109enum {
110 CMD_MAILBOX_IDLE = 0,
111 CMD_STATUS_SUCCESS = 1,
112 CMD_STATUS_UNKNOWN_CMD = 2,
113 CMD_STATUS_UNKNOWN_IE = 3,
114 CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
115 CMD_STATUS_RX_BUSY = 13,
116 CMD_STATUS_INVALID_PARAM = 14,
117 CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
118 CMD_STATUS_OUT_OF_MEMORY = 16,
119 CMD_STATUS_STA_TABLE_FULL = 17,
120 CMD_STATUS_RADIO_ERROR = 18,
121 CMD_STATUS_WRONG_NESTING = 19,
122 CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
123 CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
124 MAX_COMMAND_STATUS = 0xff
125};
126
127
128/*
129 * CMD_READ_MEMORY
130 *
131 * The host issues this command to read the WiLink device memory/registers.
132 *
133 * Note: The Base Band address has special handling (16 bits registers and
134 * addresses). For more information, see the hardware specification.
135 */
136/*
137 * CMD_WRITE_MEMORY
138 *
139 * The host issues this command to write the WiLink device memory/registers.
140 *
141 * The Base Band address has special handling (16 bits registers and
142 * addresses). For more information, see the hardware specification.
143 */
144#define MAX_READ_SIZE 256
145
146struct cmd_read_write_memory {
147 /* The address of the memory to read from or write to.*/
148 u32 addr;
149
150 /* The amount of data in bytes to read from or write to the WiLink
151 * device.*/
152 u32 size;
153
154 /* The actual value read from or written to the Wilink. The source
155 of this field is the Host in WRITE command or the Wilink in READ
156 command. */
157 u8 value[MAX_READ_SIZE];
158};
159
160#define CMDMBOX_HEADER_LEN 4
161#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
162
163
164struct basic_scan_parameters {
165 u32 rx_config_options;
166 u32 rx_filter_options;
167
168 /*
169 * Scan options:
170 * bit 0: When this bit is set, passive scan.
171 * bit 1: Band, when this bit is set we scan
172 * in the 5Ghz band.
173 * bit 2: voice mode, 0 for normal scan.
174 * bit 3: scan priority, 1 for high priority.
175 */
176 u16 scan_options;
177
178 /* Number of channels to scan */
179 u8 num_channels;
180
181 /* Number opf probe requests to send, per channel */
182 u8 num_probe_requests;
183
184 /* Rate and modulation for probe requests */
185 u16 tx_rate;
186
187 u8 tid_trigger;
188 u8 ssid_len;
189 u32 ssid[8];
190
191} __attribute__ ((packed));
192
193struct basic_scan_channel_parameters {
194 u32 min_duration; /* in TU */
195 u32 max_duration; /* in TU */
196 u32 bssid_lsb;
197 u16 bssid_msb;
198
199 /*
200 * bits 0-3: Early termination count.
201 * bits 4-5: Early termination condition.
202 */
203 u8 early_termination;
204
205 u8 tx_power_att;
206 u8 channel;
207 u8 pad[3];
208} __attribute__ ((packed));
209
210/* SCAN parameters */
211#define SCAN_MAX_NUM_OF_CHANNELS 16
212
213struct cmd_scan {
214 struct basic_scan_parameters params;
215 struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
216} __attribute__ ((packed));
217
218enum {
219 BSS_TYPE_IBSS = 0,
220 BSS_TYPE_STA_BSS = 2,
221 BSS_TYPE_AP_BSS = 3,
222 MAX_BSS_TYPE = 0xFF
223};
224
225#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
226#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */
227
228
229struct cmd_join {
230 u32 bssid_lsb;
231 u16 bssid_msb;
232 u16 beacon_interval; /* in TBTTs */
233 u32 rx_config_options;
234 u32 rx_filter_options;
235
236 /*
237 * The target uses this field to determine the rate at
238 * which to transmit control frame responses (such as
239 * ACK or CTS frames).
240 */
241 u16 basic_rate_set;
242 u8 dtim_interval;
243 u8 tx_ctrl_frame_rate; /* OBSOLETE */
244 u8 tx_ctrl_frame_mod; /* OBSOLETE */
245 /*
246 * bits 0-2: This bitwise field specifies the type
247 * of BSS to start or join (BSS_TYPE_*).
248 * bit 4: Band - The radio band in which to join
249 * or start.
250 * 0 - 2.4GHz band
251 * 1 - 5GHz band
252 * bits 3, 5-7: Reserved
253 */
254 u8 bss_type;
255 u8 channel;
256 u8 ssid_len;
257 u8 ssid[IW_ESSID_MAX_SIZE];
258 u8 ctrl; /* JOIN_CMD_CTRL_* */
259 u8 tx_mgt_frame_rate; /* OBSOLETE */
260 u8 tx_mgt_frame_mod; /* OBSOLETE */
261 u8 reserved;
262} __attribute__ ((packed));
263
264
265#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
new file mode 100644
index 000000000000..cdb368ce4dae
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -0,0 +1,508 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include "debugfs.h"
25
26#include <linux/skbuff.h>
27
28#include "wl12xx.h"
29#include "acx.h"
30
31/* ms */
32#define WL12XX_DEBUGFS_STATS_LIFETIME 1000
33
34/* debugfs macros idea from mac80211 */
35
36#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
37static ssize_t name## _read(struct file *file, char __user *userbuf, \
38 size_t count, loff_t *ppos) \
39{ \
40 struct wl12xx *wl = file->private_data; \
41 char buf[buflen]; \
42 int res; \
43 \
44 res = scnprintf(buf, buflen, fmt "\n", ##value); \
45 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
46} \
47 \
48static const struct file_operations name## _ops = { \
49 .read = name## _read, \
50 .open = wl12xx_open_file_generic, \
51};
52
53#define DEBUGFS_ADD(name, parent) \
54 wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
55 wl, &name## _ops); \
56 if (IS_ERR(wl->debugfs.name)) { \
57 ret = PTR_ERR(wl->debugfs.name); \
58 wl->debugfs.name = NULL; \
59 goto out; \
60 }
61
62#define DEBUGFS_DEL(name) \
63 do { \
64 debugfs_remove(wl->debugfs.name); \
65 wl->debugfs.name = NULL; \
66 } while (0)
67
68#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
69static ssize_t sub## _ ##name## _read(struct file *file, \
70 char __user *userbuf, \
71 size_t count, loff_t *ppos) \
72{ \
73 struct wl12xx *wl = file->private_data; \
74 char buf[buflen]; \
75 int res; \
76 \
77 wl12xx_debugfs_update_stats(wl); \
78 \
79 res = scnprintf(buf, buflen, fmt "\n", \
80 wl->stats.fw_stats->sub.name); \
81 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
82} \
83 \
84static const struct file_operations sub## _ ##name## _ops = { \
85 .read = sub## _ ##name## _read, \
86 .open = wl12xx_open_file_generic, \
87};
88
89#define DEBUGFS_FWSTATS_ADD(sub, name) \
90 DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
91
92#define DEBUGFS_FWSTATS_DEL(sub, name) \
93 DEBUGFS_DEL(sub## _ ##name)
94
95static void wl12xx_debugfs_update_stats(struct wl12xx *wl)
96{
97 mutex_lock(&wl->mutex);
98
99 if (wl->state == WL12XX_STATE_ON &&
100 time_after(jiffies, wl->stats.fw_stats_update +
101 msecs_to_jiffies(WL12XX_DEBUGFS_STATS_LIFETIME))) {
102 wl12xx_acx_statistics(wl, wl->stats.fw_stats);
103 wl->stats.fw_stats_update = jiffies;
104 }
105
106 mutex_unlock(&wl->mutex);
107}
108
109static int wl12xx_open_file_generic(struct inode *inode, struct file *file)
110{
111 file->private_data = inode->i_private;
112 return 0;
113}
114
115DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
116
117DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
118DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
119DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
120DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
121DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
122DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
123DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
124DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
125
126DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
127DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
128DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
129DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
130
131DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
132DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
133DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
134DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
135DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
136DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
137DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
138DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
139DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
140DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
141DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
142DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
143DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
144DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
145DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
146DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
147DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
148DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
149
150DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
151DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
152/* skipping wep.reserved */
153DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
154DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
155DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
156DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
157
158DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
159DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
160DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
161DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
162DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
163DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
164DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
165DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
166DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
167DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
168DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
169DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
170/* skipping cont_miss_bcns_spread for now */
171DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
172
173DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
174DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
175
176DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
177DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
178DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
179DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
180DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
181DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
182
183DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
184DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
185DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
186DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
187DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
188DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
189DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
190DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
191
192DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
193DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
194DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
195DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
196DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
197DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
198DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
199
200DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
201DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
202DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
203 20, "%u");
204DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
205DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
206
207DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
208DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
209 wl->stats.excessive_retries);
210
211static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
212 size_t count, loff_t *ppos)
213{
214 struct wl12xx *wl = file->private_data;
215 u32 queue_len;
216 char buf[20];
217 int res;
218
219 queue_len = skb_queue_len(&wl->tx_queue);
220
221 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
222 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
223}
224
225static const struct file_operations tx_queue_len_ops = {
226 .read = tx_queue_len_read,
227 .open = wl12xx_open_file_generic,
228};
229
230static void wl12xx_debugfs_delete_files(struct wl12xx *wl)
231{
232 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
233
234 DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
235 DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
236 DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
237 DEBUGFS_FWSTATS_DEL(rx, dropped);
238 DEBUGFS_FWSTATS_DEL(rx, fcs_err);
239 DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
240 DEBUGFS_FWSTATS_DEL(rx, path_reset);
241 DEBUGFS_FWSTATS_DEL(rx, reset_counter);
242
243 DEBUGFS_FWSTATS_DEL(dma, rx_requested);
244 DEBUGFS_FWSTATS_DEL(dma, rx_errors);
245 DEBUGFS_FWSTATS_DEL(dma, tx_requested);
246 DEBUGFS_FWSTATS_DEL(dma, tx_errors);
247
248 DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
249 DEBUGFS_FWSTATS_DEL(isr, fiqs);
250 DEBUGFS_FWSTATS_DEL(isr, rx_headers);
251 DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
252 DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
253 DEBUGFS_FWSTATS_DEL(isr, irqs);
254 DEBUGFS_FWSTATS_DEL(isr, tx_procs);
255 DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
256 DEBUGFS_FWSTATS_DEL(isr, dma0_done);
257 DEBUGFS_FWSTATS_DEL(isr, dma1_done);
258 DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
259 DEBUGFS_FWSTATS_DEL(isr, commands);
260 DEBUGFS_FWSTATS_DEL(isr, rx_procs);
261 DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
262 DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
263 DEBUGFS_FWSTATS_DEL(isr, pci_pm);
264 DEBUGFS_FWSTATS_DEL(isr, wakeups);
265 DEBUGFS_FWSTATS_DEL(isr, low_rssi);
266
267 DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
268 DEBUGFS_FWSTATS_DEL(wep, default_key_count);
269 /* skipping wep.reserved */
270 DEBUGFS_FWSTATS_DEL(wep, key_not_found);
271 DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
272 DEBUGFS_FWSTATS_DEL(wep, packets);
273 DEBUGFS_FWSTATS_DEL(wep, interrupt);
274
275 DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
276 DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
277 DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
278 DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
279 DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
280 DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
281 DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
282 DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
283 DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
284 DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
285 DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
286 DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
287 /* skipping cont_miss_bcns_spread for now */
288 DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
289
290 DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
291 DEBUGFS_FWSTATS_DEL(mic, calc_failure);
292
293 DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
294 DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
295 DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
296 DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
297 DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
298 DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
299
300 DEBUGFS_FWSTATS_DEL(event, heart_beat);
301 DEBUGFS_FWSTATS_DEL(event, calibration);
302 DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
303 DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
304 DEBUGFS_FWSTATS_DEL(event, rx_pool);
305 DEBUGFS_FWSTATS_DEL(event, oom_late);
306 DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
307 DEBUGFS_FWSTATS_DEL(event, tx_stuck);
308
309 DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
310 DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
311 DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
312 DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
313 DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
314 DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
315 DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
316
317 DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
318 DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
319 DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
320 DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
321 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
322
323 DEBUGFS_DEL(tx_queue_len);
324 DEBUGFS_DEL(retry_count);
325 DEBUGFS_DEL(excessive_retries);
326}
327
328static int wl12xx_debugfs_add_files(struct wl12xx *wl)
329{
330 int ret = 0;
331
332 DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
333
334 DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
335 DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
336 DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
337 DEBUGFS_FWSTATS_ADD(rx, dropped);
338 DEBUGFS_FWSTATS_ADD(rx, fcs_err);
339 DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
340 DEBUGFS_FWSTATS_ADD(rx, path_reset);
341 DEBUGFS_FWSTATS_ADD(rx, reset_counter);
342
343 DEBUGFS_FWSTATS_ADD(dma, rx_requested);
344 DEBUGFS_FWSTATS_ADD(dma, rx_errors);
345 DEBUGFS_FWSTATS_ADD(dma, tx_requested);
346 DEBUGFS_FWSTATS_ADD(dma, tx_errors);
347
348 DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
349 DEBUGFS_FWSTATS_ADD(isr, fiqs);
350 DEBUGFS_FWSTATS_ADD(isr, rx_headers);
351 DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
352 DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
353 DEBUGFS_FWSTATS_ADD(isr, irqs);
354 DEBUGFS_FWSTATS_ADD(isr, tx_procs);
355 DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
356 DEBUGFS_FWSTATS_ADD(isr, dma0_done);
357 DEBUGFS_FWSTATS_ADD(isr, dma1_done);
358 DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
359 DEBUGFS_FWSTATS_ADD(isr, commands);
360 DEBUGFS_FWSTATS_ADD(isr, rx_procs);
361 DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
362 DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
363 DEBUGFS_FWSTATS_ADD(isr, pci_pm);
364 DEBUGFS_FWSTATS_ADD(isr, wakeups);
365 DEBUGFS_FWSTATS_ADD(isr, low_rssi);
366
367 DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
368 DEBUGFS_FWSTATS_ADD(wep, default_key_count);
369 /* skipping wep.reserved */
370 DEBUGFS_FWSTATS_ADD(wep, key_not_found);
371 DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
372 DEBUGFS_FWSTATS_ADD(wep, packets);
373 DEBUGFS_FWSTATS_ADD(wep, interrupt);
374
375 DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
376 DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
377 DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
378 DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
379 DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
380 DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
381 DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
382 DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
383 DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
384 DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
385 DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
386 DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
387 /* skipping cont_miss_bcns_spread for now */
388 DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
389
390 DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
391 DEBUGFS_FWSTATS_ADD(mic, calc_failure);
392
393 DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
394 DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
395 DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
396 DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
397 DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
398 DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
399
400 DEBUGFS_FWSTATS_ADD(event, heart_beat);
401 DEBUGFS_FWSTATS_ADD(event, calibration);
402 DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
403 DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
404 DEBUGFS_FWSTATS_ADD(event, rx_pool);
405 DEBUGFS_FWSTATS_ADD(event, oom_late);
406 DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
407 DEBUGFS_FWSTATS_ADD(event, tx_stuck);
408
409 DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
410 DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
411 DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
412 DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
413 DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
414 DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
415 DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
416
417 DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
418 DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
419 DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
420 DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
421 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
422
423 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
424 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
425 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
426
427out:
428 if (ret < 0)
429 wl12xx_debugfs_delete_files(wl);
430
431 return ret;
432}
433
434void wl12xx_debugfs_reset(struct wl12xx *wl)
435{
436 memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
437 wl->stats.retry_count = 0;
438 wl->stats.excessive_retries = 0;
439}
440
441int wl12xx_debugfs_init(struct wl12xx *wl)
442{
443 int ret;
444
445 wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
446
447 if (IS_ERR(wl->debugfs.rootdir)) {
448 ret = PTR_ERR(wl->debugfs.rootdir);
449 wl->debugfs.rootdir = NULL;
450 goto err;
451 }
452
453 wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
454 wl->debugfs.rootdir);
455
456 if (IS_ERR(wl->debugfs.fw_statistics)) {
457 ret = PTR_ERR(wl->debugfs.fw_statistics);
458 wl->debugfs.fw_statistics = NULL;
459 goto err_root;
460 }
461
462 wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
463 GFP_KERNEL);
464
465 if (!wl->stats.fw_stats) {
466 ret = -ENOMEM;
467 goto err_fw;
468 }
469
470 wl->stats.fw_stats_update = jiffies;
471
472 ret = wl12xx_debugfs_add_files(wl);
473
474 if (ret < 0)
475 goto err_file;
476
477 return 0;
478
479err_file:
480 kfree(wl->stats.fw_stats);
481 wl->stats.fw_stats = NULL;
482
483err_fw:
484 debugfs_remove(wl->debugfs.fw_statistics);
485 wl->debugfs.fw_statistics = NULL;
486
487err_root:
488 debugfs_remove(wl->debugfs.rootdir);
489 wl->debugfs.rootdir = NULL;
490
491err:
492 return ret;
493}
494
495void wl12xx_debugfs_exit(struct wl12xx *wl)
496{
497 wl12xx_debugfs_delete_files(wl);
498
499 kfree(wl->stats.fw_stats);
500 wl->stats.fw_stats = NULL;
501
502 debugfs_remove(wl->debugfs.fw_statistics);
503 wl->debugfs.fw_statistics = NULL;
504
505 debugfs_remove(wl->debugfs.rootdir);
506 wl->debugfs.rootdir = NULL;
507
508}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
new file mode 100644
index 000000000000..562cdcbcc874
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/debugfs.h
@@ -0,0 +1,33 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef WL12XX_DEBUGFS_H
25#define WL12XX_DEBUGFS_H
26
27#include "wl12xx.h"
28
29int wl12xx_debugfs_init(struct wl12xx *wl);
30void wl12xx_debugfs_exit(struct wl12xx *wl);
31void wl12xx_debugfs_reset(struct wl12xx *wl);
32
33#endif /* WL12XX_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
new file mode 100644
index 000000000000..99529ca89a7e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -0,0 +1,127 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include "wl12xx.h"
26#include "reg.h"
27#include "spi.h"
28#include "event.h"
29#include "ps.h"
30
31static int wl12xx_event_scan_complete(struct wl12xx *wl,
32 struct event_mailbox *mbox)
33{
34 wl12xx_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
35 mbox->scheduled_scan_status,
36 mbox->scheduled_scan_channels);
37
38 if (wl->scanning) {
39 mutex_unlock(&wl->mutex);
40 ieee80211_scan_completed(wl->hw, false);
41 mutex_lock(&wl->mutex);
42 wl->scanning = false;
43 }
44
45 return 0;
46}
47
48static void wl12xx_event_mbox_dump(struct event_mailbox *mbox)
49{
50 wl12xx_debug(DEBUG_EVENT, "MBOX DUMP:");
51 wl12xx_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
52 wl12xx_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
53}
54
55static int wl12xx_event_process(struct wl12xx *wl, struct event_mailbox *mbox)
56{
57 int ret;
58 u32 vector;
59
60 wl12xx_event_mbox_dump(mbox);
61
62 vector = mbox->events_vector & ~(mbox->events_mask);
63 wl12xx_debug(DEBUG_EVENT, "vector: 0x%x", vector);
64
65 if (vector & SCAN_COMPLETE_EVENT_ID) {
66 ret = wl12xx_event_scan_complete(wl, mbox);
67 if (ret < 0)
68 return ret;
69 }
70
71 if (vector & BSS_LOSE_EVENT_ID) {
72 wl12xx_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
73
74 if (wl->psm_requested && wl->psm) {
75 ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
76 if (ret < 0)
77 return ret;
78 }
79 }
80
81 return 0;
82}
83
84int wl12xx_event_unmask(struct wl12xx *wl)
85{
86 int ret;
87
88 ret = wl12xx_acx_event_mbox_mask(wl, ~(wl->event_mask));
89 if (ret < 0)
90 return ret;
91
92 return 0;
93}
94
95void wl12xx_event_mbox_config(struct wl12xx *wl)
96{
97 wl->mbox_ptr[0] = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
98 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
99
100 wl12xx_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
101 wl->mbox_ptr[0], wl->mbox_ptr[1]);
102}
103
104int wl12xx_event_handle(struct wl12xx *wl, u8 mbox_num)
105{
106 struct event_mailbox mbox;
107 int ret;
108
109 wl12xx_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
110
111 if (mbox_num > 1)
112 return -EINVAL;
113
114 /* first we read the mbox descriptor */
115 wl12xx_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
116 sizeof(struct event_mailbox));
117
118 /* process the descriptor */
119 ret = wl12xx_event_process(wl, &mbox);
120 if (ret < 0)
121 return ret;
122
123 /* then we let the firmware know it can go on...*/
124 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
125
126 return 0;
127}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
new file mode 100644
index 000000000000..1f4c2f7438a7
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -0,0 +1,121 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_EVENT_H__
26#define __WL12XX_EVENT_H__
27
28/*
29 * Mbox events
30 *
31 * The event mechanism is based on a pair of event buffers (buffers A and
32 * B) at fixed locations in the target's memory. The host processes one
33 * buffer while the other buffer continues to collect events. If the host
34 * is not processing events, an interrupt is issued to signal that a buffer
35 * is ready. Once the host is done with processing events from one buffer,
36 * it signals the target (with an ACK interrupt) that the event buffer is
37 * free.
38 */
39
40enum {
41 RESERVED1_EVENT_ID = BIT(0),
42 RESERVED2_EVENT_ID = BIT(1),
43 MEASUREMENT_START_EVENT_ID = BIT(2),
44 SCAN_COMPLETE_EVENT_ID = BIT(3),
45 CALIBRATION_COMPLETE_EVENT_ID = BIT(4),
46 ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5),
47 PS_REPORT_EVENT_ID = BIT(6),
48 SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7),
49 HEALTH_REPORT_EVENT_ID = BIT(8),
50 ACI_DETECTION_EVENT_ID = BIT(9),
51 DEBUG_REPORT_EVENT_ID = BIT(10),
52 MAC_STATUS_EVENT_ID = BIT(11),
53 DISCONNECT_EVENT_COMPLETE_ID = BIT(12),
54 JOIN_EVENT_COMPLETE_ID = BIT(13),
55 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14),
56 BSS_LOSE_EVENT_ID = BIT(15),
57 ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16),
58 MEASUREMENT_COMPLETE_EVENT_ID = BIT(17),
59 AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18),
60 SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19),
61 PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20),
62 RESET_BSS_EVENT_ID = BIT(21),
63 REGAINED_BSS_EVENT_ID = BIT(22),
64 ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23),
65 ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24),
66 ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25),
67
68 DBG_EVENT_ID = BIT(26),
69 BT_PTA_SENSE_EVENT_ID = BIT(27),
70 BT_PTA_PREDICTION_EVENT_ID = BIT(28),
71 BT_PTA_AVALANCHE_EVENT_ID = BIT(29),
72
73 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30),
74
75 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
76};
77
78struct event_debug_report {
79 u8 debug_event_id;
80 u8 num_params;
81 u16 pad;
82 u32 report_1;
83 u32 report_2;
84 u32 report_3;
85} __attribute__ ((packed));
86
87struct event_mailbox {
88 u32 events_vector;
89 u32 events_mask;
90 u32 reserved_1;
91 u32 reserved_2;
92
93 char average_rssi_level;
94 u8 ps_status;
95 u8 channel_switch_status;
96 u8 scheduled_scan_status;
97
98 /* Channels scanned by the scheduled scan */
99 u16 scheduled_scan_channels;
100
101 /* If bit 0 is set -> target's fatal error */
102 u16 health_report;
103 u16 bad_fft_counter;
104 u8 bt_pta_sense_info;
105 u8 bt_pta_protective_info;
106 u32 reserved;
107 u32 debug_report[2];
108
109 /* Number of FCS errors since last event */
110 u32 fcs_err_counter;
111
112 struct event_debug_report report;
113 u8 average_snr_level;
114 u8 padding[19];
115} __attribute__ ((packed));
116
117int wl12xx_event_unmask(struct wl12xx *wl);
118void wl12xx_event_mbox_config(struct wl12xx *wl);
119int wl12xx_event_handle(struct wl12xx *wl, u8 mbox);
120
121#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
new file mode 100644
index 000000000000..2a573a6010bd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -0,0 +1,200 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26
27#include "init.h"
28#include "wl12xx_80211.h"
29#include "acx.h"
30#include "cmd.h"
31
32int wl12xx_hw_init_hwenc_config(struct wl12xx *wl)
33{
34 int ret;
35
36 ret = wl12xx_acx_feature_cfg(wl);
37 if (ret < 0) {
38 wl12xx_warning("couldn't set feature config");
39 return ret;
40 }
41
42 ret = wl12xx_acx_default_key(wl, wl->default_key);
43 if (ret < 0) {
44 wl12xx_warning("couldn't set default key");
45 return ret;
46 }
47
48 return 0;
49}
50
51int wl12xx_hw_init_templates_config(struct wl12xx *wl)
52{
53 int ret;
54 u8 partial_vbm[PARTIAL_VBM_MAX];
55
56 /* send empty templates for fw memory reservation */
57 ret = wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
58 sizeof(struct wl12xx_probe_req_template));
59 if (ret < 0)
60 return ret;
61
62 ret = wl12xx_cmd_template_set(wl, CMD_NULL_DATA, NULL,
63 sizeof(struct wl12xx_null_data_template));
64 if (ret < 0)
65 return ret;
66
67 ret = wl12xx_cmd_template_set(wl, CMD_PS_POLL, NULL,
68 sizeof(struct wl12xx_ps_poll_template));
69 if (ret < 0)
70 return ret;
71
72 ret = wl12xx_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
73 sizeof
74 (struct wl12xx_qos_null_data_template));
75 if (ret < 0)
76 return ret;
77
78 ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
79 sizeof
80 (struct wl12xx_probe_resp_template));
81 if (ret < 0)
82 return ret;
83
84 ret = wl12xx_cmd_template_set(wl, CMD_BEACON, NULL,
85 sizeof
86 (struct wl12xx_beacon_template));
87 if (ret < 0)
88 return ret;
89
90 /* tim templates, first reserve space then allocate an empty one */
91 memset(partial_vbm, 0, PARTIAL_VBM_MAX);
92 ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
93 if (ret < 0)
94 return ret;
95
96 ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
97 if (ret < 0)
98 return ret;
99
100 return 0;
101}
102
103int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter)
104{
105 int ret;
106
107 ret = wl12xx_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
108 if (ret < 0)
109 return ret;
110
111 ret = wl12xx_acx_rx_config(wl, config, filter);
112 if (ret < 0)
113 return ret;
114
115 return 0;
116}
117
118int wl12xx_hw_init_phy_config(struct wl12xx *wl)
119{
120 int ret;
121
122 ret = wl12xx_acx_pd_threshold(wl);
123 if (ret < 0)
124 return ret;
125
126 ret = wl12xx_acx_slot(wl, DEFAULT_SLOT_TIME);
127 if (ret < 0)
128 return ret;
129
130 ret = wl12xx_acx_group_address_tbl(wl);
131 if (ret < 0)
132 return ret;
133
134 ret = wl12xx_acx_service_period_timeout(wl);
135 if (ret < 0)
136 return ret;
137
138 ret = wl12xx_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
139 if (ret < 0)
140 return ret;
141
142 return 0;
143}
144
145int wl12xx_hw_init_beacon_filter(struct wl12xx *wl)
146{
147 int ret;
148
149 ret = wl12xx_acx_beacon_filter_opt(wl);
150 if (ret < 0)
151 return ret;
152
153 ret = wl12xx_acx_beacon_filter_table(wl);
154 if (ret < 0)
155 return ret;
156
157 return 0;
158}
159
160int wl12xx_hw_init_pta(struct wl12xx *wl)
161{
162 int ret;
163
164 ret = wl12xx_acx_sg_enable(wl);
165 if (ret < 0)
166 return ret;
167
168 ret = wl12xx_acx_sg_cfg(wl);
169 if (ret < 0)
170 return ret;
171
172 return 0;
173}
174
175int wl12xx_hw_init_energy_detection(struct wl12xx *wl)
176{
177 int ret;
178
179 ret = wl12xx_acx_cca_threshold(wl);
180 if (ret < 0)
181 return ret;
182
183 return 0;
184}
185
186int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl)
187{
188 int ret;
189
190 ret = wl12xx_acx_bcn_dtim_options(wl);
191 if (ret < 0)
192 return ret;
193
194 return 0;
195}
196
197int wl12xx_hw_init_power_auth(struct wl12xx *wl)
198{
199 return wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
200}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
new file mode 100644
index 000000000000..c8b6cd0b7c3e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -0,0 +1,40 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __WL12XX_INIT_H__
25#define __WL12XX_INIT_H__
26
27#include "wl12xx.h"
28
29int wl12xx_hw_init_hwenc_config(struct wl12xx *wl);
30int wl12xx_hw_init_templates_config(struct wl12xx *wl);
31int wl12xx_hw_init_mem_config(struct wl12xx *wl);
32int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter);
33int wl12xx_hw_init_phy_config(struct wl12xx *wl);
34int wl12xx_hw_init_beacon_filter(struct wl12xx *wl);
35int wl12xx_hw_init_pta(struct wl12xx *wl);
36int wl12xx_hw_init_energy_detection(struct wl12xx *wl);
37int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl);
38int wl12xx_hw_init_power_auth(struct wl12xx *wl);
39
40#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
new file mode 100644
index 000000000000..744f4ce5993b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -0,0 +1,1358 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/interrupt.h>
26#include <linux/firmware.h>
27#include <linux/delay.h>
28#include <linux/irq.h>
29#include <linux/spi/spi.h>
30#include <linux/crc32.h>
31#include <linux/etherdevice.h>
32#include <linux/spi/wl12xx.h>
33
34#include "wl12xx.h"
35#include "wl12xx_80211.h"
36#include "reg.h"
37#include "wl1251.h"
38#include "spi.h"
39#include "event.h"
40#include "tx.h"
41#include "rx.h"
42#include "ps.h"
43#include "init.h"
44#include "debugfs.h"
45
46static void wl12xx_disable_interrupts(struct wl12xx *wl)
47{
48 disable_irq(wl->irq);
49}
50
51static void wl12xx_power_off(struct wl12xx *wl)
52{
53 wl->set_power(false);
54}
55
56static void wl12xx_power_on(struct wl12xx *wl)
57{
58 wl->set_power(true);
59}
60
61static irqreturn_t wl12xx_irq(int irq, void *cookie)
62{
63 struct wl12xx *wl;
64
65 wl12xx_debug(DEBUG_IRQ, "IRQ");
66
67 wl = cookie;
68
69 schedule_work(&wl->irq_work);
70
71 return IRQ_HANDLED;
72}
73
74static int wl12xx_fetch_firmware(struct wl12xx *wl)
75{
76 const struct firmware *fw;
77 int ret;
78
79 ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
80
81 if (ret < 0) {
82 wl12xx_error("could not get firmware: %d", ret);
83 return ret;
84 }
85
86 if (fw->size % 4) {
87 wl12xx_error("firmware size is not multiple of 32 bits: %d",
88 fw->size);
89 ret = -EILSEQ;
90 goto out;
91 }
92
93 wl->fw_len = fw->size;
94 wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
95
96 if (!wl->fw) {
97 wl12xx_error("could not allocate memory for the firmware");
98 ret = -ENOMEM;
99 goto out;
100 }
101
102 memcpy(wl->fw, fw->data, wl->fw_len);
103
104 ret = 0;
105
106out:
107 release_firmware(fw);
108
109 return ret;
110}
111
112static int wl12xx_fetch_nvs(struct wl12xx *wl)
113{
114 const struct firmware *fw;
115 int ret;
116
117 ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
118
119 if (ret < 0) {
120 wl12xx_error("could not get nvs file: %d", ret);
121 return ret;
122 }
123
124 if (fw->size % 4) {
125 wl12xx_error("nvs size is not multiple of 32 bits: %d",
126 fw->size);
127 ret = -EILSEQ;
128 goto out;
129 }
130
131 wl->nvs_len = fw->size;
132 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
133
134 if (!wl->nvs) {
135 wl12xx_error("could not allocate memory for the nvs file");
136 ret = -ENOMEM;
137 goto out;
138 }
139
140 memcpy(wl->nvs, fw->data, wl->nvs_len);
141
142 ret = 0;
143
144out:
145 release_firmware(fw);
146
147 return ret;
148}
149
150static void wl12xx_fw_wakeup(struct wl12xx *wl)
151{
152 u32 elp_reg;
153
154 elp_reg = ELPCTRL_WAKE_UP;
155 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
156 elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
157
158 if (!(elp_reg & ELPCTRL_WLAN_READY)) {
159 wl12xx_warning("WLAN not ready");
160 elp_reg = ELPCTRL_WAKE_UP_WLAN_READY;
161 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
162 }
163}
164
165static int wl12xx_chip_wakeup(struct wl12xx *wl)
166{
167 int ret = 0;
168
169 wl12xx_power_on(wl);
170 msleep(wl->chip.power_on_sleep);
171 wl12xx_spi_reset(wl);
172 wl12xx_spi_init(wl);
173
174 /* We don't need a real memory partition here, because we only want
175 * to use the registers at this point. */
176 wl12xx_set_partition(wl,
177 0x00000000,
178 0x00000000,
179 REGISTERS_BASE,
180 REGISTERS_DOWN_SIZE);
181
182 /* ELP module wake up */
183 wl12xx_fw_wakeup(wl);
184
185 /* whal_FwCtrl_BootSm() */
186
187 /* 0. read chip id from CHIP_ID */
188 wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B);
189
190 /* 1. check if chip id is valid */
191
192 switch (wl->chip.id) {
193 case CHIP_ID_1251_PG12:
194 wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
195 wl->chip.id);
196
197 wl1251_setup(wl);
198
199 break;
200 case CHIP_ID_1271_PG10:
201 case CHIP_ID_1251_PG10:
202 case CHIP_ID_1251_PG11:
203 default:
204 wl12xx_error("unsupported chip id: 0x%x", wl->chip.id);
205 ret = -ENODEV;
206 goto out;
207 }
208
209 if (wl->fw == NULL) {
210 ret = wl12xx_fetch_firmware(wl);
211 if (ret < 0)
212 goto out;
213 }
214
215 /* No NVS from netlink, try to get it from the filesystem */
216 if (wl->nvs == NULL) {
217 ret = wl12xx_fetch_nvs(wl);
218 if (ret < 0)
219 goto out;
220 }
221
222out:
223 return ret;
224}
225
226static void wl12xx_filter_work(struct work_struct *work)
227{
228 struct wl12xx *wl =
229 container_of(work, struct wl12xx, filter_work);
230 int ret;
231
232 mutex_lock(&wl->mutex);
233
234 if (wl->state == WL12XX_STATE_OFF)
235 goto out;
236
237 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
238 if (ret < 0)
239 goto out;
240
241out:
242 mutex_unlock(&wl->mutex);
243}
244
245int wl12xx_plt_start(struct wl12xx *wl)
246{
247 int ret;
248
249 wl12xx_notice("power up");
250
251 if (wl->state != WL12XX_STATE_OFF) {
252 wl12xx_error("cannot go into PLT state because not "
253 "in off state: %d", wl->state);
254 return -EBUSY;
255 }
256
257 wl->state = WL12XX_STATE_PLT;
258
259 ret = wl12xx_chip_wakeup(wl);
260 if (ret < 0)
261 return ret;
262
263 ret = wl->chip.op_boot(wl);
264 if (ret < 0)
265 return ret;
266
267 wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
268
269 ret = wl->chip.op_plt_init(wl);
270 if (ret < 0)
271 return ret;
272
273 return 0;
274}
275
276int wl12xx_plt_stop(struct wl12xx *wl)
277{
278 wl12xx_notice("power down");
279
280 if (wl->state != WL12XX_STATE_PLT) {
281 wl12xx_error("cannot power down because not in PLT "
282 "state: %d", wl->state);
283 return -EBUSY;
284 }
285
286 wl12xx_disable_interrupts(wl);
287 wl12xx_power_off(wl);
288
289 wl->state = WL12XX_STATE_OFF;
290
291 return 0;
292}
293
294
295static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
296{
297 struct wl12xx *wl = hw->priv;
298
299 skb_queue_tail(&wl->tx_queue, skb);
300
301 schedule_work(&wl->tx_work);
302
303 /*
304 * The workqueue is slow to process the tx_queue and we need stop
305 * the queue here, otherwise the queue will get too long.
306 */
307 if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) {
308 ieee80211_stop_queues(wl->hw);
309
310 /*
311 * FIXME: this is racy, the variable is not properly
312 * protected. Maybe fix this by removing the stupid
313 * variable altogether and checking the real queue state?
314 */
315 wl->tx_queue_stopped = true;
316 }
317
318 return NETDEV_TX_OK;
319}
320
321static int wl12xx_op_start(struct ieee80211_hw *hw)
322{
323 struct wl12xx *wl = hw->priv;
324 int ret = 0;
325
326 wl12xx_debug(DEBUG_MAC80211, "mac80211 start");
327
328 mutex_lock(&wl->mutex);
329
330 if (wl->state != WL12XX_STATE_OFF) {
331 wl12xx_error("cannot start because not in off state: %d",
332 wl->state);
333 ret = -EBUSY;
334 goto out;
335 }
336
337 ret = wl12xx_chip_wakeup(wl);
338 if (ret < 0)
339 return ret;
340
341 ret = wl->chip.op_boot(wl);
342 if (ret < 0)
343 goto out;
344
345 ret = wl->chip.op_hw_init(wl);
346 if (ret < 0)
347 goto out;
348
349 ret = wl12xx_acx_station_id(wl);
350 if (ret < 0)
351 goto out;
352
353 wl->state = WL12XX_STATE_ON;
354
355 wl12xx_info("firmware booted (%s)", wl->chip.fw_ver);
356
357out:
358 if (ret < 0)
359 wl12xx_power_off(wl);
360
361 mutex_unlock(&wl->mutex);
362
363 return ret;
364}
365
366static void wl12xx_op_stop(struct ieee80211_hw *hw)
367{
368 struct wl12xx *wl = hw->priv;
369
370 wl12xx_info("down");
371
372 wl12xx_debug(DEBUG_MAC80211, "mac80211 stop");
373
374 mutex_lock(&wl->mutex);
375
376 WARN_ON(wl->state != WL12XX_STATE_ON);
377
378 if (wl->scanning) {
379 mutex_unlock(&wl->mutex);
380 ieee80211_scan_completed(wl->hw, true);
381 mutex_lock(&wl->mutex);
382 wl->scanning = false;
383 }
384
385 wl->state = WL12XX_STATE_OFF;
386
387 wl12xx_disable_interrupts(wl);
388
389 mutex_unlock(&wl->mutex);
390
391 cancel_work_sync(&wl->irq_work);
392 cancel_work_sync(&wl->tx_work);
393 cancel_work_sync(&wl->filter_work);
394
395 mutex_lock(&wl->mutex);
396
397 /* let's notify MAC80211 about the remaining pending TX frames */
398 wl12xx_tx_flush(wl);
399
400 wl12xx_power_off(wl);
401
402 memset(wl->bssid, 0, ETH_ALEN);
403 wl->listen_int = 1;
404 wl->bss_type = MAX_BSS_TYPE;
405
406 wl->data_in_count = 0;
407 wl->rx_counter = 0;
408 wl->rx_handled = 0;
409 wl->rx_current_buffer = 0;
410 wl->rx_last_id = 0;
411 wl->next_tx_complete = 0;
412 wl->elp = false;
413 wl->psm = 0;
414 wl->tx_queue_stopped = false;
415 wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
416
417 wl12xx_debugfs_reset(wl);
418
419 mutex_unlock(&wl->mutex);
420}
421
422static int wl12xx_op_add_interface(struct ieee80211_hw *hw,
423 struct ieee80211_if_init_conf *conf)
424{
425 struct wl12xx *wl = hw->priv;
426 DECLARE_MAC_BUF(mac);
427 int ret = 0;
428
429 wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
430 conf->type, print_mac(mac, conf->mac_addr));
431
432 mutex_lock(&wl->mutex);
433
434 switch (conf->type) {
435 case NL80211_IFTYPE_STATION:
436 wl->bss_type = BSS_TYPE_STA_BSS;
437 break;
438 case NL80211_IFTYPE_ADHOC:
439 wl->bss_type = BSS_TYPE_IBSS;
440 break;
441 default:
442 ret = -EOPNOTSUPP;
443 goto out;
444 }
445
446 if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
447 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
448 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
449 ret = wl12xx_acx_station_id(wl);
450 if (ret < 0)
451 goto out;
452 }
453
454out:
455 mutex_unlock(&wl->mutex);
456 return ret;
457}
458
459static void wl12xx_op_remove_interface(struct ieee80211_hw *hw,
460 struct ieee80211_if_init_conf *conf)
461{
462 wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface");
463}
464
465static int wl12xx_build_null_data(struct wl12xx *wl)
466{
467 struct wl12xx_null_data_template template;
468
469 if (!is_zero_ether_addr(wl->bssid)) {
470 memcpy(template.header.da, wl->bssid, ETH_ALEN);
471 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
472 } else {
473 memset(template.header.da, 0xff, ETH_ALEN);
474 memset(template.header.bssid, 0xff, ETH_ALEN);
475 }
476
477 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
478 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
479 IEEE80211_STYPE_NULLFUNC);
480
481 return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template,
482 sizeof(template));
483
484}
485
486static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid)
487{
488 struct wl12xx_ps_poll_template template;
489
490 memcpy(template.bssid, wl->bssid, ETH_ALEN);
491 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
492 template.aid = aid;
493 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
494
495 return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template,
496 sizeof(template));
497
498}
499
500static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)
501{
502 struct wl12xx *wl = hw->priv;
503 struct ieee80211_conf *conf = &hw->conf;
504 int channel, ret = 0;
505
506 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
507
508 wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
509 channel,
510 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
511 conf->power_level);
512
513 mutex_lock(&wl->mutex);
514
515 if (channel != wl->channel) {
516 /* FIXME: use beacon interval provided by mac80211 */
517 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
518 if (ret < 0)
519 goto out;
520
521 wl->channel = channel;
522 }
523
524 ret = wl12xx_build_null_data(wl);
525 if (ret < 0)
526 goto out;
527
528 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
529 wl12xx_info("psm enabled");
530
531 wl->psm_requested = true;
532
533 /*
534 * We enter PSM only if we're already associated.
535 * If we're not, we'll enter it when joining an SSID,
536 * through the bss_info_changed() hook.
537 */
538 ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
539 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
540 wl->psm_requested) {
541 wl12xx_info("psm disabled");
542
543 wl->psm_requested = false;
544
545 if (wl->psm)
546 ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
547 }
548
549 if (conf->power_level != wl->power_level) {
550 ret = wl12xx_acx_tx_power(wl, conf->power_level);
551 if (ret < 0)
552 goto out;
553
554 wl->power_level = conf->power_level;
555 }
556
557out:
558 mutex_unlock(&wl->mutex);
559 return ret;
560}
561
562#define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
563 FIF_ALLMULTI | \
564 FIF_FCSFAIL | \
565 FIF_BCN_PRBRESP_PROMISC | \
566 FIF_CONTROL | \
567 FIF_OTHER_BSS)
568
569static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
570 unsigned int changed,
571 unsigned int *total,
572 int mc_count,
573 struct dev_addr_list *mc_list)
574{
575 struct wl12xx *wl = hw->priv;
576
577 wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter");
578
579 *total &= WL12XX_SUPPORTED_FILTERS;
580 changed &= WL12XX_SUPPORTED_FILTERS;
581
582 if (changed == 0)
583 /* no filters which we support changed */
584 return;
585
586 /* FIXME: wl->rx_config and wl->rx_filter are not protected */
587
588 wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
589 wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
590
591 if (*total & FIF_PROMISC_IN_BSS) {
592 wl->rx_config |= CFG_BSSID_FILTER_EN;
593 wl->rx_config |= CFG_RX_ALL_GOOD;
594 }
595 if (*total & FIF_ALLMULTI)
596 /*
597 * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
598 * all multicast frames
599 */
600 wl->rx_config &= ~CFG_MC_FILTER_EN;
601 if (*total & FIF_FCSFAIL)
602 wl->rx_filter |= CFG_RX_FCS_ERROR;
603 if (*total & FIF_BCN_PRBRESP_PROMISC) {
604 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
605 wl->rx_config &= ~CFG_SSID_FILTER_EN;
606 }
607 if (*total & FIF_CONTROL)
608 wl->rx_filter |= CFG_RX_CTL_EN;
609 if (*total & FIF_OTHER_BSS)
610 wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
611
612 /*
613 * FIXME: workqueues need to be properly cancelled on stop(), for
614 * now let's just disable changing the filter settings. They will
615 * be updated any on config().
616 */
617 /* schedule_work(&wl->filter_work); */
618}
619
620/* HW encryption */
621static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key,
622 enum set_key_cmd cmd,
623 struct ieee80211_key_conf *mac80211_key,
624 const u8 *addr)
625{
626 switch (mac80211_key->alg) {
627 case ALG_WEP:
628 if (is_broadcast_ether_addr(addr))
629 key->key_type = KEY_WEP_DEFAULT;
630 else
631 key->key_type = KEY_WEP_ADDR;
632
633 mac80211_key->hw_key_idx = mac80211_key->keyidx;
634 break;
635 case ALG_TKIP:
636 if (is_broadcast_ether_addr(addr))
637 key->key_type = KEY_TKIP_MIC_GROUP;
638 else
639 key->key_type = KEY_TKIP_MIC_PAIRWISE;
640
641 mac80211_key->hw_key_idx = mac80211_key->keyidx;
642 break;
643 case ALG_CCMP:
644 if (is_broadcast_ether_addr(addr))
645 key->key_type = KEY_AES_GROUP;
646 else
647 key->key_type = KEY_AES_PAIRWISE;
648 mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
649 break;
650 default:
651 wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg);
652 return -EOPNOTSUPP;
653 }
654
655 return 0;
656}
657
658static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
659 struct ieee80211_vif *vif,
660 struct ieee80211_sta *sta,
661 struct ieee80211_key_conf *key)
662{
663 struct wl12xx *wl = hw->priv;
664 struct acx_set_key wl_key;
665 const u8 *addr;
666 int ret;
667
668 static const u8 bcast_addr[ETH_ALEN] =
669 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
670
671 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
672
673 memset(&wl_key, 0, sizeof(wl_key));
674
675 addr = sta ? sta->addr : bcast_addr;
676
677 wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
678 wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
679 wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
680 key->alg, key->keyidx, key->keylen, key->flags);
681 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
682
683 mutex_lock(&wl->mutex);
684
685 switch (cmd) {
686 case SET_KEY:
687 wl_key.key_action = KEY_ADD_OR_REPLACE;
688 break;
689 case DISABLE_KEY:
690 wl_key.key_action = KEY_REMOVE;
691 break;
692 default:
693 wl12xx_error("Unsupported key cmd 0x%x", cmd);
694 break;
695 }
696
697 ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr);
698 if (ret < 0) {
699 wl12xx_error("Set KEY type failed");
700 goto out;
701 }
702
703 if (wl_key.key_type != KEY_WEP_DEFAULT)
704 memcpy(wl_key.addr, addr, ETH_ALEN);
705
706 if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) ||
707 (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) {
708 /*
709 * We get the key in the following form:
710 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
711 * but the target is expecting:
712 * TKIP - RX MIC - TX MIC
713 */
714 memcpy(wl_key.key, key->key, 16);
715 memcpy(wl_key.key + 16, key->key + 24, 8);
716 memcpy(wl_key.key + 24, key->key + 16, 8);
717
718 } else {
719 memcpy(wl_key.key, key->key, key->keylen);
720 }
721 wl_key.key_size = key->keylen;
722
723 wl_key.id = key->keyidx;
724 wl_key.ssid_profile = 0;
725
726 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key));
727
728 if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) {
729 wl12xx_error("Set KEY failed");
730 ret = -EOPNOTSUPP;
731 goto out;
732 }
733
734out:
735 mutex_unlock(&wl->mutex);
736 return ret;
737}
738
739static int wl12xx_build_basic_rates(char *rates)
740{
741 u8 index = 0;
742
743 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
744 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
745 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
746 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
747
748 return index;
749}
750
751static int wl12xx_build_extended_rates(char *rates)
752{
753 u8 index = 0;
754
755 rates[index++] = IEEE80211_OFDM_RATE_6MB;
756 rates[index++] = IEEE80211_OFDM_RATE_9MB;
757 rates[index++] = IEEE80211_OFDM_RATE_12MB;
758 rates[index++] = IEEE80211_OFDM_RATE_18MB;
759 rates[index++] = IEEE80211_OFDM_RATE_24MB;
760 rates[index++] = IEEE80211_OFDM_RATE_36MB;
761 rates[index++] = IEEE80211_OFDM_RATE_48MB;
762 rates[index++] = IEEE80211_OFDM_RATE_54MB;
763
764 return index;
765}
766
767
768static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len)
769{
770 struct wl12xx_probe_req_template template;
771 struct wl12xx_ie_rates *rates;
772 char *ptr;
773 u16 size;
774
775 ptr = (char *)&template;
776 size = sizeof(struct ieee80211_header);
777
778 memset(template.header.da, 0xff, ETH_ALEN);
779 memset(template.header.bssid, 0xff, ETH_ALEN);
780 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
781 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
782
783 /* IEs */
784 /* SSID */
785 template.ssid.header.id = WLAN_EID_SSID;
786 template.ssid.header.len = ssid_len;
787 if (ssid_len && ssid)
788 memcpy(template.ssid.ssid, ssid, ssid_len);
789 size += sizeof(struct wl12xx_ie_header) + ssid_len;
790 ptr += size;
791
792 /* Basic Rates */
793 rates = (struct wl12xx_ie_rates *)ptr;
794 rates->header.id = WLAN_EID_SUPP_RATES;
795 rates->header.len = wl12xx_build_basic_rates(rates->rates);
796 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
797 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
798
799 /* Extended rates */
800 rates = (struct wl12xx_ie_rates *)ptr;
801 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
802 rates->header.len = wl12xx_build_extended_rates(rates->rates);
803 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
804
805 wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
806
807 return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template,
808 size);
809}
810
811static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
812 u8 active_scan, u8 high_prio, u8 num_channels,
813 u8 probe_requests)
814{
815 int i, ret;
816 u32 split_scan = 0;
817 u16 scan_options = 0;
818 struct cmd_scan *params;
819 struct wl12xx_command *cmd_answer;
820
821 if (wl->scanning)
822 return -EINVAL;
823
824 params = kzalloc(sizeof(*params), GFP_KERNEL);
825 if (!params)
826 return -ENOMEM;
827
828 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
829 params->params.rx_filter_options =
830 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
831
832 /* High priority scan */
833 if (!active_scan)
834 scan_options |= SCAN_PASSIVE;
835 if (high_prio)
836 scan_options |= SCAN_PRIORITY_HIGH;
837 params->params.scan_options = scan_options;
838
839 params->params.num_channels = num_channels;
840 params->params.num_probe_requests = probe_requests;
841 params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
842 params->params.tid_trigger = 0;
843
844 for (i = 0; i < num_channels; i++) {
845 params->channels[i].min_duration = cpu_to_le32(30000);
846 params->channels[i].max_duration = cpu_to_le32(60000);
847 memset(&params->channels[i].bssid_lsb, 0xff, 4);
848 memset(&params->channels[i].bssid_msb, 0xff, 2);
849 params->channels[i].early_termination = 0;
850 params->channels[i].tx_power_att = 0;
851 params->channels[i].channel = i + 1;
852 memset(params->channels[i].pad, 0, 3);
853 }
854
855 for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
856 memset(&params->channels[i], 0,
857 sizeof(struct basic_scan_channel_parameters));
858
859 if (len && ssid) {
860 params->params.ssid_len = len;
861 memcpy(params->params.ssid, ssid, len);
862 } else {
863 params->params.ssid_len = 0;
864 memset(params->params.ssid, 0, 32);
865 }
866
867 ret = wl12xx_build_probe_req(wl, ssid, len);
868 if (ret < 0) {
869 wl12xx_error("PROBE request template failed");
870 goto out;
871 }
872
873 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan,
874 sizeof(u32));
875 if (ret < 0) {
876 wl12xx_error("Split SCAN failed");
877 goto out;
878 }
879
880 wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
881
882 wl->scanning = true;
883
884 ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
885 if (ret < 0)
886 wl12xx_error("SCAN failed");
887
888 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
889
890 cmd_answer = (struct wl12xx_command *) params;
891 if (cmd_answer->status != CMD_STATUS_SUCCESS) {
892 wl12xx_error("TEST command answer error: %d",
893 cmd_answer->status);
894 wl->scanning = false;
895 ret = -EIO;
896 goto out;
897 }
898
899out:
900 kfree(params);
901 return ret;
902
903}
904
905static int wl12xx_op_hw_scan(struct ieee80211_hw *hw,
906 struct cfg80211_scan_request *req)
907{
908 struct wl12xx *wl = hw->priv;
909 int ret;
910 u8 *ssid = NULL;
911 size_t ssid_len = 0;
912
913 wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan");
914
915 if (req->n_ssids) {
916 ssid = req->ssids[0].ssid;
917 ssid_len = req->ssids[0].ssid_len;
918 }
919
920 mutex_lock(&wl->mutex);
921 ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
922 mutex_unlock(&wl->mutex);
923
924 return ret;
925}
926
927static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
928{
929 struct wl12xx *wl = hw->priv;
930 int ret;
931
932 ret = wl12xx_acx_rts_threshold(wl, (u16) value);
933
934 if (ret < 0)
935 wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret);
936
937 return ret;
938}
939
940static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
941 struct ieee80211_vif *vif,
942 struct ieee80211_bss_conf *bss_conf,
943 u32 changed)
944{
945 enum acx_ps_mode mode;
946 struct wl12xx *wl = hw->priv;
947 struct sk_buff *beacon;
948 int ret;
949
950 wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed");
951
952 mutex_lock(&wl->mutex);
953
954 if (changed & BSS_CHANGED_ASSOC) {
955 if (bss_conf->assoc) {
956 wl->aid = bss_conf->aid;
957
958 ret = wl12xx_build_ps_poll(wl, wl->aid);
959 if (ret < 0)
960 goto out;
961
962 ret = wl12xx_acx_aid(wl, wl->aid);
963 if (ret < 0)
964 goto out;
965
966 /* If we want to go in PSM but we're not there yet */
967 if (wl->psm_requested && !wl->psm) {
968 mode = STATION_POWER_SAVE_MODE;
969 ret = wl12xx_ps_set_mode(wl, mode);
970 if (ret < 0)
971 goto out;
972 }
973 }
974 }
975 if (changed & BSS_CHANGED_ERP_SLOT) {
976 if (bss_conf->use_short_slot)
977 ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT);
978 else
979 ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG);
980 if (ret < 0) {
981 wl12xx_warning("Set slot time failed %d", ret);
982 goto out;
983 }
984 }
985
986 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
987 if (bss_conf->use_short_preamble)
988 wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
989 else
990 wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
991 }
992
993 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
994 if (bss_conf->use_cts_prot)
995 ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE);
996 else
997 ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE);
998 if (ret < 0) {
999 wl12xx_warning("Set ctsprotect failed %d", ret);
1000 goto out;
1001 }
1002 }
1003
1004 if (changed & BSS_CHANGED_BSSID) {
1005 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1006
1007 ret = wl12xx_build_null_data(wl);
1008 if (ret < 0)
1009 goto out;
1010
1011 if (wl->bss_type != BSS_TYPE_IBSS) {
1012 ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1);
1013 if (ret < 0)
1014 goto out;
1015 }
1016 }
1017
1018 if (changed & BSS_CHANGED_BEACON) {
1019 beacon = ieee80211_beacon_get(hw, vif);
1020 ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data,
1021 beacon->len);
1022
1023 if (ret < 0) {
1024 dev_kfree_skb(beacon);
1025 goto out;
1026 }
1027
1028 ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
1029 beacon->len);
1030
1031 dev_kfree_skb(beacon);
1032
1033 if (ret < 0)
1034 goto out;
1035
1036 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
1037
1038 if (ret < 0)
1039 goto out;
1040 }
1041
1042out:
1043 mutex_unlock(&wl->mutex);
1044}
1045
1046
1047/* can't be const, mac80211 writes to this */
1048static struct ieee80211_rate wl12xx_rates[] = {
1049 { .bitrate = 10,
1050 .hw_value = 0x1,
1051 .hw_value_short = 0x1, },
1052 { .bitrate = 20,
1053 .hw_value = 0x2,
1054 .hw_value_short = 0x2,
1055 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1056 { .bitrate = 55,
1057 .hw_value = 0x4,
1058 .hw_value_short = 0x4,
1059 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1060 { .bitrate = 110,
1061 .hw_value = 0x20,
1062 .hw_value_short = 0x20,
1063 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1064 { .bitrate = 60,
1065 .hw_value = 0x8,
1066 .hw_value_short = 0x8, },
1067 { .bitrate = 90,
1068 .hw_value = 0x10,
1069 .hw_value_short = 0x10, },
1070 { .bitrate = 120,
1071 .hw_value = 0x40,
1072 .hw_value_short = 0x40, },
1073 { .bitrate = 180,
1074 .hw_value = 0x80,
1075 .hw_value_short = 0x80, },
1076 { .bitrate = 240,
1077 .hw_value = 0x200,
1078 .hw_value_short = 0x200, },
1079 { .bitrate = 360,
1080 .hw_value = 0x400,
1081 .hw_value_short = 0x400, },
1082 { .bitrate = 480,
1083 .hw_value = 0x800,
1084 .hw_value_short = 0x800, },
1085 { .bitrate = 540,
1086 .hw_value = 0x1000,
1087 .hw_value_short = 0x1000, },
1088};
1089
1090/* can't be const, mac80211 writes to this */
1091static struct ieee80211_channel wl12xx_channels[] = {
1092 { .hw_value = 1, .center_freq = 2412},
1093 { .hw_value = 2, .center_freq = 2417},
1094 { .hw_value = 3, .center_freq = 2422},
1095 { .hw_value = 4, .center_freq = 2427},
1096 { .hw_value = 5, .center_freq = 2432},
1097 { .hw_value = 6, .center_freq = 2437},
1098 { .hw_value = 7, .center_freq = 2442},
1099 { .hw_value = 8, .center_freq = 2447},
1100 { .hw_value = 9, .center_freq = 2452},
1101 { .hw_value = 10, .center_freq = 2457},
1102 { .hw_value = 11, .center_freq = 2462},
1103 { .hw_value = 12, .center_freq = 2467},
1104 { .hw_value = 13, .center_freq = 2472},
1105};
1106
1107/* can't be const, mac80211 writes to this */
1108static struct ieee80211_supported_band wl12xx_band_2ghz = {
1109 .channels = wl12xx_channels,
1110 .n_channels = ARRAY_SIZE(wl12xx_channels),
1111 .bitrates = wl12xx_rates,
1112 .n_bitrates = ARRAY_SIZE(wl12xx_rates),
1113};
1114
1115static const struct ieee80211_ops wl12xx_ops = {
1116 .start = wl12xx_op_start,
1117 .stop = wl12xx_op_stop,
1118 .add_interface = wl12xx_op_add_interface,
1119 .remove_interface = wl12xx_op_remove_interface,
1120 .config = wl12xx_op_config,
1121 .configure_filter = wl12xx_op_configure_filter,
1122 .tx = wl12xx_op_tx,
1123 .set_key = wl12xx_op_set_key,
1124 .hw_scan = wl12xx_op_hw_scan,
1125 .bss_info_changed = wl12xx_op_bss_info_changed,
1126 .set_rts_threshold = wl12xx_op_set_rts_threshold,
1127};
1128
1129static int wl12xx_register_hw(struct wl12xx *wl)
1130{
1131 int ret;
1132
1133 if (wl->mac80211_registered)
1134 return 0;
1135
1136 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
1137
1138 ret = ieee80211_register_hw(wl->hw);
1139 if (ret < 0) {
1140 wl12xx_error("unable to register mac80211 hw: %d", ret);
1141 return ret;
1142 }
1143
1144 wl->mac80211_registered = true;
1145
1146 wl12xx_notice("loaded");
1147
1148 return 0;
1149}
1150
1151static int wl12xx_init_ieee80211(struct wl12xx *wl)
1152{
1153 /* The tx descriptor buffer and the TKIP space */
1154 wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
1155 + WL12XX_TKIP_IV_SPACE;
1156
1157 /* unit us */
1158 /* FIXME: find a proper value */
1159 wl->hw->channel_change_time = 10000;
1160
1161 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1162 IEEE80211_HW_NOISE_DBM;
1163
1164 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1165 wl->hw->wiphy->max_scan_ssids = 1;
1166 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz;
1167
1168 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
1169
1170 return 0;
1171}
1172
1173#define WL12XX_DEFAULT_CHANNEL 1
1174static int __devinit wl12xx_probe(struct spi_device *spi)
1175{
1176 struct wl12xx_platform_data *pdata;
1177 struct ieee80211_hw *hw;
1178 struct wl12xx *wl;
1179 int ret, i;
1180 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
1181
1182 pdata = spi->dev.platform_data;
1183 if (!pdata) {
1184 wl12xx_error("no platform data");
1185 return -ENODEV;
1186 }
1187
1188 hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops);
1189 if (!hw) {
1190 wl12xx_error("could not alloc ieee80211_hw");
1191 return -ENOMEM;
1192 }
1193
1194 wl = hw->priv;
1195 memset(wl, 0, sizeof(*wl));
1196
1197 wl->hw = hw;
1198 dev_set_drvdata(&spi->dev, wl);
1199 wl->spi = spi;
1200
1201 wl->data_in_count = 0;
1202
1203 skb_queue_head_init(&wl->tx_queue);
1204
1205 INIT_WORK(&wl->tx_work, wl12xx_tx_work);
1206 INIT_WORK(&wl->filter_work, wl12xx_filter_work);
1207 wl->channel = WL12XX_DEFAULT_CHANNEL;
1208 wl->scanning = false;
1209 wl->default_key = 0;
1210 wl->listen_int = 1;
1211 wl->rx_counter = 0;
1212 wl->rx_handled = 0;
1213 wl->rx_current_buffer = 0;
1214 wl->rx_last_id = 0;
1215 wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
1216 wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
1217 wl->elp = false;
1218 wl->psm = 0;
1219 wl->psm_requested = false;
1220 wl->tx_queue_stopped = false;
1221 wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
1222
1223 /* We use the default power on sleep time until we know which chip
1224 * we're using */
1225 wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP;
1226
1227 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
1228 wl->tx_frames[i] = NULL;
1229
1230 wl->next_tx_complete = 0;
1231
1232 /*
1233 * In case our MAC address is not correctly set,
1234 * we use a random but Nokia MAC.
1235 */
1236 memcpy(wl->mac_addr, nokia_oui, 3);
1237 get_random_bytes(wl->mac_addr + 3, 3);
1238
1239 wl->state = WL12XX_STATE_OFF;
1240 mutex_init(&wl->mutex);
1241
1242 wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
1243 wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
1244
1245 /* This is the only SPI value that we need to set here, the rest
1246 * comes from the board-peripherals file */
1247 spi->bits_per_word = 32;
1248
1249 ret = spi_setup(spi);
1250 if (ret < 0) {
1251 wl12xx_error("spi_setup failed");
1252 goto out_free;
1253 }
1254
1255 wl->set_power = pdata->set_power;
1256 if (!wl->set_power) {
1257 wl12xx_error("set power function missing in platform data");
1258 return -ENODEV;
1259 }
1260
1261 wl->irq = spi->irq;
1262 if (wl->irq < 0) {
1263 wl12xx_error("irq missing in platform data");
1264 return -ENODEV;
1265 }
1266
1267 ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl);
1268 if (ret < 0) {
1269 wl12xx_error("request_irq() failed: %d", ret);
1270 goto out_free;
1271 }
1272
1273 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
1274
1275 disable_irq(wl->irq);
1276
1277 ret = wl12xx_init_ieee80211(wl);
1278 if (ret)
1279 goto out_irq;
1280
1281 ret = wl12xx_register_hw(wl);
1282 if (ret)
1283 goto out_irq;
1284
1285 wl12xx_debugfs_init(wl);
1286
1287 wl12xx_notice("initialized");
1288
1289 return 0;
1290
1291 out_irq:
1292 free_irq(wl->irq, wl);
1293
1294 out_free:
1295 ieee80211_free_hw(hw);
1296
1297 return ret;
1298}
1299
1300static int __devexit wl12xx_remove(struct spi_device *spi)
1301{
1302 struct wl12xx *wl = dev_get_drvdata(&spi->dev);
1303
1304 ieee80211_unregister_hw(wl->hw);
1305
1306 wl12xx_debugfs_exit(wl);
1307
1308 free_irq(wl->irq, wl);
1309 kfree(wl->target_mem_map);
1310 kfree(wl->data_path);
1311 kfree(wl->fw);
1312 wl->fw = NULL;
1313 kfree(wl->nvs);
1314 wl->nvs = NULL;
1315 ieee80211_free_hw(wl->hw);
1316
1317 return 0;
1318}
1319
1320
1321static struct spi_driver wl12xx_spi_driver = {
1322 .driver = {
1323 .name = "wl12xx",
1324 .bus = &spi_bus_type,
1325 .owner = THIS_MODULE,
1326 },
1327
1328 .probe = wl12xx_probe,
1329 .remove = __devexit_p(wl12xx_remove),
1330};
1331
1332static int __init wl12xx_init(void)
1333{
1334 int ret;
1335
1336 ret = spi_register_driver(&wl12xx_spi_driver);
1337 if (ret < 0) {
1338 wl12xx_error("failed to register spi driver: %d", ret);
1339 goto out;
1340 }
1341
1342out:
1343 return ret;
1344}
1345
1346static void __exit wl12xx_exit(void)
1347{
1348 spi_unregister_driver(&wl12xx_spi_driver);
1349
1350 wl12xx_notice("unloaded");
1351}
1352
1353module_init(wl12xx_init);
1354module_exit(wl12xx_exit);
1355
1356MODULE_LICENSE("GPL");
1357MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
1358 "Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
new file mode 100644
index 000000000000..83a10117330b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -0,0 +1,151 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include "reg.h"
25#include "ps.h"
26#include "spi.h"
27
28#define WL12XX_WAKEUP_TIMEOUT 2000
29
30/* Routines to toggle sleep mode while in ELP */
31void wl12xx_ps_elp_sleep(struct wl12xx *wl)
32{
33 if (wl->elp || !wl->psm)
34 return;
35
36 wl12xx_debug(DEBUG_PSM, "chip to elp");
37
38 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
39
40 wl->elp = true;
41}
42
43int wl12xx_ps_elp_wakeup(struct wl12xx *wl)
44{
45 unsigned long timeout;
46 u32 elp_reg;
47
48 if (!wl->elp)
49 return 0;
50
51 wl12xx_debug(DEBUG_PSM, "waking up chip from elp");
52
53 timeout = jiffies + msecs_to_jiffies(WL12XX_WAKEUP_TIMEOUT);
54
55 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
56
57 elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
58
59 /*
60 * FIXME: we should wait for irq from chip but, as a temporary
61 * solution to simplify locking, let's poll instead
62 */
63 while (!(elp_reg & ELPCTRL_WLAN_READY)) {
64 if (time_after(jiffies, timeout)) {
65 wl12xx_error("elp wakeup timeout");
66 return -ETIMEDOUT;
67 }
68 msleep(1);
69 elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
70 }
71
72 wl12xx_debug(DEBUG_PSM, "wakeup time: %u ms",
73 jiffies_to_msecs(jiffies) -
74 (jiffies_to_msecs(timeout) - WL12XX_WAKEUP_TIMEOUT));
75
76 wl->elp = false;
77
78 return 0;
79}
80
81static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
82{
83 int ret;
84
85 if (enable) {
86 wl12xx_debug(DEBUG_PSM, "sleep auth psm/elp");
87
88 /*
89 * FIXME: we should PSM_ELP, but because of firmware wakeup
90 * problems let's use only PSM_PS
91 */
92 ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_PS);
93 if (ret < 0)
94 return ret;
95
96 wl12xx_ps_elp_sleep(wl);
97 } else {
98 wl12xx_debug(DEBUG_PSM, "sleep auth cam");
99
100 /*
101 * When the target is in ELP, we can only
102 * access the ELP control register. Thus,
103 * we have to wake the target up before
104 * changing the power authorization.
105 */
106
107 wl12xx_ps_elp_wakeup(wl);
108
109 ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
110 if (ret < 0)
111 return ret;
112 }
113
114 return 0;
115}
116
117int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode)
118{
119 int ret;
120
121 switch (mode) {
122 case STATION_POWER_SAVE_MODE:
123 wl12xx_debug(DEBUG_PSM, "entering psm");
124 ret = wl12xx_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
125 if (ret < 0)
126 return ret;
127
128 ret = wl12xx_ps_set_elp(wl, true);
129 if (ret < 0)
130 return ret;
131
132 wl->psm = 1;
133 break;
134 case STATION_ACTIVE_MODE:
135 default:
136 wl12xx_debug(DEBUG_PSM, "leaving psm");
137 ret = wl12xx_ps_set_elp(wl, false);
138 if (ret < 0)
139 return ret;
140
141 ret = wl12xx_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
142 if (ret < 0)
143 return ret;
144
145 wl->psm = 0;
146 break;
147 }
148
149 return ret;
150}
151
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
new file mode 100644
index 000000000000..5d7c52553830
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -0,0 +1,36 @@
1#ifndef __WL12XX_PS_H__
2#define __WL12XX_PS_H__
3
4/*
5 * This file is part of wl12xx
6 *
7 * Copyright (c) 1998-2007 Texas Instruments Incorporated
8 * Copyright (C) 2008 Nokia Corporation
9 *
10 * Contact: Kalle Valo <kalle.valo@nokia.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 *
26 */
27
28#include "wl12xx.h"
29#include "acx.h"
30
31int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode);
32void wl12xx_ps_elp_sleep(struct wl12xx *wl);
33int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
34
35
36#endif /* __WL12XX_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
new file mode 100644
index 000000000000..e421643215cd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/reg.h
@@ -0,0 +1,745 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __REG_H__
26#define __REG_H__
27
28#include <linux/bitops.h>
29#include "wl12xx.h"
30
31#define REGISTERS_BASE 0x00300000
32#define DRPW_BASE 0x00310000
33
34#define REGISTERS_DOWN_SIZE 0x00008800
35#define REGISTERS_WORK_SIZE 0x0000b000
36
37#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
38
39/* ELP register commands */
40#define ELPCTRL_WAKE_UP 0x1
41#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
42#define ELPCTRL_SLEEP 0x0
43/* ELP WLAN_READY bit */
44#define ELPCTRL_WLAN_READY 0x2
45
46/*
47 * Interrupt registers.
48 * 64 bit interrupt sources registers ws ced.
49 * sme interupts were removed and new ones were added.
50 * Order was changed.
51 */
52#define FIQ_MASK (REGISTERS_BASE + 0x0400)
53#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
54#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
55#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
56#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
57#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
58#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
59#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
60#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
61#define IRQ_MASK (REGISTERS_BASE + 0x0418)
62#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
63#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
64#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
65#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
66#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
67#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
68#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
69#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
70#define ECPU_MASK (REGISTERS_BASE + 0x0448)
71#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
72#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
73#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
74#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
75#define INT_STS_ND (REGISTERS_BASE + 0x0464)
76#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
77#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
78#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
79#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
80#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
81#define INT_ACK (REGISTERS_BASE + 0x046C)
82#define INT_ACK_L (REGISTERS_BASE + 0x046C)
83#define INT_ACK_H (REGISTERS_BASE + 0x0470)
84#define INT_TRIG (REGISTERS_BASE + 0x0474)
85#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
86#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
87#define HOST_STS_L (REGISTERS_BASE + 0x045C)
88#define HOST_STS_H (REGISTERS_BASE + 0x0460)
89#define HOST_MASK (REGISTERS_BASE + 0x0430)
90#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
91#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
92#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
93#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
94#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
95#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
96#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
97#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
98
99/* Host Interrupts*/
100#define HINT_MASK (REGISTERS_BASE + 0x0494)
101#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
102#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
103#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
104/*1150 spec calls this HINT_STS_RAW*/
105#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
106#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
107#define HINT_ACK (REGISTERS_BASE + 0x04A8)
108#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
109
110/* Device Configuration registers*/
111#define SOR_CFG (REGISTERS_BASE + 0x0800)
112#define ECPU_CTRL (REGISTERS_BASE + 0x0804)
113#define HI_CFG (REGISTERS_BASE + 0x0808)
114#define EE_START (REGISTERS_BASE + 0x080C)
115
116#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
117
118#define CHIP_ID_1251_PG10 (0x7010101)
119#define CHIP_ID_1251_PG11 (0x7020101)
120#define CHIP_ID_1251_PG12 (0x7030101)
121
122#define ENABLE (REGISTERS_BASE + 0x5450)
123
124/* Power Management registers */
125#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
126#define ELP_CMD (REGISTERS_BASE + 0x5808)
127#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
128#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
129#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
130
131#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
132
133/* Scratch Pad registers*/
134#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
135#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
136#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
137#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
138#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
139#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
140#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
141#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
142#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
143#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
144#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
145#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
146#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
147#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
148
149/* Spare registers*/
150#define SPARE_A1 (REGISTERS_BASE + 0x0994)
151#define SPARE_A2 (REGISTERS_BASE + 0x0998)
152#define SPARE_A3 (REGISTERS_BASE + 0x099C)
153#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
154#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
155#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
156#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
157#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
158#define SPARE_B1 (REGISTERS_BASE + 0x5420)
159#define SPARE_B2 (REGISTERS_BASE + 0x5424)
160#define SPARE_B3 (REGISTERS_BASE + 0x5428)
161#define SPARE_B4 (REGISTERS_BASE + 0x542C)
162#define SPARE_B5 (REGISTERS_BASE + 0x5430)
163#define SPARE_B6 (REGISTERS_BASE + 0x5434)
164#define SPARE_B7 (REGISTERS_BASE + 0x5438)
165#define SPARE_B8 (REGISTERS_BASE + 0x543C)
166
167enum wl12xx_acx_int_reg {
168 ACX_REG_INTERRUPT_TRIG,
169 ACX_REG_INTERRUPT_TRIG_H,
170
171/*=============================================
172 Host Interrupt Mask Register - 32bit (RW)
173 ------------------------------------------
174 Setting a bit in this register masks the
175 corresponding interrupt to the host.
176 0 - RX0 - Rx first dubble buffer Data Interrupt
177 1 - TXD - Tx Data Interrupt
178 2 - TXXFR - Tx Transfer Interrupt
179 3 - RX1 - Rx second dubble buffer Data Interrupt
180 4 - RXXFR - Rx Transfer Interrupt
181 5 - EVENT_A - Event Mailbox interrupt
182 6 - EVENT_B - Event Mailbox interrupt
183 7 - WNONHST - Wake On Host Interrupt
184 8 - TRACE_A - Debug Trace interrupt
185 9 - TRACE_B - Debug Trace interrupt
186 10 - CDCMP - Command Complete Interrupt
187 11 -
188 12 -
189 13 -
190 14 - ICOMP - Initialization Complete Interrupt
191 16 - SG SE - Soft Gemini - Sense enable interrupt
192 17 - SG SD - Soft Gemini - Sense disable interrupt
193 18 - -
194 19 - -
195 20 - -
196 21- -
197 Default: 0x0001
198*==============================================*/
199 ACX_REG_INTERRUPT_MASK,
200
201/*=============================================
202 Host Interrupt Mask Set 16bit, (Write only)
203 ------------------------------------------
204 Setting a bit in this register sets
205 the corresponding bin in ACX_HINT_MASK register
206 without effecting the mask
207 state of other bits (0 = no effect).
208==============================================*/
209 ACX_REG_HINT_MASK_SET,
210
211/*=============================================
212 Host Interrupt Mask Clear 16bit,(Write only)
213 ------------------------------------------
214 Setting a bit in this register clears
215 the corresponding bin in ACX_HINT_MASK register
216 without effecting the mask
217 state of other bits (0 = no effect).
218=============================================*/
219 ACX_REG_HINT_MASK_CLR,
220
221/*=============================================
222 Host Interrupt Status Nondestructive Read
223 16bit,(Read only)
224 ------------------------------------------
225 The host can read this register to determine
226 which interrupts are active.
227 Reading this register doesn't
228 effect its content.
229=============================================*/
230 ACX_REG_INTERRUPT_NO_CLEAR,
231
232/*=============================================
233 Host Interrupt Status Clear on Read Register
234 16bit,(Read only)
235 ------------------------------------------
236 The host can read this register to determine
237 which interrupts are active.
238 Reading this register clears it,
239 thus making all interrupts inactive.
240==============================================*/
241 ACX_REG_INTERRUPT_CLEAR,
242
243/*=============================================
244 Host Interrupt Acknowledge Register
245 16bit,(Write only)
246 ------------------------------------------
247 The host can set individual bits in this
248 register to clear (acknowledge) the corresp.
249 interrupt status bits in the HINT_STS_CLR and
250 HINT_STS_ND registers, thus making the
251 assotiated interrupt inactive. (0-no effect)
252==============================================*/
253 ACX_REG_INTERRUPT_ACK,
254
255/*===============================================
256 Host Software Reset - 32bit RW
257 ------------------------------------------
258 [31:1] Reserved
259 0 SOFT_RESET Soft Reset - When this bit is set,
260 it holds the Wlan hardware in a soft reset state.
261 This reset disables all MAC and baseband processor
262 clocks except the CardBus/PCI interface clock.
263 It also initializes all MAC state machines except
264 the host interface. It does not reload the
265 contents of the EEPROM. When this bit is cleared
266 (not self-clearing), the Wlan hardware
267 exits the software reset state.
268===============================================*/
269 ACX_REG_SLV_SOFT_RESET,
270
271/*===============================================
272 EEPROM Burst Read Start - 32bit RW
273 ------------------------------------------
274 [31:1] Reserved
275 0 ACX_EE_START - EEPROM Burst Read Start 0
276 Setting this bit starts a burst read from
277 the external EEPROM.
278 If this bit is set (after reset) before an EEPROM read/write,
279 the burst read starts at EEPROM address 0.
280 Otherwise, it starts at the address
281 following the address of the previous access.
282 TheWlan hardware hardware clears this bit automatically.
283
284 Default: 0x00000000
285*================================================*/
286 ACX_REG_EE_START,
287
288/* Embedded ARM CPU Control */
289
290/*===============================================
291 Halt eCPU - 32bit RW
292 ------------------------------------------
293 0 HALT_ECPU Halt Embedded CPU - This bit is the
294 compliment of bit 1 (MDATA2) in the SOR_CFG register.
295 During a hardware reset, this bit holds
296 the inverse of MDATA2.
297 When downloading firmware from the host,
298 set this bit (pull down MDATA2).
299 The host clears this bit after downloading the firmware into
300 zero-wait-state SSRAM.
301 When loading firmware from Flash, clear this bit (pull up MDATA2)
302 so that the eCPU can run the bootloader code in Flash
303 HALT_ECPU eCPU State
304 --------------------
305 1 halt eCPU
306 0 enable eCPU
307 ===============================================*/
308 ACX_REG_ECPU_CONTROL,
309
310 ACX_REG_TABLE_LEN
311};
312
313#define ACX_SLV_SOFT_RESET_BIT BIT(1)
314#define ACX_REG_EEPROM_START_BIT BIT(1)
315
316/* Command/Information Mailbox Pointers */
317
318/*===============================================
319 Command Mailbox Pointer - 32bit RW
320 ------------------------------------------
321 This register holds the start address of
322 the command mailbox located in the Wlan hardware memory.
323 The host must read this pointer after a reset to
324 find the location of the command mailbox.
325 The Wlan hardware initializes the command mailbox
326 pointer with the default address of the command mailbox.
327 The command mailbox pointer is not valid until after
328 the host receives the Init Complete interrupt from
329 the Wlan hardware.
330 ===============================================*/
331#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
332
333/*===============================================
334 Information Mailbox Pointer - 32bit RW
335 ------------------------------------------
336 This register holds the start address of
337 the information mailbox located in the Wlan hardware memory.
338 The host must read this pointer after a reset to find
339 the location of the information mailbox.
340 The Wlan hardware initializes the information mailbox pointer
341 with the default address of the information mailbox.
342 The information mailbox pointer is not valid
343 until after the host receives the Init Complete interrupt from
344 the Wlan hardware.
345 ===============================================*/
346#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
347
348
349/* Misc */
350
351#define REG_ENABLE_TX_RX (ENABLE)
352/*
353 * Rx configuration (filter) information element
354 * ---------------------------------------------
355 */
356#define REG_RX_CONFIG (RX_CFG)
357#define REG_RX_FILTER (RX_FILTER_CFG)
358
359
360#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
361
362/* promiscuous - receives all valid frames */
363#define RX_CFG_PROMISCUOUS 0x0008
364
365/* receives frames from any BSSID */
366#define RX_CFG_BSSID 0x0020
367
368/* receives frames destined to any MAC address */
369#define RX_CFG_MAC 0x0010
370
371#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
372#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
373#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
374#define RX_CFG_ENABLE_ANY_BSSID 0x0000
375
376/* discards all broadcast frames */
377#define RX_CFG_DISABLE_BCAST 0x0200
378
379#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
380#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
381#define RX_CFG_COPY_RX_STATUS 0x2000
382#define RX_CFG_TSF 0x10000
383
384#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
385 RX_CFG_ENABLE_ONLY_MY_BSSID)
386
387#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
388 | RX_CFG_ENABLE_ANY_BSSID)
389
390#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
391 RX_CFG_ENABLE_ANY_BSSID)
392
393#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
394 | RX_CFG_ENABLE_ONLY_MY_BSSID)
395
396#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
397 | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
398 | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
399
400#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
401
402#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
403 RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
404
405#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
406 RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
407
408#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
409 | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
410 | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
411
412#define RX_FILTER_OPTION_FILTER_ALL 0
413
414#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
415 | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
416
417#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
418 | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
419 | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
420 | CFG_RX_PRSP_EN)
421
422
423/*===============================================
424 Phy regs
425 ===============================================*/
426#define ACX_PHY_ADDR_REG SBB_ADDR
427#define ACX_PHY_DATA_REG SBB_DATA
428#define ACX_PHY_CTRL_REG SBB_CTL
429#define ACX_PHY_REG_WR_MASK 0x00000001ul
430#define ACX_PHY_REG_RD_MASK 0x00000002ul
431
432
433/*===============================================
434 EEPROM Read/Write Request 32bit RW
435 ------------------------------------------
436 1 EE_READ - EEPROM Read Request 1 - Setting this bit
437 loads a single byte of data into the EE_DATA
438 register from the EEPROM location specified in
439 the EE_ADDR register.
440 The Wlan hardware hardware clears this bit automatically.
441 EE_DATA is valid when this bit is cleared.
442
443 0 EE_WRITE - EEPROM Write Request - Setting this bit
444 writes a single byte of data from the EE_DATA register into the
445 EEPROM location specified in the EE_ADDR register.
446 The Wlan hardware hardware clears this bit automatically.
447*===============================================*/
448#define ACX_EE_CTL_REG EE_CTL
449#define EE_WRITE 0x00000001ul
450#define EE_READ 0x00000002ul
451
452/*===============================================
453 EEPROM Address - 32bit RW
454 ------------------------------------------
455 This register specifies the address
456 within the EEPROM from/to which to read/write data.
457 ===============================================*/
458#define ACX_EE_ADDR_REG EE_ADDR
459
460/*===============================================
461 EEPROM Data - 32bit RW
462 ------------------------------------------
463 This register either holds the read 8 bits of
464 data from the EEPROM or the write data
465 to be written to the EEPROM.
466 ===============================================*/
467#define ACX_EE_DATA_REG EE_DATA
468
469/*===============================================
470 EEPROM Base Address - 32bit RW
471 ------------------------------------------
472 This register holds the upper nine bits
473 [23:15] of the 24-bit Wlan hardware memory
474 address for burst reads from EEPROM accesses.
475 The EEPROM provides the lower 15 bits of this address.
476 The MSB of the address from the EEPROM is ignored.
477 ===============================================*/
478#define ACX_EE_CFG EE_CFG
479
480/*===============================================
481 GPIO Output Values -32bit, RW
482 ------------------------------------------
483 [31:16] Reserved
484 [15: 0] Specify the output values (at the output driver inputs) for
485 GPIO[15:0], respectively.
486 ===============================================*/
487#define ACX_GPIO_OUT_REG GPIO_OUT
488#define ACX_MAX_GPIO_LINES 15
489
490/*===============================================
491 Contention window -32bit, RW
492 ------------------------------------------
493 [31:26] Reserved
494 [25:16] Max (0x3ff)
495 [15:07] Reserved
496 [06:00] Current contention window value - default is 0x1F
497 ===============================================*/
498#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
499#define ACX_CONT_WIND_MIN_MASK 0x0000007f
500#define ACX_CONT_WIND_MAX 0x03ff0000
501
502/*
503 * Indirect slave register/memory registers
504 * ----------------------------------------
505 */
506#define HW_SLAVE_REG_ADDR_REG 0x00000004
507#define HW_SLAVE_REG_DATA_REG 0x00000008
508#define HW_SLAVE_REG_CTRL_REG 0x0000000c
509
510#define SLAVE_AUTO_INC 0x00010000
511#define SLAVE_NO_AUTO_INC 0x00000000
512#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
513
514#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
515#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
516#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
517#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
518
519#define HW_FUNC_EVENT_INT_EN 0x8000
520#define HW_FUNC_EVENT_MASK_REG 0x00000034
521
522#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
523
524/*===============================================
525 HI_CFG Interface Configuration Register Values
526 ------------------------------------------
527 ===============================================*/
528#define HI_CFG_UART_ENABLE 0x00000004
529#define HI_CFG_RST232_ENABLE 0x00000008
530#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
531#define HI_CFG_HOST_INT_ENABLE 0x00000020
532#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
533#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
534#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
535#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
536#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
537
538/*
539 * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
540 * for platforms using active high interrupt level
541 */
542#ifdef USE_ACTIVE_HIGH
543#define HI_CFG_DEF_VAL \
544 (HI_CFG_UART_ENABLE | \
545 HI_CFG_RST232_ENABLE | \
546 HI_CFG_CLOCK_REQ_SELECT | \
547 HI_CFG_HOST_INT_ENABLE)
548#else
549#define HI_CFG_DEF_VAL \
550 (HI_CFG_UART_ENABLE | \
551 HI_CFG_RST232_ENABLE | \
552 HI_CFG_CLOCK_REQ_SELECT | \
553 HI_CFG_HOST_INT_ENABLE)
554
555#endif
556
557#define REF_FREQ_19_2 0
558#define REF_FREQ_26_0 1
559#define REF_FREQ_38_4 2
560#define REF_FREQ_40_0 3
561#define REF_FREQ_33_6 4
562#define REF_FREQ_NUM 5
563
564#define LUT_PARAM_INTEGER_DIVIDER 0
565#define LUT_PARAM_FRACTIONAL_DIVIDER 1
566#define LUT_PARAM_ATTN_BB 2
567#define LUT_PARAM_ALPHA_BB 3
568#define LUT_PARAM_STOP_TIME_BB 4
569#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
570#define LUT_PARAM_NUM 6
571
572#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
573#define USE_EEPROM 0
574#define SOFT_RESET_MAX_TIME 1000000
575#define SOFT_RESET_STALL_TIME 1000
576#define NVS_DATA_BUNDARY_ALIGNMENT 4
577
578
579/* Firmware image load chunk size */
580#define CHUNK_SIZE 512
581
582/* Firmware image header size */
583#define FW_HDR_SIZE 8
584
585#define ECPU_CONTROL_HALT 0x00000101
586
587
588/******************************************************************************
589
590 CHANNELS, BAND & REG DOMAINS definitions
591
592******************************************************************************/
593
594
595enum {
596 RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
597 RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
598 RADIO_BAND_JAPAN_4_9_GHZ = 2,
599 DEFAULT_BAND = RADIO_BAND_2_4GHZ,
600 INVALID_BAND = 0xFE,
601 MAX_RADIO_BANDS = 0xFF
602};
603
604enum {
605 NO_RATE = 0,
606 RATE_1MBPS = 0x0A,
607 RATE_2MBPS = 0x14,
608 RATE_5_5MBPS = 0x37,
609 RATE_6MBPS = 0x0B,
610 RATE_9MBPS = 0x0F,
611 RATE_11MBPS = 0x6E,
612 RATE_12MBPS = 0x0A,
613 RATE_18MBPS = 0x0E,
614 RATE_22MBPS = 0xDC,
615 RATE_24MBPS = 0x09,
616 RATE_36MBPS = 0x0D,
617 RATE_48MBPS = 0x08,
618 RATE_54MBPS = 0x0C
619};
620
621enum {
622 RATE_INDEX_1MBPS = 0,
623 RATE_INDEX_2MBPS = 1,
624 RATE_INDEX_5_5MBPS = 2,
625 RATE_INDEX_6MBPS = 3,
626 RATE_INDEX_9MBPS = 4,
627 RATE_INDEX_11MBPS = 5,
628 RATE_INDEX_12MBPS = 6,
629 RATE_INDEX_18MBPS = 7,
630 RATE_INDEX_22MBPS = 8,
631 RATE_INDEX_24MBPS = 9,
632 RATE_INDEX_36MBPS = 10,
633 RATE_INDEX_48MBPS = 11,
634 RATE_INDEX_54MBPS = 12,
635 RATE_INDEX_MAX = RATE_INDEX_54MBPS,
636 MAX_RATE_INDEX,
637 INVALID_RATE_INDEX = MAX_RATE_INDEX,
638 RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
639};
640
641enum {
642 RATE_MASK_1MBPS = 0x1,
643 RATE_MASK_2MBPS = 0x2,
644 RATE_MASK_5_5MBPS = 0x4,
645 RATE_MASK_11MBPS = 0x20,
646};
647
648#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
649#define OFDM_RATE_BIT BIT(6)
650#define PBCC_RATE_BIT BIT(7)
651
652enum {
653 CCK_LONG = 0,
654 CCK_SHORT = SHORT_PREAMBLE_BIT,
655 PBCC_LONG = PBCC_RATE_BIT,
656 PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
657 OFDM = OFDM_RATE_BIT
658};
659
660/******************************************************************************
661
662Transmit-Descriptor RATE-SET field definitions...
663
664Define a new "Rate-Set" for TX path that incorporates the
665Rate & Modulation info into a single 16-bit field.
666
667TxdRateSet_t:
668b15 - Indicates Preamble type (1=SHORT, 0=LONG).
669 Notes:
670 Must be LONG (0) for 1Mbps rate.
671 Does not apply (set to 0) for RevG-OFDM rates.
672b14 - Indicates PBCC encoding (1=PBCC, 0=not).
673 Notes:
674 Does not apply (set to 0) for rates 1 and 2 Mbps.
675 Does not apply (set to 0) for RevG-OFDM rates.
676b13 - Unused (set to 0).
677b12-b0 - Supported Rate indicator bits as defined below.
678
679******************************************************************************/
680
681
682#define TNETW1251_CHIP_ID_PG1_0 0x07010101
683#define TNETW1251_CHIP_ID_PG1_1 0x07020101
684#define TNETW1251_CHIP_ID_PG1_2 0x07030101
685
686/*************************************************************************
687
688 Interrupt Trigger Register (Host -> WiLink)
689
690**************************************************************************/
691
692/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
693
694/*
695 * Host Command Interrupt. Setting this bit masks
696 * the interrupt that the host issues to inform
697 * the FW that it has sent a command
698 * to the Wlan hardware Command Mailbox.
699 */
700#define INTR_TRIG_CMD BIT(0)
701
702/*
703 * Host Event Acknowlegde Interrupt. The host
704 * sets this bit to acknowledge that it received
705 * the unsolicited information from the event
706 * mailbox.
707 */
708#define INTR_TRIG_EVENT_ACK BIT(1)
709
710/*
711 * The host sets this bit to inform the Wlan
712 * FW that a TX packet is in the XFER
713 * Buffer #0.
714 */
715#define INTR_TRIG_TX_PROC0 BIT(2)
716
717/*
718 * The host sets this bit to inform the FW
719 * that it read a packet from RX XFER
720 * Buffer #0.
721 */
722#define INTR_TRIG_RX_PROC0 BIT(3)
723
724#define INTR_TRIG_DEBUG_ACK BIT(4)
725
726#define INTR_TRIG_STATE_CHANGED BIT(5)
727
728
729/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
730
731/*
732 * The host sets this bit to inform the FW
733 * that it read a packet from RX XFER
734 * Buffer #1.
735 */
736#define INTR_TRIG_RX_PROC1 BIT(17)
737
738/*
739 * The host sets this bit to inform the Wlan
740 * hardware that a TX packet is in the XFER
741 * Buffer #1.
742 */
743#define INTR_TRIG_TX_PROC1 BIT(18)
744
745#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
new file mode 100644
index 000000000000..981ea259eb89
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -0,0 +1,208 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/skbuff.h>
26#include <net/mac80211.h>
27
28#include "wl12xx.h"
29#include "reg.h"
30#include "spi.h"
31#include "rx.h"
32
33static void wl12xx_rx_header(struct wl12xx *wl,
34 struct wl12xx_rx_descriptor *desc)
35{
36 u32 rx_packet_ring_addr;
37
38 rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
39 if (wl->rx_current_buffer)
40 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
41
42 wl12xx_spi_mem_read(wl, rx_packet_ring_addr, desc,
43 sizeof(struct wl12xx_rx_descriptor));
44}
45
46static void wl12xx_rx_status(struct wl12xx *wl,
47 struct wl12xx_rx_descriptor *desc,
48 struct ieee80211_rx_status *status,
49 u8 beacon)
50{
51 memset(status, 0, sizeof(struct ieee80211_rx_status));
52
53 status->band = IEEE80211_BAND_2GHZ;
54 status->mactime = desc->timestamp;
55
56 /*
57 * The rx status timestamp is a 32 bits value while the TSF is a
58 * 64 bits one.
59 * For IBSS merging, TSF is mandatory, so we have to get it
60 * somehow, so we ask for ACX_TSF_INFO.
61 * That could be moved to the get_tsf() hook, but unfortunately,
62 * this one must be atomic, while our SPI routines can sleep.
63 */
64 if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
65 u64 mactime;
66 int ret;
67 struct wl12xx_command cmd;
68 struct acx_tsf_info *tsf_info;
69
70 memset(&cmd, 0, sizeof(cmd));
71
72 ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
73 sizeof(struct acx_tsf_info),
74 &cmd);
75 if (ret < 0) {
76 wl12xx_warning("ACX_FW_REV interrogate failed");
77 return;
78 }
79
80 tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
81
82 mactime = tsf_info->current_tsf_lsb |
83 (tsf_info->current_tsf_msb << 31);
84
85 status->mactime = mactime;
86 }
87
88 status->signal = desc->rssi;
89 status->qual = (desc->rssi - WL12XX_RX_MIN_RSSI) * 100 /
90 (WL12XX_RX_MAX_RSSI - WL12XX_RX_MIN_RSSI);
91 status->qual = min(status->qual, 100);
92 status->qual = max(status->qual, 0);
93
94 /*
95 * FIXME: guessing that snr needs to be divided by two, otherwise
96 * the values don't make any sense
97 */
98 status->noise = desc->rssi - desc->snr / 2;
99
100 status->freq = ieee80211_channel_to_frequency(desc->channel);
101
102 status->flag |= RX_FLAG_TSFT;
103
104 if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
105 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
106
107 if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
108 status->flag |= RX_FLAG_DECRYPTED;
109
110 if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
111 status->flag |= RX_FLAG_MMIC_ERROR;
112 }
113
114 if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
115 status->flag |= RX_FLAG_FAILED_FCS_CRC;
116
117
118 /* FIXME: set status->rate_idx */
119}
120
121static void wl12xx_rx_body(struct wl12xx *wl,
122 struct wl12xx_rx_descriptor *desc)
123{
124 struct sk_buff *skb;
125 struct ieee80211_rx_status status;
126 u8 *rx_buffer, beacon = 0;
127 u16 length, *fc;
128 u32 curr_id, last_id_inc, rx_packet_ring_addr;
129
130 length = WL12XX_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH);
131 curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
132 last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
133
134 if (last_id_inc != curr_id) {
135 wl12xx_warning("curr ID:%d, last ID inc:%d",
136 curr_id, last_id_inc);
137 wl->rx_last_id = curr_id;
138 } else {
139 wl->rx_last_id = last_id_inc;
140 }
141
142 rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
143 sizeof(struct wl12xx_rx_descriptor) + 20;
144 if (wl->rx_current_buffer)
145 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
146
147 skb = dev_alloc_skb(length);
148 if (!skb) {
149 wl12xx_error("Couldn't allocate RX frame");
150 return;
151 }
152
153 rx_buffer = skb_put(skb, length);
154 wl12xx_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
155
156 /* The actual lenght doesn't include the target's alignment */
157 skb->len = desc->length - PLCP_HEADER_LENGTH;
158
159 fc = (u16 *)skb->data;
160
161 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
162 beacon = 1;
163
164 wl12xx_rx_status(wl, desc, &status, beacon);
165
166 wl12xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
167 beacon ? "beacon" : "");
168
169 ieee80211_rx(wl->hw, skb, &status);
170}
171
172static void wl12xx_rx_ack(struct wl12xx *wl)
173{
174 u32 data, addr;
175
176 if (wl->rx_current_buffer) {
177 addr = ACX_REG_INTERRUPT_TRIG_H;
178 data = INTR_TRIG_RX_PROC1;
179 } else {
180 addr = ACX_REG_INTERRUPT_TRIG;
181 data = INTR_TRIG_RX_PROC0;
182 }
183
184 wl12xx_reg_write32(wl, addr, data);
185
186 /* Toggle buffer ring */
187 wl->rx_current_buffer = !wl->rx_current_buffer;
188}
189
190
191void wl12xx_rx(struct wl12xx *wl)
192{
193 struct wl12xx_rx_descriptor rx_desc;
194
195 if (wl->state != WL12XX_STATE_ON)
196 return;
197
198 /* We first read the frame's header */
199 wl12xx_rx_header(wl, &rx_desc);
200
201 /* Now we can read the body */
202 wl12xx_rx_body(wl, &rx_desc);
203
204 /* Finally, we need to ACK the RX */
205 wl12xx_rx_ack(wl);
206
207 return;
208}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
new file mode 100644
index 000000000000..8a23fdea5016
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -0,0 +1,122 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_RX_H__
26#define __WL12XX_RX_H__
27
28#include <linux/bitops.h>
29
30/*
31 * RX PATH
32 *
33 * The Rx path uses a double buffer and an rx_contro structure, each located
34 * at a fixed address in the device memory. The host keeps track of which
35 * buffer is available and alternates between them on a per packet basis.
36 * The size of each of the two buffers is large enough to hold the longest
37 * 802.3 packet.
38 * The RX path goes like that:
39 * 1) The target generates an interrupt each time a new packet is received.
40 * There are 2 RX interrupts, one for each buffer.
41 * 2) The host reads the received packet from one of the double buffers.
42 * 3) The host triggers a target interrupt.
43 * 4) The target prepares the next RX packet.
44 */
45
46#define WL12XX_RX_MAX_RSSI -30
47#define WL12XX_RX_MIN_RSSI -95
48
49#define WL12XX_RX_ALIGN_TO 4
50#define WL12XX_RX_ALIGN(len) (((len) + WL12XX_RX_ALIGN_TO - 1) & \
51 ~(WL12XX_RX_ALIGN_TO - 1))
52
53#define SHORT_PREAMBLE_BIT BIT(0)
54#define OFDM_RATE_BIT BIT(6)
55#define PBCC_RATE_BIT BIT(7)
56
57#define PLCP_HEADER_LENGTH 8
58#define RX_DESC_PACKETID_SHIFT 11
59#define RX_MAX_PACKET_ID 3
60
61#define RX_DESC_VALID_FCS 0x0001
62#define RX_DESC_MATCH_RXADDR1 0x0002
63#define RX_DESC_MCAST 0x0004
64#define RX_DESC_STAINTIM 0x0008
65#define RX_DESC_VIRTUAL_BM 0x0010
66#define RX_DESC_BCAST 0x0020
67#define RX_DESC_MATCH_SSID 0x0040
68#define RX_DESC_MATCH_BSSID 0x0080
69#define RX_DESC_ENCRYPTION_MASK 0x0300
70#define RX_DESC_MEASURMENT 0x0400
71#define RX_DESC_SEQNUM_MASK 0x1800
72#define RX_DESC_MIC_FAIL 0x2000
73#define RX_DESC_DECRYPT_FAIL 0x4000
74
75struct wl12xx_rx_descriptor {
76 u32 timestamp; /* In microseconds */
77 u16 length; /* Paylod length, including headers */
78 u16 flags;
79
80 /*
81 * 0 - 802.11
82 * 1 - 802.3
83 * 2 - IP
84 * 3 - Raw Codec
85 */
86 u8 type;
87
88 /*
89 * Recevied Rate:
90 * 0x0A - 1MBPS
91 * 0x14 - 2MBPS
92 * 0x37 - 5_5MBPS
93 * 0x0B - 6MBPS
94 * 0x0F - 9MBPS
95 * 0x6E - 11MBPS
96 * 0x0A - 12MBPS
97 * 0x0E - 18MBPS
98 * 0xDC - 22MBPS
99 * 0x09 - 24MBPS
100 * 0x0D - 36MBPS
101 * 0x08 - 48MBPS
102 * 0x0C - 54MBPS
103 */
104 u8 rate;
105
106 u8 mod_pre; /* Modulation and preamble */
107 u8 channel;
108
109 /*
110 * 0 - 2.4 Ghz
111 * 1 - 5 Ghz
112 */
113 u8 band;
114
115 s8 rssi; /* in dB */
116 u8 rcpi; /* in dB */
117 u8 snr; /* in dB */
118} __attribute__ ((packed));
119
120void wl12xx_rx(struct wl12xx *wl);
121
122#endif
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
new file mode 100644
index 000000000000..abdf171a47e7
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -0,0 +1,358 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/crc7.h>
26#include <linux/spi/spi.h>
27
28#include "wl12xx.h"
29#include "wl12xx_80211.h"
30#include "reg.h"
31#include "spi.h"
32#include "ps.h"
33
34static int wl12xx_translate_reg_addr(struct wl12xx *wl, int addr)
35{
36 /* If the address is lower than REGISTERS_BASE, it means that this is
37 * a chip-specific register address, so look it up in the registers
38 * table */
39 if (addr < REGISTERS_BASE) {
40 /* Make sure we don't go over the table */
41 if (addr >= ACX_REG_TABLE_LEN) {
42 wl12xx_error("address out of range (%d)", addr);
43 return -EINVAL;
44 }
45 addr = wl->chip.acx_reg_table[addr];
46 }
47
48 return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
49}
50
51static int wl12xx_translate_mem_addr(struct wl12xx *wl, int addr)
52{
53 return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
54}
55
56
57void wl12xx_spi_reset(struct wl12xx *wl)
58{
59 u8 *cmd;
60 struct spi_transfer t;
61 struct spi_message m;
62
63 cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
64 if (!cmd) {
65 wl12xx_error("could not allocate cmd for spi reset");
66 return;
67 }
68
69 memset(&t, 0, sizeof(t));
70 spi_message_init(&m);
71
72 memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
73
74 t.tx_buf = cmd;
75 t.len = WSPI_INIT_CMD_LEN;
76 spi_message_add_tail(&t, &m);
77
78 spi_sync(wl->spi, &m);
79
80 wl12xx_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
81}
82
83void wl12xx_spi_init(struct wl12xx *wl)
84{
85 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
86 struct spi_transfer t;
87 struct spi_message m;
88
89 cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
90 if (!cmd) {
91 wl12xx_error("could not allocate cmd for spi init");
92 return;
93 }
94
95 memset(crc, 0, sizeof(crc));
96 memset(&t, 0, sizeof(t));
97 spi_message_init(&m);
98
99 /*
100 * Set WSPI_INIT_COMMAND
101 * the data is being send from the MSB to LSB
102 */
103 cmd[2] = 0xff;
104 cmd[3] = 0xff;
105 cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
106 cmd[0] = 0;
107 cmd[7] = 0;
108 cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
109 cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
110
111 if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
112 cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
113 else
114 cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
115
116 cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
117 | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
118
119 crc[0] = cmd[1];
120 crc[1] = cmd[0];
121 crc[2] = cmd[7];
122 crc[3] = cmd[6];
123 crc[4] = cmd[5];
124
125 cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
126 cmd[4] |= WSPI_INIT_CMD_END;
127
128 t.tx_buf = cmd;
129 t.len = WSPI_INIT_CMD_LEN;
130 spi_message_add_tail(&t, &m);
131
132 spi_sync(wl->spi, &m);
133
134 wl12xx_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
135}
136
137/* Set the SPI partitions to access the chip addresses
138 *
139 * There are two VIRTUAL (SPI) partitions (the memory partition and the
140 * registers partition), which are mapped to two different areas of the
141 * PHYSICAL (hardware) memory. This function also makes other checks to
142 * ensure that the partitions are not overlapping. In the diagram below, the
143 * memory partition comes before the register partition, but the opposite is
144 * also supported.
145 *
146 * PHYSICAL address
147 * space
148 *
149 * | |
150 * ...+----+--> mem_start
151 * VIRTUAL address ... | |
152 * space ... | | [PART_0]
153 * ... | |
154 * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
155 * | | ... | |
156 * |MEM | ... | |
157 * | | ... | |
158 * part_size <--+----+... | | {unused area)
159 * | | ... | |
160 * |REG | ... | |
161 * part_size | | ... | |
162 * + <--+----+... ...+----+--> reg_start
163 * reg_size ... | |
164 * ... | | [PART_1]
165 * ... | |
166 * ...+----+--> reg_start + reg_size
167 * | |
168 *
169 */
170void wl12xx_set_partition(struct wl12xx *wl,
171 u32 mem_start, u32 mem_size,
172 u32 reg_start, u32 reg_size)
173{
174 u8 tx_buf[sizeof(u32) + 2 * sizeof(struct wl12xx_partition)];
175 struct wl12xx_partition *partition;
176 struct spi_transfer t;
177 struct spi_message m;
178 u32 *cmd;
179 size_t len;
180 int addr;
181
182 spi_message_init(&m);
183 memset(&t, 0, sizeof(t));
184 memset(tx_buf, 0, sizeof(tx_buf));
185
186 cmd = (u32 *) tx_buf;
187 partition = (struct wl12xx_partition *) (tx_buf + sizeof(u32));
188 addr = HW_ACCESS_PART0_SIZE_ADDR;
189 len = 2 * sizeof(struct wl12xx_partition);
190
191 *cmd |= WSPI_CMD_WRITE;
192 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
193 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
194
195 wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
196 mem_start, mem_size);
197 wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
198 reg_start, reg_size);
199
200 /* Make sure that the two partitions together don't exceed the
201 * address range */
202 if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
203 wl12xx_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
204 " address range. Truncating partition[0].");
205 mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
206 wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
207 mem_start, mem_size);
208 wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
209 reg_start, reg_size);
210 }
211
212 if ((mem_start < reg_start) &&
213 ((mem_start + mem_size) > reg_start)) {
214 /* Guarantee that the memory partition doesn't overlap the
215 * registers partition */
216 wl12xx_debug(DEBUG_SPI, "End of partition[0] is "
217 "overlapping partition[1]. Adjusted.");
218 mem_size = reg_start - mem_start;
219 wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
220 mem_start, mem_size);
221 wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
222 reg_start, reg_size);
223 } else if ((reg_start < mem_start) &&
224 ((reg_start + reg_size) > mem_start)) {
225 /* Guarantee that the register partition doesn't overlap the
226 * memory partition */
227 wl12xx_debug(DEBUG_SPI, "End of partition[1] is"
228 " overlapping partition[0]. Adjusted.");
229 reg_size = mem_start - reg_start;
230 wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
231 mem_start, mem_size);
232 wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
233 reg_start, reg_size);
234 }
235
236 partition[0].start = mem_start;
237 partition[0].size = mem_size;
238 partition[1].start = reg_start;
239 partition[1].size = reg_size;
240
241 wl->physical_mem_addr = mem_start;
242 wl->physical_reg_addr = reg_start;
243
244 wl->virtual_mem_addr = 0;
245 wl->virtual_reg_addr = mem_size;
246
247 t.tx_buf = tx_buf;
248 t.len = sizeof(tx_buf);
249 spi_message_add_tail(&t, &m);
250
251 spi_sync(wl->spi, &m);
252}
253
254void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf,
255 size_t len)
256{
257 struct spi_transfer t[3];
258 struct spi_message m;
259 char busy_buf[TNETWIF_READ_OFFSET_BYTES];
260 u32 cmd;
261
262 cmd = 0;
263 cmd |= WSPI_CMD_READ;
264 cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
265 cmd |= addr & WSPI_CMD_BYTE_ADDR;
266
267 spi_message_init(&m);
268 memset(t, 0, sizeof(t));
269
270 t[0].tx_buf = &cmd;
271 t[0].len = 4;
272 spi_message_add_tail(&t[0], &m);
273
274 /* Busy and non busy words read */
275 t[1].rx_buf = busy_buf;
276 t[1].len = TNETWIF_READ_OFFSET_BYTES;
277 spi_message_add_tail(&t[1], &m);
278
279 t[2].rx_buf = buf;
280 t[2].len = len;
281 spi_message_add_tail(&t[2], &m);
282
283 spi_sync(wl->spi, &m);
284
285 /* FIXME: check busy words */
286
287 wl12xx_dump(DEBUG_SPI, "spi_read cmd -> ", &cmd, sizeof(cmd));
288 wl12xx_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
289}
290
291void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf,
292 size_t len)
293{
294 struct spi_transfer t[2];
295 struct spi_message m;
296 u32 cmd;
297
298 cmd = 0;
299 cmd |= WSPI_CMD_WRITE;
300 cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
301 cmd |= addr & WSPI_CMD_BYTE_ADDR;
302
303 spi_message_init(&m);
304 memset(t, 0, sizeof(t));
305
306 t[0].tx_buf = &cmd;
307 t[0].len = sizeof(cmd);
308 spi_message_add_tail(&t[0], &m);
309
310 t[1].tx_buf = buf;
311 t[1].len = len;
312 spi_message_add_tail(&t[1], &m);
313
314 spi_sync(wl->spi, &m);
315
316 wl12xx_dump(DEBUG_SPI, "spi_write cmd -> ", &cmd, sizeof(cmd));
317 wl12xx_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
318}
319
320void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf,
321 size_t len)
322{
323 int physical;
324
325 physical = wl12xx_translate_mem_addr(wl, addr);
326
327 wl12xx_spi_read(wl, physical, buf, len);
328}
329
330void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf,
331 size_t len)
332{
333 int physical;
334
335 physical = wl12xx_translate_mem_addr(wl, addr);
336
337 wl12xx_spi_write(wl, physical, buf, len);
338}
339
340u32 wl12xx_mem_read32(struct wl12xx *wl, int addr)
341{
342 return wl12xx_read32(wl, wl12xx_translate_mem_addr(wl, addr));
343}
344
345void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val)
346{
347 wl12xx_write32(wl, wl12xx_translate_mem_addr(wl, addr), val);
348}
349
350u32 wl12xx_reg_read32(struct wl12xx *wl, int addr)
351{
352 return wl12xx_read32(wl, wl12xx_translate_reg_addr(wl, addr));
353}
354
355void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val)
356{
357 wl12xx_write32(wl, wl12xx_translate_reg_addr(wl, addr), val);
358}
diff --git a/drivers/net/wireless/wl12xx/spi.h b/drivers/net/wireless/wl12xx/spi.h
new file mode 100644
index 000000000000..fd3227e904a8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/spi.h
@@ -0,0 +1,109 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_SPI_H__
26#define __WL12XX_SPI_H__
27
28#include "cmd.h"
29#include "acx.h"
30#include "reg.h"
31
32#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
33
34#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
35#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
36#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
37#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
38
39#define HW_ACCESS_REGISTER_SIZE 4
40
41#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
42
43#define WSPI_CMD_READ 0x40000000
44#define WSPI_CMD_WRITE 0x00000000
45#define WSPI_CMD_FIXED 0x20000000
46#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
47#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
48#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
49
50#define WSPI_INIT_CMD_CRC_LEN 5
51
52#define WSPI_INIT_CMD_START 0x00
53#define WSPI_INIT_CMD_TX 0x40
54/* the extra bypass bit is sampled by the TNET as '1' */
55#define WSPI_INIT_CMD_BYPASS_BIT 0x80
56#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
57#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
58#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
59#define WSPI_INIT_CMD_IOD 0x40
60#define WSPI_INIT_CMD_IP 0x20
61#define WSPI_INIT_CMD_CS 0x10
62#define WSPI_INIT_CMD_WS 0x08
63#define WSPI_INIT_CMD_WSPI 0x01
64#define WSPI_INIT_CMD_END 0x01
65
66#define WSPI_INIT_CMD_LEN 8
67
68#define TNETWIF_READ_OFFSET_BYTES 8
69#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
70 ((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32))
71#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
72
73
74/* Raw target IO, address is not translated */
75void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len);
76void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len);
77
78/* Memory target IO, address is tranlated to partition 0 */
79void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len);
80void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len);
81u32 wl12xx_mem_read32(struct wl12xx *wl, int addr);
82void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val);
83
84/* Registers IO */
85u32 wl12xx_reg_read32(struct wl12xx *wl, int addr);
86void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val);
87
88/* INIT and RESET words */
89void wl12xx_spi_reset(struct wl12xx *wl);
90void wl12xx_spi_init(struct wl12xx *wl);
91void wl12xx_set_partition(struct wl12xx *wl,
92 u32 part_start, u32 part_size,
93 u32 reg_start, u32 reg_size);
94
95static inline u32 wl12xx_read32(struct wl12xx *wl, int addr)
96{
97 u32 response;
98
99 wl12xx_spi_read(wl, addr, &response, sizeof(u32));
100
101 return response;
102}
103
104static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val)
105{
106 wl12xx_spi_write(wl, addr, &val, sizeof(u32));
107}
108
109#endif /* __WL12XX_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
new file mode 100644
index 000000000000..62145e205a8c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -0,0 +1,557 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27
28#include "wl12xx.h"
29#include "reg.h"
30#include "spi.h"
31#include "tx.h"
32#include "ps.h"
33
34static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
35{
36 int used, data_in_count;
37
38 data_in_count = wl->data_in_count;
39
40 if (data_in_count < data_out_count)
41 /* data_in_count has wrapped */
42 data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
43
44 used = data_in_count - data_out_count;
45
46 WARN_ON(used < 0);
47 WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
48
49 if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
50 return true;
51 else
52 return false;
53}
54
55static int wl12xx_tx_path_status(struct wl12xx *wl)
56{
57 u32 status, addr, data_out_count;
58 bool busy;
59
60 addr = wl->data_path->tx_control_addr;
61 status = wl12xx_mem_read32(wl, addr);
62 data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
63 busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
64
65 if (busy)
66 return -EBUSY;
67
68 return 0;
69}
70
71static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
72{
73 int i;
74
75 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
76 if (wl->tx_frames[i] == NULL) {
77 wl->tx_frames[i] = skb;
78 return i;
79 }
80
81 return -EBUSY;
82}
83
84static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
85 struct ieee80211_tx_info *control, u16 fc)
86{
87 *(u16 *)&tx_hdr->control = 0;
88
89 tx_hdr->control.rate_policy = 0;
90
91 /* 802.11 packets */
92 tx_hdr->control.packet_type = 0;
93
94 if (control->flags & IEEE80211_TX_CTL_NO_ACK)
95 tx_hdr->control.ack_policy = 1;
96
97 tx_hdr->control.tx_complete = 1;
98
99 if ((fc & IEEE80211_FTYPE_DATA) &&
100 ((fc & IEEE80211_STYPE_QOS_DATA) ||
101 (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
102 tx_hdr->control.qos = 1;
103}
104
105/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
106#define MAX_MSDU_SECURITY_LENGTH 16
107#define MAX_MPDU_SECURITY_LENGTH 16
108#define WLAN_QOS_HDR_LEN 26
109#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \
110 WLAN_QOS_HDR_LEN)
111#define HW_BLOCK_SIZE 252
112static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
113{
114 u16 payload_len, frag_threshold, mem_blocks;
115 u16 num_mpdus, mem_blocks_per_frag;
116
117 frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
118 tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
119
120 payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
121
122 if (payload_len > frag_threshold) {
123 mem_blocks_per_frag =
124 ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
125 HW_BLOCK_SIZE) + 1;
126 num_mpdus = payload_len / frag_threshold;
127 mem_blocks = num_mpdus * mem_blocks_per_frag;
128 payload_len -= num_mpdus * frag_threshold;
129 num_mpdus++;
130
131 } else {
132 mem_blocks_per_frag = 0;
133 mem_blocks = 0;
134 num_mpdus = 1;
135 }
136
137 mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
138
139 if (num_mpdus > 1)
140 mem_blocks += min(num_mpdus, mem_blocks_per_frag);
141
142 tx_hdr->num_mem_blocks = mem_blocks;
143}
144
145static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
146 struct ieee80211_tx_info *control)
147{
148 struct tx_double_buffer_desc *tx_hdr;
149 struct ieee80211_rate *rate;
150 int id;
151 u16 fc;
152
153 if (!skb)
154 return -EINVAL;
155
156 id = wl12xx_tx_id(wl, skb);
157 if (id < 0)
158 return id;
159
160 fc = *(u16 *)skb->data;
161 tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
162 sizeof(*tx_hdr));
163
164 tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
165 rate = ieee80211_get_tx_rate(wl->hw, control);
166 tx_hdr->rate = cpu_to_le16(rate->hw_value);
167 tx_hdr->expiry_time = cpu_to_le32(1 << 16);
168 tx_hdr->id = id;
169
170 /* FIXME: how to get the correct queue id? */
171 tx_hdr->xmit_queue = 0;
172
173 wl12xx_tx_control(tx_hdr, control, fc);
174 wl12xx_tx_frag_block_num(tx_hdr);
175
176 return 0;
177}
178
179/* We copy the packet to the target */
180static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
181 struct ieee80211_tx_info *control)
182{
183 struct tx_double_buffer_desc *tx_hdr;
184 int len;
185 u32 addr;
186
187 if (!skb)
188 return -EINVAL;
189
190 tx_hdr = (struct tx_double_buffer_desc *) skb->data;
191
192 if (control->control.hw_key &&
193 control->control.hw_key->alg == ALG_TKIP) {
194 int hdrlen;
195 u16 fc;
196 u8 *pos;
197
198 fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
199 tx_hdr->length += WL12XX_TKIP_IV_SPACE;
200
201 hdrlen = ieee80211_hdrlen(fc);
202
203 pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
204 memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
205 sizeof(*tx_hdr) + hdrlen);
206 }
207
208 /* Revisit. This is a workaround for getting non-aligned packets.
209 This happens at least with EAPOL packets from the user space.
210 Our DMA requires packets to be aligned on a 4-byte boundary.
211 */
212 if (unlikely((long)skb->data & 0x03)) {
213 int offset = (4 - (long)skb->data) & 0x03;
214 wl12xx_debug(DEBUG_TX, "skb offset %d", offset);
215
216 /* check whether the current skb can be used */
217 if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
218 unsigned char *src = skb->data;
219
220 /* align the buffer on a 4-byte boundary */
221 skb_reserve(skb, offset);
222 memmove(skb->data, src, skb->len);
223 } else {
224 wl12xx_info("No handler, fixme!");
225 return -EINVAL;
226 }
227 }
228
229 /* Our skb->data at this point includes the HW header */
230 len = WL12XX_TX_ALIGN(skb->len);
231
232 if (wl->data_in_count & 0x1)
233 addr = wl->data_path->tx_packet_ring_addr +
234 wl->data_path->tx_packet_ring_chunk_size;
235 else
236 addr = wl->data_path->tx_packet_ring_addr;
237
238 wl12xx_spi_mem_write(wl, addr, skb->data, len);
239
240 wl12xx_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
241 tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
242
243 return 0;
244}
245
246static void wl12xx_tx_trigger(struct wl12xx *wl)
247{
248 u32 data, addr;
249
250 if (wl->data_in_count & 0x1) {
251 addr = ACX_REG_INTERRUPT_TRIG_H;
252 data = INTR_TRIG_TX_PROC1;
253 } else {
254 addr = ACX_REG_INTERRUPT_TRIG;
255 data = INTR_TRIG_TX_PROC0;
256 }
257
258 wl12xx_reg_write32(wl, addr, data);
259
260 /* Bumping data in */
261 wl->data_in_count = (wl->data_in_count + 1) &
262 TX_STATUS_DATA_OUT_COUNT_MASK;
263}
264
265/* caller must hold wl->mutex */
266static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
267{
268 struct ieee80211_tx_info *info;
269 int ret = 0;
270 u8 idx;
271
272 info = IEEE80211_SKB_CB(skb);
273
274 if (info->control.hw_key) {
275 idx = info->control.hw_key->hw_key_idx;
276 if (unlikely(wl->default_key != idx)) {
277 ret = wl12xx_acx_default_key(wl, idx);
278 if (ret < 0)
279 return ret;
280 }
281 }
282
283 ret = wl12xx_tx_path_status(wl);
284 if (ret < 0)
285 return ret;
286
287 ret = wl12xx_tx_fill_hdr(wl, skb, info);
288 if (ret < 0)
289 return ret;
290
291 ret = wl12xx_tx_send_packet(wl, skb, info);
292 if (ret < 0)
293 return ret;
294
295 wl12xx_tx_trigger(wl);
296
297 return ret;
298}
299
300void wl12xx_tx_work(struct work_struct *work)
301{
302 struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
303 struct sk_buff *skb;
304 bool woken_up = false;
305 int ret;
306
307 mutex_lock(&wl->mutex);
308
309 if (unlikely(wl->state == WL12XX_STATE_OFF))
310 goto out;
311
312 while ((skb = skb_dequeue(&wl->tx_queue))) {
313 if (!woken_up) {
314 wl12xx_ps_elp_wakeup(wl);
315 woken_up = true;
316 }
317
318 ret = wl12xx_tx_frame(wl, skb);
319 if (ret == -EBUSY) {
320 /* firmware buffer is full, stop queues */
321 wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
322 "stop queues");
323 ieee80211_stop_queues(wl->hw);
324 wl->tx_queue_stopped = true;
325 skb_queue_head(&wl->tx_queue, skb);
326 goto out;
327 } else if (ret < 0) {
328 dev_kfree_skb(skb);
329 goto out;
330 }
331 }
332
333out:
334 if (woken_up)
335 wl12xx_ps_elp_sleep(wl);
336
337 mutex_unlock(&wl->mutex);
338}
339
340static const char *wl12xx_tx_parse_status(u8 status)
341{
342 /* 8 bit status field, one character per bit plus null */
343 static char buf[9];
344 int i = 0;
345
346 memset(buf, 0, sizeof(buf));
347
348 if (status & TX_DMA_ERROR)
349 buf[i++] = 'm';
350 if (status & TX_DISABLED)
351 buf[i++] = 'd';
352 if (status & TX_RETRY_EXCEEDED)
353 buf[i++] = 'r';
354 if (status & TX_TIMEOUT)
355 buf[i++] = 't';
356 if (status & TX_KEY_NOT_FOUND)
357 buf[i++] = 'k';
358 if (status & TX_ENCRYPT_FAIL)
359 buf[i++] = 'e';
360 if (status & TX_UNAVAILABLE_PRIORITY)
361 buf[i++] = 'p';
362
363 /* bit 0 is unused apparently */
364
365 return buf;
366}
367
368static void wl12xx_tx_packet_cb(struct wl12xx *wl,
369 struct tx_result *result)
370{
371 struct ieee80211_tx_info *info;
372 struct sk_buff *skb;
373 int hdrlen, ret;
374 u8 *frame;
375
376 skb = wl->tx_frames[result->id];
377 if (skb == NULL) {
378 wl12xx_error("SKB for packet %d is NULL", result->id);
379 return;
380 }
381
382 info = IEEE80211_SKB_CB(skb);
383
384 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
385 (result->status == TX_SUCCESS))
386 info->flags |= IEEE80211_TX_STAT_ACK;
387
388 info->status.rates[0].count = result->ack_failures + 1;
389 wl->stats.retry_count += result->ack_failures;
390
391 /*
392 * We have to remove our private TX header before pushing
393 * the skb back to mac80211.
394 */
395 frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
396 if (info->control.hw_key &&
397 info->control.hw_key->alg == ALG_TKIP) {
398 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
399 memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
400 skb_pull(skb, WL12XX_TKIP_IV_SPACE);
401 }
402
403 wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
404 " status 0x%x (%s)",
405 result->id, skb, result->ack_failures, result->rate,
406 result->status, wl12xx_tx_parse_status(result->status));
407
408
409 ieee80211_tx_status(wl->hw, skb);
410
411 wl->tx_frames[result->id] = NULL;
412
413 if (wl->tx_queue_stopped) {
414 wl12xx_debug(DEBUG_TX, "cb: queue was stopped");
415
416 skb = skb_dequeue(&wl->tx_queue);
417
418 /* The skb can be NULL because tx_work might have been
419 scheduled before the queue was stopped making the
420 queue empty */
421
422 if (skb) {
423 ret = wl12xx_tx_frame(wl, skb);
424 if (ret == -EBUSY) {
425 /* firmware buffer is still full */
426 wl12xx_debug(DEBUG_TX, "cb: fw buffer "
427 "still full");
428 skb_queue_head(&wl->tx_queue, skb);
429 return;
430 } else if (ret < 0) {
431 dev_kfree_skb(skb);
432 return;
433 }
434 }
435
436 wl12xx_debug(DEBUG_TX, "cb: waking queues");
437 ieee80211_wake_queues(wl->hw);
438 wl->tx_queue_stopped = false;
439 }
440}
441
442/* Called upon reception of a TX complete interrupt */
443void wl12xx_tx_complete(struct wl12xx *wl)
444{
445 int i, result_index, num_complete = 0;
446 struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
447
448 if (unlikely(wl->state != WL12XX_STATE_ON))
449 return;
450
451 /* First we read the result */
452 wl12xx_spi_mem_read(wl, wl->data_path->tx_complete_addr,
453 result, sizeof(result));
454
455 result_index = wl->next_tx_complete;
456
457 for (i = 0; i < ARRAY_SIZE(result); i++) {
458 result_ptr = &result[result_index];
459
460 if (result_ptr->done_1 == 1 &&
461 result_ptr->done_2 == 1) {
462 wl12xx_tx_packet_cb(wl, result_ptr);
463
464 result_ptr->done_1 = 0;
465 result_ptr->done_2 = 0;
466
467 result_index = (result_index + 1) &
468 (FW_TX_CMPLT_BLOCK_SIZE - 1);
469 num_complete++;
470 } else {
471 break;
472 }
473 }
474
475 /* Every completed frame needs to be acknowledged */
476 if (num_complete) {
477 /*
478 * If we've wrapped, we have to clear
479 * the results in 2 steps.
480 */
481 if (result_index > wl->next_tx_complete) {
482 /* Only 1 write is needed */
483 wl12xx_spi_mem_write(wl,
484 wl->data_path->tx_complete_addr +
485 (wl->next_tx_complete *
486 sizeof(struct tx_result)),
487 &result[wl->next_tx_complete],
488 num_complete *
489 sizeof(struct tx_result));
490
491
492 } else if (result_index < wl->next_tx_complete) {
493 /* 2 writes are needed */
494 wl12xx_spi_mem_write(wl,
495 wl->data_path->tx_complete_addr +
496 (wl->next_tx_complete *
497 sizeof(struct tx_result)),
498 &result[wl->next_tx_complete],
499 (FW_TX_CMPLT_BLOCK_SIZE -
500 wl->next_tx_complete) *
501 sizeof(struct tx_result));
502
503 wl12xx_spi_mem_write(wl,
504 wl->data_path->tx_complete_addr,
505 result,
506 (num_complete -
507 FW_TX_CMPLT_BLOCK_SIZE +
508 wl->next_tx_complete) *
509 sizeof(struct tx_result));
510
511 } else {
512 /* We have to write the whole array */
513 wl12xx_spi_mem_write(wl,
514 wl->data_path->tx_complete_addr,
515 result,
516 FW_TX_CMPLT_BLOCK_SIZE *
517 sizeof(struct tx_result));
518 }
519
520 }
521
522 wl->next_tx_complete = result_index;
523}
524
525/* caller must hold wl->mutex */
526void wl12xx_tx_flush(struct wl12xx *wl)
527{
528 int i;
529 struct sk_buff *skb;
530 struct ieee80211_tx_info *info;
531
532 /* TX failure */
533/* control->flags = 0; FIXME */
534
535 while ((skb = skb_dequeue(&wl->tx_queue))) {
536 info = IEEE80211_SKB_CB(skb);
537
538 wl12xx_debug(DEBUG_TX, "flushing skb 0x%p", skb);
539
540 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
541 continue;
542
543 ieee80211_tx_status(wl->hw, skb);
544 }
545
546 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
547 if (wl->tx_frames[i] != NULL) {
548 skb = wl->tx_frames[i];
549 info = IEEE80211_SKB_CB(skb);
550
551 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
552 continue;
553
554 ieee80211_tx_status(wl->hw, skb);
555 wl->tx_frames[i] = NULL;
556 }
557}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
new file mode 100644
index 000000000000..dc82691f4c14
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -0,0 +1,215 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_TX_H__
26#define __WL12XX_TX_H__
27
28#include <linux/bitops.h>
29
30/*
31 *
32 * TX PATH
33 *
34 * The Tx path uses a double buffer and a tx_control structure, each located
35 * at a fixed address in the device's memory. On startup, the host retrieves
36 * the pointers to these addresses. A double buffer allows for continuous data
37 * flow towards the device. The host keeps track of which buffer is available
38 * and alternates between these two buffers on a per packet basis.
39 *
40 * The size of each of the two buffers is large enough to hold the longest
41 * 802.3 packet - maximum size Ethernet packet + header + descriptor.
42 * TX complete indication will be received a-synchronously in a TX done cyclic
43 * buffer which is composed of 16 tx_result descriptors structures and is used
44 * in a cyclic manner.
45 *
46 * The TX (HOST) procedure is as follows:
47 * 1. Read the Tx path status, that will give the data_out_count.
48 * 2. goto 1, if not possible.
49 * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
50 * buffer).
51 * 3. Copy the packet (preceded by double_buffer_desc), if possible.
52 * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
53 * buffer).
54 * 4. increment data_in_count.
55 * 5. Inform the firmware by generating a firmware internal interrupt.
56 * 6. FW will increment data_out_count after it reads the buffer.
57 *
58 * The TX Complete procedure:
59 * 1. To get a TX complete indication the host enables the tx_complete flag in
60 * the TX descriptor Structure.
61 * 2. For each packet with a Tx Complete field set, the firmware adds the
62 * transmit results to the cyclic buffer (txDoneRing) and sets both done_1
63 * and done_2 to 1 to indicate driver ownership.
64 * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
65 * host to process the new data. Note: interrupt will be send per packet if
66 * TX complete indication was requested in tx_control or per crossing
67 * aggregation threshold.
68 * 4. After receiving the Tx Complete interrupt, the host reads the
69 * TxDescriptorDone information in a cyclic manner and clears both done_1
70 * and done_2 fields.
71 *
72 */
73
74#define TX_COMPLETE_REQUIRED_BIT 0x80
75#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf
76#define WL12XX_TX_ALIGN_TO 4
77#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
78 ~(WL12XX_TX_ALIGN_TO - 1))
79#define WL12XX_TKIP_IV_SPACE 4
80
81struct tx_control {
82 /* Rate Policy (class) index */
83 unsigned rate_policy:3;
84
85 /* When set, no ack policy is expected */
86 unsigned ack_policy:1;
87
88 /*
89 * Packet type:
90 * 0 -> 802.11
91 * 1 -> 802.3
92 * 2 -> IP
93 * 3 -> raw codec
94 */
95 unsigned packet_type:2;
96
97 /* If set, this is a QoS-Null or QoS-Data frame */
98 unsigned qos:1;
99
100 /*
101 * If set, the target triggers the tx complete INT
102 * upon frame sending completion.
103 */
104 unsigned tx_complete:1;
105
106 /* 2 bytes padding before packet header */
107 unsigned xfer_pad:1;
108
109 unsigned reserved:7;
110} __attribute__ ((packed));
111
112
113struct tx_double_buffer_desc {
114 /* Length of payload, including headers. */
115 u16 length;
116
117 /*
118 * A bit mask that specifies the initial rate to be used
119 * Possible values are:
120 * 0x0001 - 1Mbits
121 * 0x0002 - 2Mbits
122 * 0x0004 - 5.5Mbits
123 * 0x0008 - 6Mbits
124 * 0x0010 - 9Mbits
125 * 0x0020 - 11Mbits
126 * 0x0040 - 12Mbits
127 * 0x0080 - 18Mbits
128 * 0x0100 - 22Mbits
129 * 0x0200 - 24Mbits
130 * 0x0400 - 36Mbits
131 * 0x0800 - 48Mbits
132 * 0x1000 - 54Mbits
133 */
134 u16 rate;
135
136 /* Time in us that a packet can spend in the target */
137 u32 expiry_time;
138
139 /* index of the TX queue used for this packet */
140 u8 xmit_queue;
141
142 /* Used to identify a packet */
143 u8 id;
144
145 struct tx_control control;
146
147 /*
148 * The FW should cut the packet into fragments
149 * of this size.
150 */
151 u16 frag_threshold;
152
153 /* Numbers of HW queue blocks to be allocated */
154 u8 num_mem_blocks;
155
156 u8 reserved;
157} __attribute__ ((packed));
158
159enum {
160 TX_SUCCESS = 0,
161 TX_DMA_ERROR = BIT(7),
162 TX_DISABLED = BIT(6),
163 TX_RETRY_EXCEEDED = BIT(5),
164 TX_TIMEOUT = BIT(4),
165 TX_KEY_NOT_FOUND = BIT(3),
166 TX_ENCRYPT_FAIL = BIT(2),
167 TX_UNAVAILABLE_PRIORITY = BIT(1),
168};
169
170struct tx_result {
171 /*
172 * Ownership synchronization between the host and
173 * the firmware. If done_1 and done_2 are cleared,
174 * owned by the FW (no info ready).
175 */
176 u8 done_1;
177
178 /* same as double_buffer_desc->id */
179 u8 id;
180
181 /*
182 * Total air access duration consumed by this
183 * packet, including all retries and overheads.
184 */
185 u16 medium_usage;
186
187 /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
188 u32 medium_delay;
189
190 /* Time between host xfer and tx complete */
191 u32 fw_hnadling_time;
192
193 /* The LS-byte of the last TKIP sequence number. */
194 u8 lsb_seq_num;
195
196 /* Retry count */
197 u8 ack_failures;
198
199 /* At which rate we got a ACK */
200 u16 rate;
201
202 u16 reserved;
203
204 /* TX_* */
205 u8 status;
206
207 /* See done_1 */
208 u8 done_2;
209} __attribute__ ((packed));
210
211void wl12xx_tx_work(struct work_struct *work);
212void wl12xx_tx_complete(struct wl12xx *wl);
213void wl12xx_tx_flush(struct wl12xx *wl);
214
215#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
new file mode 100644
index 000000000000..bd0decdcad23
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.c
@@ -0,0 +1,709 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26
27#include "wl1251.h"
28#include "reg.h"
29#include "spi.h"
30#include "boot.h"
31#include "event.h"
32#include "acx.h"
33#include "tx.h"
34#include "rx.h"
35#include "ps.h"
36#include "init.h"
37
38static struct wl12xx_partition_set wl1251_part_table[PART_TABLE_LEN] = {
39 [PART_DOWN] = {
40 .mem = {
41 .start = 0x00000000,
42 .size = 0x00016800
43 },
44 .reg = {
45 .start = REGISTERS_BASE,
46 .size = REGISTERS_DOWN_SIZE
47 },
48 },
49
50 [PART_WORK] = {
51 .mem = {
52 .start = 0x00028000,
53 .size = 0x00014000
54 },
55 .reg = {
56 .start = REGISTERS_BASE,
57 .size = REGISTERS_WORK_SIZE
58 },
59 },
60
61 /* WL1251 doesn't use the DRPW partition, so we don't set it here */
62};
63
64static enum wl12xx_acx_int_reg wl1251_acx_reg_table[ACX_REG_TABLE_LEN] = {
65 [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
66 [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
67 [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
68 [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
69 [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
70 [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
71 [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
72 [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
73 [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
74 [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
75 [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
76};
77
78static int wl1251_upload_firmware(struct wl12xx *wl)
79{
80 struct wl12xx_partition_set *p_table = wl->chip.p_table;
81 int addr, chunk_num, partition_limit;
82 size_t fw_data_len;
83 u8 *p;
84
85 /* whal_FwCtrl_LoadFwImageSm() */
86
87 wl12xx_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
88 wl12xx_reg_read32(wl, CHIP_ID_B));
89
90 /* 10.0 check firmware length and set partition */
91 fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) |
92 (wl->fw[6] << 8) | (wl->fw[7]);
93
94 wl12xx_debug(DEBUG_BOOT, "fw_data_len %d chunk_size %d", fw_data_len,
95 CHUNK_SIZE);
96
97 if ((fw_data_len % 4) != 0) {
98 wl12xx_error("firmware length not multiple of four");
99 return -EIO;
100 }
101
102 wl12xx_set_partition(wl,
103 p_table[PART_DOWN].mem.start,
104 p_table[PART_DOWN].mem.size,
105 p_table[PART_DOWN].reg.start,
106 p_table[PART_DOWN].reg.size);
107
108 /* 10.1 set partition limit and chunk num */
109 chunk_num = 0;
110 partition_limit = p_table[PART_DOWN].mem.size;
111
112 while (chunk_num < fw_data_len / CHUNK_SIZE) {
113 /* 10.2 update partition, if needed */
114 addr = p_table[PART_DOWN].mem.start +
115 (chunk_num + 2) * CHUNK_SIZE;
116 if (addr > partition_limit) {
117 addr = p_table[PART_DOWN].mem.start +
118 chunk_num * CHUNK_SIZE;
119 partition_limit = chunk_num * CHUNK_SIZE +
120 p_table[PART_DOWN].mem.size;
121 wl12xx_set_partition(wl,
122 addr,
123 p_table[PART_DOWN].mem.size,
124 p_table[PART_DOWN].reg.start,
125 p_table[PART_DOWN].reg.size);
126 }
127
128 /* 10.3 upload the chunk */
129 addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
130 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
131 wl12xx_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
132 p, addr);
133 wl12xx_spi_mem_write(wl, addr, p, CHUNK_SIZE);
134
135 chunk_num++;
136 }
137
138 /* 10.4 upload the last chunk */
139 addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
140 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
141 wl12xx_debug(DEBUG_BOOT, "uploading fw last chunk (%d B) 0x%p to 0x%x",
142 fw_data_len % CHUNK_SIZE, p, addr);
143 wl12xx_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
144
145 return 0;
146}
147
148static int wl1251_upload_nvs(struct wl12xx *wl)
149{
150 size_t nvs_len, nvs_bytes_written, burst_len;
151 int nvs_start, i;
152 u32 dest_addr, val;
153 u8 *nvs_ptr, *nvs;
154
155 nvs = wl->nvs;
156 if (nvs == NULL)
157 return -ENODEV;
158
159 nvs_ptr = nvs;
160
161 nvs_len = wl->nvs_len;
162 nvs_start = wl->fw_len;
163
164 /*
165 * Layout before the actual NVS tables:
166 * 1 byte : burst length.
167 * 2 bytes: destination address.
168 * n bytes: data to burst copy.
169 *
170 * This is ended by a 0 length, then the NVS tables.
171 */
172
173 while (nvs_ptr[0]) {
174 burst_len = nvs_ptr[0];
175 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
176
177 /* We move our pointer to the data */
178 nvs_ptr += 3;
179
180 for (i = 0; i < burst_len; i++) {
181 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
182 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
183
184 wl12xx_debug(DEBUG_BOOT,
185 "nvs burst write 0x%x: 0x%x",
186 dest_addr, val);
187 wl12xx_mem_write32(wl, dest_addr, val);
188
189 nvs_ptr += 4;
190 dest_addr += 4;
191 }
192 }
193
194 /*
195 * We've reached the first zero length, the first NVS table
196 * is 7 bytes further.
197 */
198 nvs_ptr += 7;
199 nvs_len -= nvs_ptr - nvs;
200 nvs_len = ALIGN(nvs_len, 4);
201
202 /* Now we must set the partition correctly */
203 wl12xx_set_partition(wl, nvs_start,
204 wl->chip.p_table[PART_DOWN].mem.size,
205 wl->chip.p_table[PART_DOWN].reg.start,
206 wl->chip.p_table[PART_DOWN].reg.size);
207
208 /* And finally we upload the NVS tables */
209 nvs_bytes_written = 0;
210 while (nvs_bytes_written < nvs_len) {
211 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
212 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
213
214 val = cpu_to_le32(val);
215
216 wl12xx_debug(DEBUG_BOOT,
217 "nvs write table 0x%x: 0x%x",
218 nvs_start, val);
219 wl12xx_mem_write32(wl, nvs_start, val);
220
221 nvs_ptr += 4;
222 nvs_bytes_written += 4;
223 nvs_start += 4;
224 }
225
226 return 0;
227}
228
229static int wl1251_boot(struct wl12xx *wl)
230{
231 int ret = 0, minor_minor_e2_ver;
232 u32 tmp, boot_data;
233
234 ret = wl12xx_boot_soft_reset(wl);
235 if (ret < 0)
236 goto out;
237
238 /* 2. start processing NVS file */
239 ret = wl->chip.op_upload_nvs(wl);
240 if (ret < 0)
241 goto out;
242
243 /* write firmware's last address (ie. it's length) to
244 * ACX_EEPROMLESS_IND_REG */
245 wl12xx_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
246
247 /* 6. read the EEPROM parameters */
248 tmp = wl12xx_reg_read32(wl, SCR_PAD2);
249
250 /* 7. read bootdata */
251 wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
252 wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
253 tmp = wl12xx_reg_read32(wl, SCR_PAD3);
254
255 /* 8. check bootdata and call restart sequence */
256 wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
257 minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
258
259 wl12xx_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
260 "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
261 wl->boot_attr.radio_type, wl->boot_attr.major,
262 wl->boot_attr.minor, minor_minor_e2_ver);
263
264 ret = wl12xx_boot_init_seq(wl);
265 if (ret < 0)
266 goto out;
267
268 /* 9. NVS processing done */
269 boot_data = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
270
271 wl12xx_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
272
273 /* 10. check that ECPU_CONTROL_HALT bits are set in
274 * pWhalBus->uBootData and start uploading firmware
275 */
276 if ((boot_data & ECPU_CONTROL_HALT) == 0) {
277 wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
278 ret = -EIO;
279 goto out;
280 }
281
282 ret = wl->chip.op_upload_fw(wl);
283 if (ret < 0)
284 goto out;
285
286 /* 10.5 start firmware */
287 ret = wl12xx_boot_run_firmware(wl);
288 if (ret < 0)
289 goto out;
290
291 /* Get and save the firmware version */
292 wl12xx_acx_fw_version(wl, wl->chip.fw_ver, sizeof(wl->chip.fw_ver));
293
294out:
295 return ret;
296}
297
298static int wl1251_mem_cfg(struct wl12xx *wl)
299{
300 struct wl1251_acx_config_memory mem_conf;
301 int ret, i;
302
303 wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
304
305 /* memory config */
306 mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
307 mem_conf.mem_config.rx_mem_block_num = 35;
308 mem_conf.mem_config.tx_min_mem_block_num = 64;
309 mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES;
310 mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING;
311 mem_conf.mem_config.num_ssid_profiles = 1;
312 mem_conf.mem_config.debug_buffer_size =
313 cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
314
315 /* RX queue config */
316 mem_conf.rx_queue_config.dma_address = 0;
317 mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF;
318 mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
319 mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE;
320
321 /* TX queue config */
322 for (i = 0; i < MAX_TX_QUEUES; i++) {
323 mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
324 mem_conf.tx_queue_config[i].attributes = i;
325 }
326
327 mem_conf.header.id = ACX_MEM_CFG;
328 mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) -
329 sizeof(struct acx_header);
330 mem_conf.header.len -=
331 (MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
332 sizeof(struct wl1251_acx_tx_queue_config);
333
334 ret = wl12xx_cmd_configure(wl, &mem_conf,
335 sizeof(struct wl1251_acx_config_memory));
336 if (ret < 0)
337 wl12xx_warning("wl1251 mem config failed: %d", ret);
338
339 return ret;
340}
341
342static int wl1251_hw_init_mem_config(struct wl12xx *wl)
343{
344 int ret;
345
346 ret = wl1251_mem_cfg(wl);
347 if (ret < 0)
348 return ret;
349
350 wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
351 GFP_KERNEL);
352 if (!wl->target_mem_map) {
353 wl12xx_error("couldn't allocate target memory map");
354 return -ENOMEM;
355 }
356
357 /* we now ask for the firmware built memory map */
358 ret = wl12xx_acx_mem_map(wl, wl->target_mem_map,
359 sizeof(struct wl1251_acx_mem_map));
360 if (ret < 0) {
361 wl12xx_error("couldn't retrieve firmware memory map");
362 kfree(wl->target_mem_map);
363 wl->target_mem_map = NULL;
364 return ret;
365 }
366
367 return 0;
368}
369
370static void wl1251_set_ecpu_ctrl(struct wl12xx *wl, u32 flag)
371{
372 u32 cpu_ctrl;
373
374 /* 10.5.0 run the firmware (I) */
375 cpu_ctrl = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
376
377 /* 10.5.1 run the firmware (II) */
378 cpu_ctrl &= ~flag;
379 wl12xx_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
380}
381
382static void wl1251_target_enable_interrupts(struct wl12xx *wl)
383{
384 /* Enable target's interrupts */
385 wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
386 WL1251_ACX_INTR_RX1_DATA |
387 WL1251_ACX_INTR_TX_RESULT |
388 WL1251_ACX_INTR_EVENT_A |
389 WL1251_ACX_INTR_EVENT_B |
390 WL1251_ACX_INTR_INIT_COMPLETE;
391 wl12xx_boot_target_enable_interrupts(wl);
392}
393
394static void wl1251_irq_work(struct work_struct *work)
395{
396 u32 intr;
397 struct wl12xx *wl =
398 container_of(work, struct wl12xx, irq_work);
399
400 mutex_lock(&wl->mutex);
401
402 wl12xx_debug(DEBUG_IRQ, "IRQ work");
403
404 if (wl->state == WL12XX_STATE_OFF)
405 goto out;
406
407 wl12xx_ps_elp_wakeup(wl);
408
409 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
410
411 intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
412 wl12xx_debug(DEBUG_IRQ, "intr: 0x%x", intr);
413
414 if (wl->data_path) {
415 wl12xx_spi_mem_read(wl, wl->data_path->rx_control_addr,
416 &wl->rx_counter, sizeof(u32));
417
418 /* We handle a frmware bug here */
419 switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
420 case 0:
421 wl12xx_debug(DEBUG_IRQ, "RX: FW and host in sync");
422 intr &= ~WL1251_ACX_INTR_RX0_DATA;
423 intr &= ~WL1251_ACX_INTR_RX1_DATA;
424 break;
425 case 1:
426 wl12xx_debug(DEBUG_IRQ, "RX: FW +1");
427 intr |= WL1251_ACX_INTR_RX0_DATA;
428 intr &= ~WL1251_ACX_INTR_RX1_DATA;
429 break;
430 case 2:
431 wl12xx_debug(DEBUG_IRQ, "RX: FW +2");
432 intr |= WL1251_ACX_INTR_RX0_DATA;
433 intr |= WL1251_ACX_INTR_RX1_DATA;
434 break;
435 default:
436 wl12xx_warning("RX: FW and host out of sync: %d",
437 wl->rx_counter - wl->rx_handled);
438 break;
439 }
440
441 wl->rx_handled = wl->rx_counter;
442
443
444 wl12xx_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
445 }
446
447 intr &= wl->intr_mask;
448
449 if (intr == 0) {
450 wl12xx_debug(DEBUG_IRQ, "INTR is 0");
451 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
452 ~(wl->intr_mask));
453
454 goto out_sleep;
455 }
456
457 if (intr & WL1251_ACX_INTR_RX0_DATA) {
458 wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
459 wl12xx_rx(wl);
460 }
461
462 if (intr & WL1251_ACX_INTR_RX1_DATA) {
463 wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
464 wl12xx_rx(wl);
465 }
466
467 if (intr & WL1251_ACX_INTR_TX_RESULT) {
468 wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
469 wl12xx_tx_complete(wl);
470 }
471
472 if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
473 wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
474 if (intr & WL1251_ACX_INTR_EVENT_A)
475 wl12xx_event_handle(wl, 0);
476 else
477 wl12xx_event_handle(wl, 1);
478 }
479
480 if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
481 wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
482
483 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
484
485out_sleep:
486 wl12xx_ps_elp_sleep(wl);
487out:
488 mutex_unlock(&wl->mutex);
489}
490
491static int wl1251_hw_init_txq_fill(u8 qid,
492 struct acx_tx_queue_qos_config *config,
493 u32 num_blocks)
494{
495 config->qid = qid;
496
497 switch (qid) {
498 case QOS_AC_BE:
499 config->high_threshold =
500 (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
501 config->low_threshold =
502 (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
503 break;
504 case QOS_AC_BK:
505 config->high_threshold =
506 (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
507 config->low_threshold =
508 (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
509 break;
510 case QOS_AC_VI:
511 config->high_threshold =
512 (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
513 config->low_threshold =
514 (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
515 break;
516 case QOS_AC_VO:
517 config->high_threshold =
518 (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
519 config->low_threshold =
520 (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
521 break;
522 default:
523 wl12xx_error("Invalid TX queue id: %d", qid);
524 return -EINVAL;
525 }
526
527 return 0;
528}
529
530static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
531{
532 struct acx_tx_queue_qos_config config;
533 struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
534 int ret, i;
535
536 wl12xx_debug(DEBUG_ACX, "acx tx queue config");
537
538 config.header.id = ACX_TX_QUEUE_CFG;
539 config.header.len = sizeof(struct acx_tx_queue_qos_config) -
540 sizeof(struct acx_header);
541
542 for (i = 0; i < MAX_NUM_OF_AC; i++) {
543 ret = wl1251_hw_init_txq_fill(i, &config,
544 wl_mem_map->num_tx_mem_blocks);
545 if (ret < 0)
546 return ret;
547
548 ret = wl12xx_cmd_configure(wl, &config, sizeof(config));
549 if (ret < 0)
550 return ret;
551 }
552
553 return 0;
554}
555
556static int wl1251_hw_init_data_path_config(struct wl12xx *wl)
557{
558 int ret;
559
560 /* asking for the data path parameters */
561 wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
562 GFP_KERNEL);
563 if (!wl->data_path) {
564 wl12xx_error("Couldnt allocate data path parameters");
565 return -ENOMEM;
566 }
567
568 ret = wl12xx_acx_data_path_params(wl, wl->data_path);
569 if (ret < 0) {
570 kfree(wl->data_path);
571 wl->data_path = NULL;
572 return ret;
573 }
574
575 return 0;
576}
577
578static int wl1251_hw_init(struct wl12xx *wl)
579{
580 struct wl1251_acx_mem_map *wl_mem_map;
581 int ret;
582
583 ret = wl12xx_hw_init_hwenc_config(wl);
584 if (ret < 0)
585 return ret;
586
587 /* Template settings */
588 ret = wl12xx_hw_init_templates_config(wl);
589 if (ret < 0)
590 return ret;
591
592 /* Default memory configuration */
593 ret = wl1251_hw_init_mem_config(wl);
594 if (ret < 0)
595 return ret;
596
597 /* Default data path configuration */
598 ret = wl1251_hw_init_data_path_config(wl);
599 if (ret < 0)
600 goto out_free_memmap;
601
602 /* RX config */
603 ret = wl12xx_hw_init_rx_config(wl,
604 RX_CFG_PROMISCUOUS | RX_CFG_TSF,
605 RX_FILTER_OPTION_DEF);
606 /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
607 RX_FILTER_OPTION_FILTER_ALL); */
608 if (ret < 0)
609 goto out_free_data_path;
610
611 /* TX queues config */
612 ret = wl1251_hw_init_tx_queue_config(wl);
613 if (ret < 0)
614 goto out_free_data_path;
615
616 /* PHY layer config */
617 ret = wl12xx_hw_init_phy_config(wl);
618 if (ret < 0)
619 goto out_free_data_path;
620
621 /* Beacon filtering */
622 ret = wl12xx_hw_init_beacon_filter(wl);
623 if (ret < 0)
624 goto out_free_data_path;
625
626 /* Bluetooth WLAN coexistence */
627 ret = wl12xx_hw_init_pta(wl);
628 if (ret < 0)
629 goto out_free_data_path;
630
631 /* Energy detection */
632 ret = wl12xx_hw_init_energy_detection(wl);
633 if (ret < 0)
634 goto out_free_data_path;
635
636 /* Beacons and boradcast settings */
637 ret = wl12xx_hw_init_beacon_broadcast(wl);
638 if (ret < 0)
639 goto out_free_data_path;
640
641 /* Enable data path */
642 ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
643 if (ret < 0)
644 goto out_free_data_path;
645
646 /* Default power state */
647 ret = wl12xx_hw_init_power_auth(wl);
648 if (ret < 0)
649 goto out_free_data_path;
650
651 wl_mem_map = wl->target_mem_map;
652 wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
653 wl_mem_map->num_tx_mem_blocks,
654 wl->data_path->tx_control_addr,
655 wl_mem_map->num_rx_mem_blocks,
656 wl->data_path->rx_control_addr);
657
658 return 0;
659
660 out_free_data_path:
661 kfree(wl->data_path);
662
663 out_free_memmap:
664 kfree(wl->target_mem_map);
665
666 return ret;
667}
668
669static int wl1251_plt_init(struct wl12xx *wl)
670{
671 int ret;
672
673 ret = wl1251_hw_init_mem_config(wl);
674 if (ret < 0)
675 return ret;
676
677 ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
678 if (ret < 0)
679 return ret;
680
681 return 0;
682}
683
684void wl1251_setup(struct wl12xx *wl)
685{
686 /* FIXME: Is it better to use strncpy here or is this ok? */
687 wl->chip.fw_filename = WL1251_FW_NAME;
688 wl->chip.nvs_filename = WL1251_NVS_NAME;
689
690 /* Now we know what chip we're using, so adjust the power on sleep
691 * time accordingly */
692 wl->chip.power_on_sleep = WL1251_POWER_ON_SLEEP;
693
694 wl->chip.intr_cmd_complete = WL1251_ACX_INTR_CMD_COMPLETE;
695 wl->chip.intr_init_complete = WL1251_ACX_INTR_INIT_COMPLETE;
696
697 wl->chip.op_upload_nvs = wl1251_upload_nvs;
698 wl->chip.op_upload_fw = wl1251_upload_firmware;
699 wl->chip.op_boot = wl1251_boot;
700 wl->chip.op_set_ecpu_ctrl = wl1251_set_ecpu_ctrl;
701 wl->chip.op_target_enable_interrupts = wl1251_target_enable_interrupts;
702 wl->chip.op_hw_init = wl1251_hw_init;
703 wl->chip.op_plt_init = wl1251_plt_init;
704
705 wl->chip.p_table = wl1251_part_table;
706 wl->chip.acx_reg_table = wl1251_acx_reg_table;
707
708 INIT_WORK(&wl->irq_work, wl1251_irq_work);
709}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
new file mode 100644
index 000000000000..1f4a44330394
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -0,0 +1,165 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __WL1251_H__
25#define __WL1251_H__
26
27#include <linux/bitops.h>
28
29#include "wl12xx.h"
30#include "acx.h"
31
32#define WL1251_FW_NAME "wl1251-fw.bin"
33#define WL1251_NVS_NAME "wl1251-nvs.bin"
34
35#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
36
37void wl1251_setup(struct wl12xx *wl);
38
39
40struct wl1251_acx_memory {
41 __le16 num_stations; /* number of STAs to be supported. */
42 u16 reserved_1;
43
44 /*
45 * Nmber of memory buffers for the RX mem pool.
46 * The actual number may be less if there are
47 * not enough blocks left for the minimum num
48 * of TX ones.
49 */
50 u8 rx_mem_block_num;
51 u8 reserved_2;
52 u8 num_tx_queues; /* From 1 to 16 */
53 u8 host_if_options; /* HOST_IF* */
54 u8 tx_min_mem_block_num;
55 u8 num_ssid_profiles;
56 __le16 debug_buffer_size;
57} __attribute__ ((packed));
58
59
60#define ACX_RX_DESC_MIN 1
61#define ACX_RX_DESC_MAX 127
62#define ACX_RX_DESC_DEF 32
63struct wl1251_acx_rx_queue_config {
64 u8 num_descs;
65 u8 pad;
66 u8 type;
67 u8 priority;
68 __le32 dma_address;
69} __attribute__ ((packed));
70
71#define ACX_TX_DESC_MIN 1
72#define ACX_TX_DESC_MAX 127
73#define ACX_TX_DESC_DEF 16
74struct wl1251_acx_tx_queue_config {
75 u8 num_descs;
76 u8 pad[2];
77 u8 attributes;
78} __attribute__ ((packed));
79
80#define MAX_TX_QUEUE_CONFIGS 5
81#define MAX_TX_QUEUES 4
82struct wl1251_acx_config_memory {
83 struct acx_header header;
84
85 struct wl1251_acx_memory mem_config;
86 struct wl1251_acx_rx_queue_config rx_queue_config;
87 struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
88} __attribute__ ((packed));
89
90struct wl1251_acx_mem_map {
91 struct acx_header header;
92
93 void *code_start;
94 void *code_end;
95
96 void *wep_defkey_start;
97 void *wep_defkey_end;
98
99 void *sta_table_start;
100 void *sta_table_end;
101
102 void *packet_template_start;
103 void *packet_template_end;
104
105 void *queue_memory_start;
106 void *queue_memory_end;
107
108 void *packet_memory_pool_start;
109 void *packet_memory_pool_end;
110
111 void *debug_buffer1_start;
112 void *debug_buffer1_end;
113
114 void *debug_buffer2_start;
115 void *debug_buffer2_end;
116
117 /* Number of blocks FW allocated for TX packets */
118 u32 num_tx_mem_blocks;
119
120 /* Number of blocks FW allocated for RX packets */
121 u32 num_rx_mem_blocks;
122} __attribute__ ((packed));
123
124/*************************************************************************
125
126 Host Interrupt Register (WiLink -> Host)
127
128**************************************************************************/
129
130/* RX packet is ready in Xfer buffer #0 */
131#define WL1251_ACX_INTR_RX0_DATA BIT(0)
132
133/* TX result(s) are in the TX complete buffer */
134#define WL1251_ACX_INTR_TX_RESULT BIT(1)
135
136/* OBSOLETE */
137#define WL1251_ACX_INTR_TX_XFR BIT(2)
138
139/* RX packet is ready in Xfer buffer #1 */
140#define WL1251_ACX_INTR_RX1_DATA BIT(3)
141
142/* Event was entered to Event MBOX #A */
143#define WL1251_ACX_INTR_EVENT_A BIT(4)
144
145/* Event was entered to Event MBOX #B */
146#define WL1251_ACX_INTR_EVENT_B BIT(5)
147
148/* OBSOLETE */
149#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6)
150
151/* Trace meassge on MBOX #A */
152#define WL1251_ACX_INTR_TRACE_A BIT(7)
153
154/* Trace meassge on MBOX #B */
155#define WL1251_ACX_INTR_TRACE_B BIT(8)
156
157/* Command processing completion */
158#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9)
159
160/* Init sequence is done */
161#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14)
162
163#define WL1251_ACX_INTR_ALL 0xFFFFFFFF
164
165#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
new file mode 100644
index 000000000000..48641437414b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -0,0 +1,409 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (c) 1998-2007 Texas Instruments Incorporated
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL12XX_H__
26#define __WL12XX_H__
27
28#include <linux/mutex.h>
29#include <linux/list.h>
30#include <linux/bitops.h>
31#include <net/mac80211.h>
32
33#define DRIVER_NAME "wl12xx"
34#define DRIVER_PREFIX DRIVER_NAME ": "
35
36enum {
37 DEBUG_NONE = 0,
38 DEBUG_IRQ = BIT(0),
39 DEBUG_SPI = BIT(1),
40 DEBUG_BOOT = BIT(2),
41 DEBUG_MAILBOX = BIT(3),
42 DEBUG_NETLINK = BIT(4),
43 DEBUG_EVENT = BIT(5),
44 DEBUG_TX = BIT(6),
45 DEBUG_RX = BIT(7),
46 DEBUG_SCAN = BIT(8),
47 DEBUG_CRYPT = BIT(9),
48 DEBUG_PSM = BIT(10),
49 DEBUG_MAC80211 = BIT(11),
50 DEBUG_CMD = BIT(12),
51 DEBUG_ACX = BIT(13),
52 DEBUG_ALL = ~0,
53};
54
55#define DEBUG_LEVEL (DEBUG_NONE)
56
57#define DEBUG_DUMP_LIMIT 1024
58
59#define wl12xx_error(fmt, arg...) \
60 printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
61
62#define wl12xx_warning(fmt, arg...) \
63 printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
64
65#define wl12xx_notice(fmt, arg...) \
66 printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
67
68#define wl12xx_info(fmt, arg...) \
69 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
70
71#define wl12xx_debug(level, fmt, arg...) \
72 do { \
73 if (level & DEBUG_LEVEL) \
74 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
75 } while (0)
76
77#define wl12xx_dump(level, prefix, buf, len) \
78 do { \
79 if (level & DEBUG_LEVEL) \
80 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
81 DUMP_PREFIX_OFFSET, 16, 1, \
82 buf, \
83 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
84 0); \
85 } while (0)
86
87#define wl12xx_dump_ascii(level, prefix, buf, len) \
88 do { \
89 if (level & DEBUG_LEVEL) \
90 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
91 DUMP_PREFIX_OFFSET, 16, 1, \
92 buf, \
93 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
94 true); \
95 } while (0)
96
97#define WL12XX_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
98 CFG_BSSID_FILTER_EN)
99
100#define WL12XX_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
101 CFG_RX_MGMT_EN | \
102 CFG_RX_DATA_EN | \
103 CFG_RX_CTL_EN | \
104 CFG_RX_BCN_EN | \
105 CFG_RX_AUTH_EN | \
106 CFG_RX_ASSOC_EN)
107
108
109struct boot_attr {
110 u32 radio_type;
111 u8 mac_clock;
112 u8 arm_clock;
113 int firmware_debug;
114 u32 minor;
115 u32 major;
116 u32 bugfix;
117};
118
119enum wl12xx_state {
120 WL12XX_STATE_OFF,
121 WL12XX_STATE_ON,
122 WL12XX_STATE_PLT,
123};
124
125enum wl12xx_partition_type {
126 PART_DOWN,
127 PART_WORK,
128 PART_DRPW,
129
130 PART_TABLE_LEN
131};
132
133struct wl12xx_partition {
134 u32 size;
135 u32 start;
136};
137
138struct wl12xx_partition_set {
139 struct wl12xx_partition mem;
140 struct wl12xx_partition reg;
141};
142
143struct wl12xx;
144
145/* FIXME: I'm not sure about this structure name */
146struct wl12xx_chip {
147 u32 id;
148
149 const char *fw_filename;
150 const char *nvs_filename;
151
152 char fw_ver[21];
153
154 unsigned int power_on_sleep;
155 int intr_cmd_complete;
156 int intr_init_complete;
157
158 int (*op_upload_fw)(struct wl12xx *wl);
159 int (*op_upload_nvs)(struct wl12xx *wl);
160 int (*op_boot)(struct wl12xx *wl);
161 void (*op_set_ecpu_ctrl)(struct wl12xx *wl, u32 flag);
162 void (*op_target_enable_interrupts)(struct wl12xx *wl);
163 int (*op_hw_init)(struct wl12xx *wl);
164 int (*op_plt_init)(struct wl12xx *wl);
165
166 struct wl12xx_partition_set *p_table;
167 enum wl12xx_acx_int_reg *acx_reg_table;
168};
169
170struct wl12xx_stats {
171 struct acx_statistics *fw_stats;
172 unsigned long fw_stats_update;
173
174 unsigned int retry_count;
175 unsigned int excessive_retries;
176};
177
178struct wl12xx_debugfs {
179 struct dentry *rootdir;
180 struct dentry *fw_statistics;
181
182 struct dentry *tx_internal_desc_overflow;
183
184 struct dentry *rx_out_of_mem;
185 struct dentry *rx_hdr_overflow;
186 struct dentry *rx_hw_stuck;
187 struct dentry *rx_dropped;
188 struct dentry *rx_fcs_err;
189 struct dentry *rx_xfr_hint_trig;
190 struct dentry *rx_path_reset;
191 struct dentry *rx_reset_counter;
192
193 struct dentry *dma_rx_requested;
194 struct dentry *dma_rx_errors;
195 struct dentry *dma_tx_requested;
196 struct dentry *dma_tx_errors;
197
198 struct dentry *isr_cmd_cmplt;
199 struct dentry *isr_fiqs;
200 struct dentry *isr_rx_headers;
201 struct dentry *isr_rx_mem_overflow;
202 struct dentry *isr_rx_rdys;
203 struct dentry *isr_irqs;
204 struct dentry *isr_tx_procs;
205 struct dentry *isr_decrypt_done;
206 struct dentry *isr_dma0_done;
207 struct dentry *isr_dma1_done;
208 struct dentry *isr_tx_exch_complete;
209 struct dentry *isr_commands;
210 struct dentry *isr_rx_procs;
211 struct dentry *isr_hw_pm_mode_changes;
212 struct dentry *isr_host_acknowledges;
213 struct dentry *isr_pci_pm;
214 struct dentry *isr_wakeups;
215 struct dentry *isr_low_rssi;
216
217 struct dentry *wep_addr_key_count;
218 struct dentry *wep_default_key_count;
219 /* skipping wep.reserved */
220 struct dentry *wep_key_not_found;
221 struct dentry *wep_decrypt_fail;
222 struct dentry *wep_packets;
223 struct dentry *wep_interrupt;
224
225 struct dentry *pwr_ps_enter;
226 struct dentry *pwr_elp_enter;
227 struct dentry *pwr_missing_bcns;
228 struct dentry *pwr_wake_on_host;
229 struct dentry *pwr_wake_on_timer_exp;
230 struct dentry *pwr_tx_with_ps;
231 struct dentry *pwr_tx_without_ps;
232 struct dentry *pwr_rcvd_beacons;
233 struct dentry *pwr_power_save_off;
234 struct dentry *pwr_enable_ps;
235 struct dentry *pwr_disable_ps;
236 struct dentry *pwr_fix_tsf_ps;
237 /* skipping cont_miss_bcns_spread for now */
238 struct dentry *pwr_rcvd_awake_beacons;
239
240 struct dentry *mic_rx_pkts;
241 struct dentry *mic_calc_failure;
242
243 struct dentry *aes_encrypt_fail;
244 struct dentry *aes_decrypt_fail;
245 struct dentry *aes_encrypt_packets;
246 struct dentry *aes_decrypt_packets;
247 struct dentry *aes_encrypt_interrupt;
248 struct dentry *aes_decrypt_interrupt;
249
250 struct dentry *event_heart_beat;
251 struct dentry *event_calibration;
252 struct dentry *event_rx_mismatch;
253 struct dentry *event_rx_mem_empty;
254 struct dentry *event_rx_pool;
255 struct dentry *event_oom_late;
256 struct dentry *event_phy_transmit_error;
257 struct dentry *event_tx_stuck;
258
259 struct dentry *ps_pspoll_timeouts;
260 struct dentry *ps_upsd_timeouts;
261 struct dentry *ps_upsd_max_sptime;
262 struct dentry *ps_upsd_max_apturn;
263 struct dentry *ps_pspoll_max_apturn;
264 struct dentry *ps_pspoll_utilization;
265 struct dentry *ps_upsd_utilization;
266
267 struct dentry *rxpipe_rx_prep_beacon_drop;
268 struct dentry *rxpipe_descr_host_int_trig_rx_data;
269 struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
270 struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
271 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
272
273 struct dentry *tx_queue_len;
274
275 struct dentry *retry_count;
276 struct dentry *excessive_retries;
277};
278
279struct wl12xx {
280 struct ieee80211_hw *hw;
281 bool mac80211_registered;
282
283 struct spi_device *spi;
284
285 void (*set_power)(bool enable);
286 int irq;
287
288 enum wl12xx_state state;
289 struct mutex mutex;
290
291 int physical_mem_addr;
292 int physical_reg_addr;
293 int virtual_mem_addr;
294 int virtual_reg_addr;
295
296 struct wl12xx_chip chip;
297
298 int cmd_box_addr;
299 int event_box_addr;
300 struct boot_attr boot_attr;
301
302 u8 *fw;
303 size_t fw_len;
304 u8 *nvs;
305 size_t nvs_len;
306
307 u8 bssid[ETH_ALEN];
308 u8 mac_addr[ETH_ALEN];
309 u8 bss_type;
310 u8 listen_int;
311 int channel;
312
313 void *target_mem_map;
314 struct acx_data_path_params_resp *data_path;
315
316 /* Number of TX packets transferred to the FW, modulo 16 */
317 u32 data_in_count;
318
319 /* Frames scheduled for transmission, not handled yet */
320 struct sk_buff_head tx_queue;
321 bool tx_queue_stopped;
322
323 struct work_struct tx_work;
324 struct work_struct filter_work;
325
326 /* Pending TX frames */
327 struct sk_buff *tx_frames[16];
328
329 /*
330 * Index pointing to the next TX complete entry
331 * in the cyclic XT complete array we get from
332 * the FW.
333 */
334 u32 next_tx_complete;
335
336 /* FW Rx counter */
337 u32 rx_counter;
338
339 /* Rx frames handled */
340 u32 rx_handled;
341
342 /* Current double buffer */
343 u32 rx_current_buffer;
344 u32 rx_last_id;
345
346 /* The target interrupt mask */
347 u32 intr_mask;
348 struct work_struct irq_work;
349
350 /* The mbox event mask */
351 u32 event_mask;
352
353 /* Mailbox pointers */
354 u32 mbox_ptr[2];
355
356 /* Are we currently scanning */
357 bool scanning;
358
359 /* Our association ID */
360 u16 aid;
361
362 /* Default key (for WEP) */
363 u32 default_key;
364
365 unsigned int tx_mgmt_frm_rate;
366 unsigned int tx_mgmt_frm_mod;
367
368 unsigned int rx_config;
369 unsigned int rx_filter;
370
371 /* is firmware in elp mode */
372 bool elp;
373
374 /* we can be in psm, but not in elp, we have to differentiate */
375 bool psm;
376
377 /* PSM mode requested */
378 bool psm_requested;
379
380 /* in dBm */
381 int power_level;
382
383 struct wl12xx_stats stats;
384 struct wl12xx_debugfs debugfs;
385};
386
387int wl12xx_plt_start(struct wl12xx *wl);
388int wl12xx_plt_stop(struct wl12xx *wl);
389
390#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
391#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
392#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
393
394#define WL12XX_DEFAULT_POWER_LEVEL 20
395
396#define WL12XX_TX_QUEUE_MAX_LENGTH 20
397
398/* Different chips need different sleep times after power on. WL1271 needs
399 * 200ms, WL1251 needs only 10ms. By default we use 200ms, but as soon as we
400 * know the chip ID, we change the sleep value in the wl12xx chip structure,
401 * so in subsequent power ons, we don't waste more time then needed. */
402#define WL12XX_DEFAULT_POWER_ON_SLEEP 200
403
404#define CHIP_ID_1251_PG10 (0x7010101)
405#define CHIP_ID_1251_PG11 (0x7020101)
406#define CHIP_ID_1251_PG12 (0x7030101)
407#define CHIP_ID_1271_PG10 (0x4030101)
408
409#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
new file mode 100644
index 000000000000..657c2dbcb7d3
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h
@@ -0,0 +1,156 @@
1#ifndef __WL12XX_80211_H__
2#define __WL12XX_80211_H__
3
4#include <linux/if_ether.h> /* ETH_ALEN */
5
6/* RATES */
7#define IEEE80211_CCK_RATE_1MB 0x02
8#define IEEE80211_CCK_RATE_2MB 0x04
9#define IEEE80211_CCK_RATE_5MB 0x0B
10#define IEEE80211_CCK_RATE_11MB 0x16
11#define IEEE80211_OFDM_RATE_6MB 0x0C
12#define IEEE80211_OFDM_RATE_9MB 0x12
13#define IEEE80211_OFDM_RATE_12MB 0x18
14#define IEEE80211_OFDM_RATE_18MB 0x24
15#define IEEE80211_OFDM_RATE_24MB 0x30
16#define IEEE80211_OFDM_RATE_36MB 0x48
17#define IEEE80211_OFDM_RATE_48MB 0x60
18#define IEEE80211_OFDM_RATE_54MB 0x6C
19#define IEEE80211_BASIC_RATE_MASK 0x80
20
21#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
22#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
23#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
24#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
25#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
26#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
27#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
28#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
29#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
30#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
31#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
32#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
33
34#define IEEE80211_CCK_RATES_MASK 0x0000000F
35#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
36 IEEE80211_CCK_RATE_2MB_MASK)
37#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
38 IEEE80211_CCK_RATE_5MB_MASK | \
39 IEEE80211_CCK_RATE_11MB_MASK)
40
41#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
42#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
43 IEEE80211_OFDM_RATE_12MB_MASK | \
44 IEEE80211_OFDM_RATE_24MB_MASK)
45#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
46 IEEE80211_OFDM_RATE_9MB_MASK | \
47 IEEE80211_OFDM_RATE_18MB_MASK | \
48 IEEE80211_OFDM_RATE_36MB_MASK | \
49 IEEE80211_OFDM_RATE_48MB_MASK | \
50 IEEE80211_OFDM_RATE_54MB_MASK)
51#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
52 IEEE80211_CCK_DEFAULT_RATES_MASK)
53
54
55/* This really should be 8, but not for our firmware */
56#define MAX_SUPPORTED_RATES 32
57#define COUNTRY_STRING_LEN 3
58#define MAX_COUNTRY_TRIPLETS 32
59
60/* Headers */
61struct ieee80211_header {
62 __le16 frame_ctl;
63 __le16 duration_id;
64 u8 da[ETH_ALEN];
65 u8 sa[ETH_ALEN];
66 u8 bssid[ETH_ALEN];
67 __le16 seq_ctl;
68 u8 payload[0];
69} __attribute__ ((packed));
70
71struct wl12xx_ie_header {
72 u8 id;
73 u8 len;
74} __attribute__ ((packed));
75
76/* IEs */
77
78struct wl12xx_ie_ssid {
79 struct wl12xx_ie_header header;
80 char ssid[IW_ESSID_MAX_SIZE];
81} __attribute__ ((packed));
82
83struct wl12xx_ie_rates {
84 struct wl12xx_ie_header header;
85 u8 rates[MAX_SUPPORTED_RATES];
86} __attribute__ ((packed));
87
88struct wl12xx_ie_ds_params {
89 struct wl12xx_ie_header header;
90 u8 channel;
91} __attribute__ ((packed));
92
93struct country_triplet {
94 u8 channel;
95 u8 num_channels;
96 u8 max_tx_power;
97} __attribute__ ((packed));
98
99struct wl12xx_ie_country {
100 struct wl12xx_ie_header header;
101 u8 country_string[COUNTRY_STRING_LEN];
102 struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
103} __attribute__ ((packed));
104
105
106/* Templates */
107
108struct wl12xx_beacon_template {
109 struct ieee80211_header header;
110 __le32 time_stamp[2];
111 __le16 beacon_interval;
112 __le16 capability;
113 struct wl12xx_ie_ssid ssid;
114 struct wl12xx_ie_rates rates;
115 struct wl12xx_ie_rates ext_rates;
116 struct wl12xx_ie_ds_params ds_params;
117 struct wl12xx_ie_country country;
118} __attribute__ ((packed));
119
120struct wl12xx_null_data_template {
121 struct ieee80211_header header;
122} __attribute__ ((packed));
123
124struct wl12xx_ps_poll_template {
125 u16 fc;
126 u16 aid;
127 u8 bssid[ETH_ALEN];
128 u8 ta[ETH_ALEN];
129} __attribute__ ((packed));
130
131struct wl12xx_qos_null_data_template {
132 struct ieee80211_header header;
133 __le16 qos_ctl;
134} __attribute__ ((packed));
135
136struct wl12xx_probe_req_template {
137 struct ieee80211_header header;
138 struct wl12xx_ie_ssid ssid;
139 struct wl12xx_ie_rates rates;
140 struct wl12xx_ie_rates ext_rates;
141} __attribute__ ((packed));
142
143
144struct wl12xx_probe_resp_template {
145 struct ieee80211_header header;
146 __le32 time_stamp[2];
147 __le16 beacon_interval;
148 __le16 capability;
149 struct wl12xx_ie_ssid ssid;
150 struct wl12xx_ie_rates rates;
151 struct wl12xx_ie_rates ext_rates;
152 struct wl12xx_ie_ds_params ds_params;
153 struct wl12xx_ie_country country;
154} __attribute__ ((packed));
155
156#endif