aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@nokia.com>2009-08-06 09:25:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:12:46 -0400
commitf5fc0f86b02afef1119b523623b4cde41475bc8c (patch)
tree793be075412781fef4fcd752032e9b3680eaf96f /drivers/net/wireless/wl12xx
parentb935df01ed4f0848f29b1e39c4f95d87b0206dea (diff)
wl1271: add wl1271 driver files
This driver supports the wl1271 chipset from Texas Instruments based on the WiLink(tm) 6.0 mobile platform. Support for wl1273 should be relatively easy to add. This chipset is designed for embedded devices, with good powersaving capabilities. The wl1271 chipset is the successor of wl1251 and supports the 802.11b/g/n standards, but currently this driver supports only b/g. More information about this chipset can be found here: http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?templateId=6123&navigationId=12762&contentId=29993 Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h407
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c961
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h1221
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c540
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h72
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c813
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h464
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c518
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c125
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.h110
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c397
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.h115
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1396
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c142
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h35
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_reg.h758
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c200
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.h121
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c382
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.h113
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c378
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h130
23 files changed, 9431 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
new file mode 100644
index 000000000000..55818f94017b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -0,0 +1,407 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_H__
26#define __WL1271_H__
27
28#include <linux/mutex.h>
29#include <linux/completion.h>
30#include <linux/spinlock.h>
31#include <linux/list.h>
32#include <linux/bitops.h>
33#include <net/mac80211.h>
34
35#define DRIVER_NAME "wl1271"
36#define DRIVER_PREFIX DRIVER_NAME ": "
37
38enum {
39 DEBUG_NONE = 0,
40 DEBUG_IRQ = BIT(0),
41 DEBUG_SPI = BIT(1),
42 DEBUG_BOOT = BIT(2),
43 DEBUG_MAILBOX = BIT(3),
44 DEBUG_NETLINK = BIT(4),
45 DEBUG_EVENT = BIT(5),
46 DEBUG_TX = BIT(6),
47 DEBUG_RX = BIT(7),
48 DEBUG_SCAN = BIT(8),
49 DEBUG_CRYPT = BIT(9),
50 DEBUG_PSM = BIT(10),
51 DEBUG_MAC80211 = BIT(11),
52 DEBUG_CMD = BIT(12),
53 DEBUG_ACX = BIT(13),
54 DEBUG_ALL = ~0,
55};
56
57#define DEBUG_LEVEL (DEBUG_NONE)
58
59#define DEBUG_DUMP_LIMIT 1024
60
61#define wl1271_error(fmt, arg...) \
62 printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
63
64#define wl1271_warning(fmt, arg...) \
65 printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
66
67#define wl1271_notice(fmt, arg...) \
68 printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
69
70#define wl1271_info(fmt, arg...) \
71 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
72
73#define wl1271_debug(level, fmt, arg...) \
74 do { \
75 if (level & DEBUG_LEVEL) \
76 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
77 } while (0)
78
79#define wl1271_dump(level, prefix, buf, len) \
80 do { \
81 if (level & DEBUG_LEVEL) \
82 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
83 DUMP_PREFIX_OFFSET, 16, 1, \
84 buf, \
85 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
86 0); \
87 } while (0)
88
89#define wl1271_dump_ascii(level, prefix, buf, len) \
90 do { \
91 if (level & DEBUG_LEVEL) \
92 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
93 DUMP_PREFIX_OFFSET, 16, 1, \
94 buf, \
95 min_t(size_t, len, DEBUG_DUMP_LIMIT), \
96 true); \
97 } while (0)
98
99#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
100 CFG_BSSID_FILTER_EN)
101
102#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \
103 CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \
104 CFG_RX_CTL_EN | CFG_RX_BCN_EN | \
105 CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
106
107#define WL1271_FW_NAME "wl1271-fw.bin"
108#define WL1271_NVS_NAME "wl1271-nvs.bin"
109
110#define WL1271_BUSY_WORD_LEN 8
111
112#define WL1271_ELP_HW_STATE_ASLEEP 0
113#define WL1271_ELP_HW_STATE_IRQ 1
114
115enum wl1271_state {
116 WL1271_STATE_OFF,
117 WL1271_STATE_ON,
118 WL1271_STATE_PLT,
119};
120
121enum wl1271_partition_type {
122 PART_DOWN,
123 PART_WORK,
124 PART_DRPW,
125
126 PART_TABLE_LEN
127};
128
129struct wl1271_partition {
130 u32 size;
131 u32 start;
132};
133
134struct wl1271_partition_set {
135 struct wl1271_partition mem;
136 struct wl1271_partition reg;
137};
138
139struct wl1271;
140
141/* FIXME: I'm not sure about this structure name */
142struct wl1271_chip {
143 u32 id;
144 char fw_ver[21];
145};
146
147struct wl1271_stats {
148 struct acx_statistics *fw_stats;
149 unsigned long fw_stats_update;
150
151 unsigned int retry_count;
152 unsigned int excessive_retries;
153};
154
155struct wl1271_debugfs {
156 struct dentry *rootdir;
157 struct dentry *fw_statistics;
158
159 struct dentry *tx_internal_desc_overflow;
160
161 struct dentry *rx_out_of_mem;
162 struct dentry *rx_hdr_overflow;
163 struct dentry *rx_hw_stuck;
164 struct dentry *rx_dropped;
165 struct dentry *rx_fcs_err;
166 struct dentry *rx_xfr_hint_trig;
167 struct dentry *rx_path_reset;
168 struct dentry *rx_reset_counter;
169
170 struct dentry *dma_rx_requested;
171 struct dentry *dma_rx_errors;
172 struct dentry *dma_tx_requested;
173 struct dentry *dma_tx_errors;
174
175 struct dentry *isr_cmd_cmplt;
176 struct dentry *isr_fiqs;
177 struct dentry *isr_rx_headers;
178 struct dentry *isr_rx_mem_overflow;
179 struct dentry *isr_rx_rdys;
180 struct dentry *isr_irqs;
181 struct dentry *isr_tx_procs;
182 struct dentry *isr_decrypt_done;
183 struct dentry *isr_dma0_done;
184 struct dentry *isr_dma1_done;
185 struct dentry *isr_tx_exch_complete;
186 struct dentry *isr_commands;
187 struct dentry *isr_rx_procs;
188 struct dentry *isr_hw_pm_mode_changes;
189 struct dentry *isr_host_acknowledges;
190 struct dentry *isr_pci_pm;
191 struct dentry *isr_wakeups;
192 struct dentry *isr_low_rssi;
193
194 struct dentry *wep_addr_key_count;
195 struct dentry *wep_default_key_count;
196 /* skipping wep.reserved */
197 struct dentry *wep_key_not_found;
198 struct dentry *wep_decrypt_fail;
199 struct dentry *wep_packets;
200 struct dentry *wep_interrupt;
201
202 struct dentry *pwr_ps_enter;
203 struct dentry *pwr_elp_enter;
204 struct dentry *pwr_missing_bcns;
205 struct dentry *pwr_wake_on_host;
206 struct dentry *pwr_wake_on_timer_exp;
207 struct dentry *pwr_tx_with_ps;
208 struct dentry *pwr_tx_without_ps;
209 struct dentry *pwr_rcvd_beacons;
210 struct dentry *pwr_power_save_off;
211 struct dentry *pwr_enable_ps;
212 struct dentry *pwr_disable_ps;
213 struct dentry *pwr_fix_tsf_ps;
214 /* skipping cont_miss_bcns_spread for now */
215 struct dentry *pwr_rcvd_awake_beacons;
216
217 struct dentry *mic_rx_pkts;
218 struct dentry *mic_calc_failure;
219
220 struct dentry *aes_encrypt_fail;
221 struct dentry *aes_decrypt_fail;
222 struct dentry *aes_encrypt_packets;
223 struct dentry *aes_decrypt_packets;
224 struct dentry *aes_encrypt_interrupt;
225 struct dentry *aes_decrypt_interrupt;
226
227 struct dentry *event_heart_beat;
228 struct dentry *event_calibration;
229 struct dentry *event_rx_mismatch;
230 struct dentry *event_rx_mem_empty;
231 struct dentry *event_rx_pool;
232 struct dentry *event_oom_late;
233 struct dentry *event_phy_transmit_error;
234 struct dentry *event_tx_stuck;
235
236 struct dentry *ps_pspoll_timeouts;
237 struct dentry *ps_upsd_timeouts;
238 struct dentry *ps_upsd_max_sptime;
239 struct dentry *ps_upsd_max_apturn;
240 struct dentry *ps_pspoll_max_apturn;
241 struct dentry *ps_pspoll_utilization;
242 struct dentry *ps_upsd_utilization;
243
244 struct dentry *rxpipe_rx_prep_beacon_drop;
245 struct dentry *rxpipe_descr_host_int_trig_rx_data;
246 struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
247 struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
248 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
249
250 struct dentry *tx_queue_len;
251
252 struct dentry *retry_count;
253 struct dentry *excessive_retries;
254};
255
256#define NUM_TX_QUEUES 4
257#define NUM_RX_PKT_DESC 8
258
259/* FW status registers */
260struct wl1271_fw_status {
261 u32 intr;
262 u8 fw_rx_counter;
263 u8 drv_rx_counter;
264 u8 reserved;
265 u8 tx_results_counter;
266 u32 rx_pkt_descs[NUM_RX_PKT_DESC];
267 u32 tx_released_blks[NUM_TX_QUEUES];
268 u32 fw_localtime;
269 u32 padding[2];
270} __attribute__ ((packed));
271
272struct wl1271_rx_mem_pool_addr {
273 u32 addr;
274 u32 addr_extra;
275};
276
277struct wl1271 {
278 struct ieee80211_hw *hw;
279 bool mac80211_registered;
280
281 struct spi_device *spi;
282
283 void (*set_power)(bool enable);
284 int irq;
285
286 spinlock_t wl_lock;
287
288 enum wl1271_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 wl1271_chip chip;
297
298 int cmd_box_addr;
299 int event_box_addr;
300
301 u8 *fw;
302 size_t fw_len;
303 u8 *nvs;
304 size_t nvs_len;
305
306 u8 bssid[ETH_ALEN];
307 u8 mac_addr[ETH_ALEN];
308 u8 bss_type;
309 u8 ssid[IW_ESSID_MAX_SIZE + 1];
310 u8 ssid_len;
311 u8 listen_int;
312 int channel;
313
314 struct wl1271_acx_mem_map *target_mem_map;
315
316 /* Accounting for allocated / available TX blocks on HW */
317 u32 tx_blocks_freed[NUM_TX_QUEUES];
318 u32 tx_blocks_available;
319 u8 tx_results_count;
320
321 /* Transmitted TX packets counter for chipset interface */
322 int tx_packets_count;
323
324 /* Time-offset between host and chipset clocks */
325 int time_offset;
326
327 /* Session counter for the chipset */
328 int session_counter;
329
330 /* Frames scheduled for transmission, not handled yet */
331 struct sk_buff_head tx_queue;
332 bool tx_queue_stopped;
333
334 struct work_struct tx_work;
335 struct work_struct filter_work;
336
337 /* Pending TX frames */
338 struct sk_buff *tx_frames[16];
339
340 /* FW Rx counter */
341 u32 rx_counter;
342
343 /* Rx memory pool address */
344 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
345
346 /* The target interrupt mask */
347 struct work_struct irq_work;
348
349 /* The mbox event mask */
350 u32 event_mask;
351
352 /* Mailbox pointers */
353 u32 mbox_ptr[2];
354
355 /* Are we currently scanning */
356 bool scanning;
357
358 /* Our association ID */
359 u16 aid;
360
361 /* Default key (for WEP) */
362 u32 default_key;
363
364 unsigned int rx_config;
365 unsigned int rx_filter;
366
367 /* is firmware in elp mode */
368 bool elp;
369
370 struct completion *elp_compl;
371
372 /* we can be in psm, but not in elp, we have to differentiate */
373 bool psm;
374
375 /* PSM mode requested */
376 bool psm_requested;
377
378 /* in dBm */
379 int power_level;
380
381 struct wl1271_stats stats;
382 struct wl1271_debugfs debugfs;
383
384 u32 buffer_32;
385 u32 buffer_cmd;
386 u8 buffer_busyword[WL1271_BUSY_WORD_LEN];
387 struct wl1271_rx_descriptor *rx_descriptor;
388
389 struct wl1271_fw_status *fw_status;
390 struct wl1271_tx_hw_res_if *tx_res_if;
391};
392
393int wl1271_plt_start(struct wl1271 *wl);
394int wl1271_plt_stop(struct wl1271 *wl);
395
396#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
397
398#define SESSION_COUNTER_MAX 7 /* maximum value for the session counter */
399
400#define WL1271_DEFAULT_POWER_LEVEL 0
401
402#define WL1271_TX_QUEUE_MAX_LENGTH 20
403
404/* WL1271 needs a 200ms sleep after power on */
405#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
406
407#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
new file mode 100644
index 000000000000..f622a4092615
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -0,0 +1,961 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_acx.h"
25
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/crc7.h>
29#include <linux/spi/spi.h>
30
31#include "wl1271.h"
32#include "wl12xx_80211.h"
33#include "wl1271_reg.h"
34#include "wl1271_spi.h"
35#include "wl1271_ps.h"
36
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
38 u8 listen_interval)
39{
40 struct acx_wake_up_condition *wake_up;
41 int ret;
42
43 wl1271_debug(DEBUG_ACX, "acx wake up conditions");
44
45 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
46 if (!wake_up) {
47 ret = -ENOMEM;
48 goto out;
49 }
50
51 wake_up->wake_up_event = wake_up_event;
52 wake_up->listen_interval = listen_interval;
53
54 ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
55 wake_up, sizeof(*wake_up));
56 if (ret < 0) {
57 wl1271_warning("could not set wake up conditions: %d", ret);
58 goto out;
59 }
60
61out:
62 kfree(wake_up);
63 return ret;
64}
65
66int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
67{
68 struct acx_sleep_auth *auth;
69 int ret;
70
71 wl1271_debug(DEBUG_ACX, "acx sleep auth");
72
73 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
74 if (!auth) {
75 ret = -ENOMEM;
76 goto out;
77 }
78
79 auth->sleep_auth = sleep_auth;
80
81 ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
82 if (ret < 0)
83 return ret;
84
85out:
86 kfree(auth);
87 return ret;
88}
89
90int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
91{
92 struct acx_revision *rev;
93 int ret;
94
95 wl1271_debug(DEBUG_ACX, "acx fw rev");
96
97 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
98 if (!rev) {
99 ret = -ENOMEM;
100 goto out;
101 }
102
103 ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
104 if (ret < 0) {
105 wl1271_warning("ACX_FW_REV interrogate failed");
106 goto out;
107 }
108
109 /* be careful with the buffer sizes */
110 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
111
112 /*
113 * if the firmware version string is exactly
114 * sizeof(rev->fw_version) long or fw_len is less than
115 * sizeof(rev->fw_version) it won't be null terminated
116 */
117 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
118
119out:
120 kfree(rev);
121 return ret;
122}
123
124int wl1271_acx_tx_power(struct wl1271 *wl, int power)
125{
126 struct acx_current_tx_power *acx;
127 int ret;
128
129 wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
130
131 if (power < 0 || power > 25)
132 return -EINVAL;
133
134 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
135 if (!acx) {
136 ret = -ENOMEM;
137 goto out;
138 }
139
140 acx->current_tx_power = power * 10;
141
142 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
143 if (ret < 0) {
144 wl1271_warning("configure of tx power failed: %d", ret);
145 goto out;
146 }
147
148out:
149 kfree(acx);
150 return ret;
151}
152
153int wl1271_acx_feature_cfg(struct wl1271 *wl)
154{
155 struct acx_feature_config *feature;
156 int ret;
157
158 wl1271_debug(DEBUG_ACX, "acx feature cfg");
159
160 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
161 if (!feature) {
162 ret = -ENOMEM;
163 goto out;
164 }
165
166 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
167 feature->data_flow_options = 0;
168 feature->options = 0;
169
170 ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
171 feature, sizeof(*feature));
172 if (ret < 0) {
173 wl1271_error("Couldnt set HW encryption");
174 goto out;
175 }
176
177out:
178 kfree(feature);
179 return ret;
180}
181
182int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
183 size_t len)
184{
185 int ret;
186
187 wl1271_debug(DEBUG_ACX, "acx mem map");
188
189 ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
190 if (ret < 0)
191 return ret;
192
193 return 0;
194}
195
196int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
197{
198 struct acx_rx_msdu_lifetime *acx;
199 int ret;
200
201 wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
202
203 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
204 if (!acx) {
205 ret = -ENOMEM;
206 goto out;
207 }
208
209 acx->lifetime = life_time;
210 ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
211 acx, sizeof(*acx));
212 if (ret < 0) {
213 wl1271_warning("failed to set rx msdu life time: %d", ret);
214 goto out;
215 }
216
217out:
218 kfree(acx);
219 return ret;
220}
221
222int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
223{
224 struct acx_rx_config *rx_config;
225 int ret;
226
227 wl1271_debug(DEBUG_ACX, "acx rx config");
228
229 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
230 if (!rx_config) {
231 ret = -ENOMEM;
232 goto out;
233 }
234
235 rx_config->config_options = config;
236 rx_config->filter_options = filter;
237
238 ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
239 rx_config, sizeof(*rx_config));
240 if (ret < 0) {
241 wl1271_warning("failed to set rx config: %d", ret);
242 goto out;
243 }
244
245out:
246 kfree(rx_config);
247 return ret;
248}
249
250int wl1271_acx_pd_threshold(struct wl1271 *wl)
251{
252 struct acx_packet_detection *pd;
253 int ret;
254
255 wl1271_debug(DEBUG_ACX, "acx data pd threshold");
256
257 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
258 if (!pd) {
259 ret = -ENOMEM;
260 goto out;
261 }
262
263 /* FIXME: threshold value not set */
264
265 ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
266 if (ret < 0) {
267 wl1271_warning("failed to set pd threshold: %d", ret);
268 goto out;
269 }
270
271out:
272 kfree(pd);
273 return 0;
274}
275
276int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
277{
278 struct acx_slot *slot;
279 int ret;
280
281 wl1271_debug(DEBUG_ACX, "acx slot");
282
283 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
284 if (!slot) {
285 ret = -ENOMEM;
286 goto out;
287 }
288
289 slot->wone_index = STATION_WONE_INDEX;
290 slot->slot_time = slot_time;
291
292 ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
293 if (ret < 0) {
294 wl1271_warning("failed to set slot time: %d", ret);
295 goto out;
296 }
297
298out:
299 kfree(slot);
300 return ret;
301}
302
303int wl1271_acx_group_address_tbl(struct wl1271 *wl)
304{
305 struct acx_dot11_grp_addr_tbl *acx;
306 int ret;
307
308 wl1271_debug(DEBUG_ACX, "acx group address tbl");
309
310 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
311 if (!acx) {
312 ret = -ENOMEM;
313 goto out;
314 }
315
316 /* MAC filtering */
317 acx->enabled = 0;
318 acx->num_groups = 0;
319 memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
320
321 ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
322 acx, sizeof(*acx));
323 if (ret < 0) {
324 wl1271_warning("failed to set group addr table: %d", ret);
325 goto out;
326 }
327
328out:
329 kfree(acx);
330 return ret;
331}
332
333int wl1271_acx_service_period_timeout(struct wl1271 *wl)
334{
335 struct acx_rx_timeout *rx_timeout;
336 int ret;
337
338 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
339 if (!rx_timeout) {
340 ret = -ENOMEM;
341 goto out;
342 }
343
344 wl1271_debug(DEBUG_ACX, "acx service period timeout");
345
346 rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
347 rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
348
349 ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
350 rx_timeout, sizeof(*rx_timeout));
351 if (ret < 0) {
352 wl1271_warning("failed to set service period timeout: %d",
353 ret);
354 goto out;
355 }
356
357out:
358 kfree(rx_timeout);
359 return ret;
360}
361
362int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
363{
364 struct acx_rts_threshold *rts;
365 int ret;
366
367 wl1271_debug(DEBUG_ACX, "acx rts threshold");
368
369 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
370 if (!rts) {
371 ret = -ENOMEM;
372 goto out;
373 }
374
375 rts->threshold = rts_threshold;
376
377 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
378 if (ret < 0) {
379 wl1271_warning("failed to set rts threshold: %d", ret);
380 goto out;
381 }
382
383out:
384 kfree(rts);
385 return ret;
386}
387
388int wl1271_acx_beacon_filter_opt(struct wl1271 *wl)
389{
390 struct acx_beacon_filter_option *beacon_filter;
391 int ret;
392
393 wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
394
395 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
396 if (!beacon_filter) {
397 ret = -ENOMEM;
398 goto out;
399 }
400
401 beacon_filter->enable = 0;
402 beacon_filter->max_num_beacons = 0;
403
404 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
405 beacon_filter, sizeof(*beacon_filter));
406 if (ret < 0) {
407 wl1271_warning("failed to set beacon filter opt: %d", ret);
408 goto out;
409 }
410
411out:
412 kfree(beacon_filter);
413 return ret;
414}
415
416int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
417{
418 struct acx_beacon_filter_ie_table *ie_table;
419 int ret;
420
421 wl1271_debug(DEBUG_ACX, "acx beacon filter table");
422
423 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
424 if (!ie_table) {
425 ret = -ENOMEM;
426 goto out;
427 }
428
429 ie_table->num_ie = 0;
430 memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
431
432 ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
433 ie_table, sizeof(*ie_table));
434 if (ret < 0) {
435 wl1271_warning("failed to set beacon filter table: %d", ret);
436 goto out;
437 }
438
439out:
440 kfree(ie_table);
441 return ret;
442}
443
444int wl1271_acx_sg_enable(struct wl1271 *wl)
445{
446 struct acx_bt_wlan_coex *pta;
447 int ret;
448
449 wl1271_debug(DEBUG_ACX, "acx sg enable");
450
451 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
452 if (!pta) {
453 ret = -ENOMEM;
454 goto out;
455 }
456
457 pta->enable = SG_ENABLE;
458
459 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
460 if (ret < 0) {
461 wl1271_warning("failed to set softgemini enable: %d", ret);
462 goto out;
463 }
464
465out:
466 kfree(pta);
467 return ret;
468}
469
470int wl1271_acx_sg_cfg(struct wl1271 *wl)
471{
472 struct acx_bt_wlan_coex_param *param;
473 int ret;
474
475 wl1271_debug(DEBUG_ACX, "acx sg cfg");
476
477 param = kzalloc(sizeof(*param), GFP_KERNEL);
478 if (!param) {
479 ret = -ENOMEM;
480 goto out;
481 }
482
483 /* BT-WLAN coext parameters */
484 param->min_rate = RATE_INDEX_24MBPS;
485 param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
486 param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
487 param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
488 param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
489 param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
490 param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
491 param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
492 param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
493 param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
494 param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
495 param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
496 param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
497 param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
498 param->antenna_type = PTA_ANTENNA_TYPE_DEF;
499 param->signal_type = PTA_SIGNALING_TYPE_DEF;
500 param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
501 param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
502 param->max_cts = PTA_MAX_NUM_CTS_DEF;
503 param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
504 param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
505 param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
506 param->wlan_elp_hp = PTA_ELP_HP_DEF;
507 param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
508 param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
509 param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
510 param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
511 param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
512
513 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
514 if (ret < 0) {
515 wl1271_warning("failed to set sg config: %d", ret);
516 goto out;
517 }
518
519out:
520 kfree(param);
521 return ret;
522}
523
524int wl1271_acx_cca_threshold(struct wl1271 *wl)
525{
526 struct acx_energy_detection *detection;
527 int ret;
528
529 wl1271_debug(DEBUG_ACX, "acx cca threshold");
530
531 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
532 if (!detection) {
533 ret = -ENOMEM;
534 goto out;
535 }
536
537 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
538 detection->tx_energy_detection = 0;
539
540 ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
541 detection, sizeof(*detection));
542 if (ret < 0) {
543 wl1271_warning("failed to set cca threshold: %d", ret);
544 return ret;
545 }
546
547out:
548 kfree(detection);
549 return ret;
550}
551
552int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
553{
554 struct acx_beacon_broadcast *bb;
555 int ret;
556
557 wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
558
559 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
560 if (!bb) {
561 ret = -ENOMEM;
562 goto out;
563 }
564
565 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
566 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
567 bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
568 bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
569
570 ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
571 if (ret < 0) {
572 wl1271_warning("failed to set rx config: %d", ret);
573 goto out;
574 }
575
576out:
577 kfree(bb);
578 return ret;
579}
580
581int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
582{
583 struct acx_aid *acx_aid;
584 int ret;
585
586 wl1271_debug(DEBUG_ACX, "acx aid");
587
588 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
589 if (!acx_aid) {
590 ret = -ENOMEM;
591 goto out;
592 }
593
594 acx_aid->aid = aid;
595
596 ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
597 if (ret < 0) {
598 wl1271_warning("failed to set aid: %d", ret);
599 goto out;
600 }
601
602out:
603 kfree(acx_aid);
604 return ret;
605}
606
607int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
608{
609 struct acx_event_mask *mask;
610 int ret;
611
612 wl1271_debug(DEBUG_ACX, "acx event mbox mask");
613
614 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
615 if (!mask) {
616 ret = -ENOMEM;
617 goto out;
618 }
619
620 /* high event mask is unused */
621 mask->high_event_mask = 0xffffffff;
622
623 mask->event_mask = event_mask;
624
625 ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
626 mask, sizeof(*mask));
627 if (ret < 0) {
628 wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
629 goto out;
630 }
631
632out:
633 kfree(mask);
634 return ret;
635}
636
637int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
638{
639 struct acx_preamble *acx;
640 int ret;
641
642 wl1271_debug(DEBUG_ACX, "acx_set_preamble");
643
644 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
645 if (!acx) {
646 ret = -ENOMEM;
647 goto out;
648 }
649
650 acx->preamble = preamble;
651
652 ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
653 if (ret < 0) {
654 wl1271_warning("Setting of preamble failed: %d", ret);
655 goto out;
656 }
657
658out:
659 kfree(acx);
660 return ret;
661}
662
663int wl1271_acx_cts_protect(struct wl1271 *wl,
664 enum acx_ctsprotect_type ctsprotect)
665{
666 struct acx_ctsprotect *acx;
667 int ret;
668
669 wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
670
671 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
672 if (!acx) {
673 ret = -ENOMEM;
674 goto out;
675 }
676
677 acx->ctsprotect = ctsprotect;
678
679 ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
680 if (ret < 0) {
681 wl1271_warning("Setting of ctsprotect failed: %d", ret);
682 goto out;
683 }
684
685out:
686 kfree(acx);
687 return ret;
688}
689
690int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
691{
692 int ret;
693
694 wl1271_debug(DEBUG_ACX, "acx statistics");
695
696 ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
697 sizeof(*stats));
698 if (ret < 0) {
699 wl1271_warning("acx statistics failed: %d", ret);
700 return -ENOMEM;
701 }
702
703 return 0;
704}
705
706int wl1271_acx_rate_policies(struct wl1271 *wl)
707{
708 struct acx_rate_policy *acx;
709 int ret = 0;
710
711 wl1271_debug(DEBUG_ACX, "acx rate policies");
712
713 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
714
715 if (!acx) {
716 ret = -ENOMEM;
717 goto out;
718 }
719
720 /* configure one default (one-size-fits-all) rate class */
721 acx->rate_class_cnt = 1;
722 acx->rate_class[0].enabled_rates = ACX_RATE_MASK_ALL;
723 acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
724 acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
725 acx->rate_class[0].aflags = 0;
726
727 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
728 if (ret < 0) {
729 wl1271_warning("Setting of rate policies failed: %d", ret);
730 goto out;
731 }
732
733out:
734 kfree(acx);
735 return ret;
736}
737
738int wl1271_acx_ac_cfg(struct wl1271 *wl)
739{
740 struct acx_ac_cfg *acx;
741 int i, ret = 0;
742
743 wl1271_debug(DEBUG_ACX, "acx access category config");
744
745 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
746
747 if (!acx) {
748 ret = -ENOMEM;
749 goto out;
750 }
751
752 /*
753 * FIXME: Configure each AC with appropriate values (most suitable
754 * values will probably be different for each AC.
755 */
756 for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
757 acx->ac = i;
758
759 /*
760 * FIXME: The following default values originate from
761 * the TI reference driver. What do they mean?
762 */
763 acx->cw_min = 15;
764 acx->cw_max = 63;
765 acx->aifsn = 3;
766 acx->reserved = 0;
767 acx->tx_op_limit = 0;
768
769 ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
770 if (ret < 0) {
771 wl1271_warning("Setting of access category "
772 "config: %d", ret);
773 goto out;
774 }
775 }
776
777out:
778 kfree(acx);
779 return ret;
780}
781
782int wl1271_acx_tid_cfg(struct wl1271 *wl)
783{
784 struct acx_tid_config *acx;
785 int i, ret = 0;
786
787 wl1271_debug(DEBUG_ACX, "acx tid config");
788
789 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
790
791 if (!acx) {
792 ret = -ENOMEM;
793 goto out;
794 }
795
796 /* FIXME: configure each TID with a different AC reference */
797 for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
798 acx->queue_id = i;
799 acx->tsid = WL1271_ACX_AC_BE;
800 acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
801 acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
802
803 ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
804 if (ret < 0) {
805 wl1271_warning("Setting of tid config failed: %d", ret);
806 goto out;
807 }
808 }
809
810out:
811 kfree(acx);
812 return ret;
813}
814
815int wl1271_acx_frag_threshold(struct wl1271 *wl)
816{
817 struct acx_frag_threshold *acx;
818 int ret = 0;
819
820 wl1271_debug(DEBUG_ACX, "acx frag threshold");
821
822 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
823
824 if (!acx) {
825 ret = -ENOMEM;
826 goto out;
827 }
828
829 acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
830 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
831 if (ret < 0) {
832 wl1271_warning("Setting of frag threshold failed: %d", ret);
833 goto out;
834 }
835
836out:
837 kfree(acx);
838 return ret;
839}
840
841int wl1271_acx_tx_config_options(struct wl1271 *wl)
842{
843 struct acx_tx_config_options *acx;
844 int ret = 0;
845
846 wl1271_debug(DEBUG_ACX, "acx tx config options");
847
848 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
849
850 if (!acx) {
851 ret = -ENOMEM;
852 goto out;
853 }
854
855 acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
856 acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
857 ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
858 if (ret < 0) {
859 wl1271_warning("Setting of tx options failed: %d", ret);
860 goto out;
861 }
862
863out:
864 kfree(acx);
865 return ret;
866}
867
868int wl1271_acx_mem_cfg(struct wl1271 *wl)
869{
870 struct wl1271_acx_config_memory *mem_conf;
871 int ret;
872
873 wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
874
875 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
876 if (!mem_conf) {
877 ret = -ENOMEM;
878 goto out;
879 }
880
881 /* memory config */
882 mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
883 mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
884 mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
885 mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
886 mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
887
888 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
889 sizeof(*mem_conf));
890 if (ret < 0) {
891 wl1271_warning("wl1271 mem config failed: %d", ret);
892 goto out;
893 }
894
895out:
896 kfree(mem_conf);
897 return ret;
898}
899
900int wl1271_acx_init_mem_config(struct wl1271 *wl)
901{
902 int ret;
903
904 ret = wl1271_acx_mem_cfg(wl);
905 if (ret < 0)
906 return ret;
907
908 wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
909 GFP_KERNEL);
910 if (!wl->target_mem_map) {
911 wl1271_error("couldn't allocate target memory map");
912 return -ENOMEM;
913 }
914
915 /* we now ask for the firmware built memory map */
916 ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
917 sizeof(struct wl1271_acx_mem_map));
918 if (ret < 0) {
919 wl1271_error("couldn't retrieve firmware memory map");
920 kfree(wl->target_mem_map);
921 wl->target_mem_map = NULL;
922 return ret;
923 }
924
925 /* initialize TX block book keeping */
926 wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
927 wl1271_debug(DEBUG_TX, "available tx blocks: %d",
928 wl->tx_blocks_available);
929
930 return 0;
931}
932
933int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
934{
935 struct wl1271_acx_rx_config_opt *rx_conf;
936 int ret;
937
938 wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
939
940 rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
941 if (!rx_conf) {
942 ret = -ENOMEM;
943 goto out;
944 }
945
946 rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
947 rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
948 rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
949 rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
950
951 ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
952 sizeof(*rx_conf));
953 if (ret < 0) {
954 wl1271_warning("wl1271 rx config opt failed: %d", ret);
955 goto out;
956 }
957
958out:
959 kfree(rx_conf);
960 return ret;
961}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
new file mode 100644
index 000000000000..9068daaf0ddf
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -0,0 +1,1221 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_ACX_H__
26#define __WL1271_ACX_H__
27
28#include "wl1271.h"
29#include "wl1271_cmd.h"
30
31/*************************************************************************
32
33 Host Interrupt Register (WiLink -> Host)
34
35**************************************************************************/
36/* HW Initiated interrupt Watchdog timer expiration */
37#define WL1271_ACX_INTR_WATCHDOG BIT(0)
38/* Init sequence is done (masked interrupt, detection through polling only ) */
39#define WL1271_ACX_INTR_INIT_COMPLETE BIT(1)
40/* Event was entered to Event MBOX #A*/
41#define WL1271_ACX_INTR_EVENT_A BIT(2)
42/* Event was entered to Event MBOX #B*/
43#define WL1271_ACX_INTR_EVENT_B BIT(3)
44/* Command processing completion*/
45#define WL1271_ACX_INTR_CMD_COMPLETE BIT(4)
46/* Signaling the host on HW wakeup */
47#define WL1271_ACX_INTR_HW_AVAILABLE BIT(5)
48/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */
49#define WL1271_ACX_INTR_DATA BIT(6)
50/* Trace meassge on MBOX #A */
51#define WL1271_ACX_INTR_TRACE_A BIT(7)
52/* Trace meassge on MBOX #B */
53#define WL1271_ACX_INTR_TRACE_B BIT(8)
54
55#define WL1271_ACX_INTR_ALL 0xFFFFFFFF
56#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \
57 WL1271_ACX_INTR_INIT_COMPLETE | \
58 WL1271_ACX_INTR_EVENT_A | \
59 WL1271_ACX_INTR_EVENT_B | \
60 WL1271_ACX_INTR_CMD_COMPLETE | \
61 WL1271_ACX_INTR_HW_AVAILABLE | \
62 WL1271_ACX_INTR_DATA)
63
64#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \
65 WL1271_ACX_INTR_EVENT_B | \
66 WL1271_ACX_INTR_DATA)
67
68/* Target's information element */
69struct acx_header {
70 struct wl1271_cmd_header cmd;
71
72 /* acx (or information element) header */
73 u16 id;
74
75 /* payload length (not including headers */
76 u16 len;
77};
78
79struct acx_error_counter {
80 struct acx_header header;
81
82 /* The number of PLCP errors since the last time this */
83 /* information element was interrogated. This field is */
84 /* automatically cleared when it is interrogated.*/
85 u32 PLCP_error;
86
87 /* The number of FCS errors since the last time this */
88 /* information element was interrogated. This field is */
89 /* automatically cleared when it is interrogated.*/
90 u32 FCS_error;
91
92 /* The number of MPDUs without PLCP header errors received*/
93 /* since the last time this information element was interrogated. */
94 /* This field is automatically cleared when it is interrogated.*/
95 u32 valid_frame;
96
97 /* the number of missed sequence numbers in the squentially */
98 /* values of frames seq numbers */
99 u32 seq_num_miss;
100} __attribute__ ((packed));
101
102struct acx_revision {
103 struct acx_header header;
104
105 /*
106 * The WiLink firmware version, an ASCII string x.x.x.x,
107 * that uniquely identifies the current firmware.
108 * The left most digit is incremented each time a
109 * significant change is made to the firmware, such as
110 * code redesign or new platform support.
111 * The second digit is incremented when major enhancements
112 * are added or major fixes are made.
113 * The third digit is incremented for each GA release.
114 * The fourth digit is incremented for each build.
115 * The first two digits identify a firmware release version,
116 * in other words, a unique set of features.
117 * The first three digits identify a GA release.
118 */
119 char fw_version[20];
120
121 /*
122 * This 4 byte field specifies the WiLink hardware version.
123 * bits 0 - 15: Reserved.
124 * bits 16 - 23: Version ID - The WiLink version ID
125 * (1 = first spin, 2 = second spin, and so on).
126 * bits 24 - 31: Chip ID - The WiLink chip ID.
127 */
128 u32 hw_version;
129} __attribute__ ((packed));
130
131enum wl1271_psm_mode {
132 /* Active mode */
133 WL1271_PSM_CAM = 0,
134
135 /* Power save mode */
136 WL1271_PSM_PS = 1,
137
138 /* Extreme low power */
139 WL1271_PSM_ELP = 2,
140};
141
142struct acx_sleep_auth {
143 struct acx_header header;
144
145 /* The sleep level authorization of the device. */
146 /* 0 - Always active*/
147 /* 1 - Power down mode: light / fast sleep*/
148 /* 2 - ELP mode: Deep / Max sleep*/
149 u8 sleep_auth;
150 u8 padding[3];
151} __attribute__ ((packed));
152
153enum {
154 HOSTIF_PCI_MASTER_HOST_INDIRECT,
155 HOSTIF_PCI_MASTER_HOST_DIRECT,
156 HOSTIF_SLAVE,
157 HOSTIF_PKT_RING,
158 HOSTIF_DONTCARE = 0xFF
159};
160
161#define DEFAULT_UCAST_PRIORITY 0
162#define DEFAULT_RX_Q_PRIORITY 0
163#define DEFAULT_NUM_STATIONS 1
164#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
165#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
166#define TRACE_BUFFER_MAX_SIZE 256
167
168#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
169#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
170#define DP_RX_PACKET_RING_CHUNK_NUM 2
171#define DP_TX_PACKET_RING_CHUNK_NUM 2
172#define DP_TX_COMPLETE_TIME_OUT 20
173#define FW_TX_CMPLT_BLOCK_SIZE 16
174
175#define TX_MSDU_LIFETIME_MIN 0
176#define TX_MSDU_LIFETIME_MAX 3000
177#define TX_MSDU_LIFETIME_DEF 512
178#define RX_MSDU_LIFETIME_MIN 0
179#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
180#define RX_MSDU_LIFETIME_DEF 512000
181
182struct acx_rx_msdu_lifetime {
183 struct acx_header header;
184
185 /*
186 * The maximum amount of time, in TU, before the
187 * firmware discards the MSDU.
188 */
189 u32 lifetime;
190} __attribute__ ((packed));
191
192/*
193 * RX Config Options Table
194 * Bit Definition
195 * === ==========
196 * 31:14 Reserved
197 * 13 Copy RX Status - when set, write three receive status words
198 * to top of rx'd MPDUs.
199 * When cleared, do not write three status words (added rev 1.5)
200 * 12 Reserved
201 * 11 RX Complete upon FCS error - when set, give rx complete
202 * interrupt for FCS errors, after the rx filtering, e.g. unicast
203 * frames not to us with FCS error will not generate an interrupt.
204 * 10 SSID Filter Enable - When set, the WiLink discards all beacon,
205 * probe request, and probe response frames with an SSID that does
206 * not match the SSID specified by the host in the START/JOIN
207 * command.
208 * When clear, the WiLink receives frames with any SSID.
209 * 9 Broadcast Filter Enable - When set, the WiLink discards all
210 * broadcast frames. When clear, the WiLink receives all received
211 * broadcast frames.
212 * 8:6 Reserved
213 * 5 BSSID Filter Enable - When set, the WiLink discards any frames
214 * with a BSSID that does not match the BSSID specified by the
215 * host.
216 * When clear, the WiLink receives frames from any BSSID.
217 * 4 MAC Addr Filter - When set, the WiLink discards any frames
218 * with a destination address that does not match the MAC address
219 * of the adaptor.
220 * When clear, the WiLink receives frames destined to any MAC
221 * address.
222 * 3 Promiscuous - When set, the WiLink receives all valid frames
223 * (i.e., all frames that pass the FCS check).
224 * When clear, only frames that pass the other filters specified
225 * are received.
226 * 2 FCS - When set, the WiLink includes the FCS with the received
227 * frame.
228 * When cleared, the FCS is discarded.
229 * 1 PLCP header - When set, write all data from baseband to frame
230 * buffer including PHY header.
231 * 0 Reserved - Always equal to 0.
232 *
233 * RX Filter Options Table
234 * Bit Definition
235 * === ==========
236 * 31:12 Reserved - Always equal to 0.
237 * 11 Association - When set, the WiLink receives all association
238 * related frames (association request/response, reassocation
239 * request/response, and disassociation). When clear, these frames
240 * are discarded.
241 * 10 Auth/De auth - When set, the WiLink receives all authentication
242 * and de-authentication frames. When clear, these frames are
243 * discarded.
244 * 9 Beacon - When set, the WiLink receives all beacon frames.
245 * When clear, these frames are discarded.
246 * 8 Contention Free - When set, the WiLink receives all contention
247 * free frames.
248 * When clear, these frames are discarded.
249 * 7 Control - When set, the WiLink receives all control frames.
250 * When clear, these frames are discarded.
251 * 6 Data - When set, the WiLink receives all data frames.
252 * When clear, these frames are discarded.
253 * 5 FCS Error - When set, the WiLink receives frames that have FCS
254 * errors.
255 * When clear, these frames are discarded.
256 * 4 Management - When set, the WiLink receives all management
257 * frames.
258 * When clear, these frames are discarded.
259 * 3 Probe Request - When set, the WiLink receives all probe request
260 * frames.
261 * When clear, these frames are discarded.
262 * 2 Probe Response - When set, the WiLink receives all probe
263 * response frames.
264 * When clear, these frames are discarded.
265 * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
266 * frames.
267 * When clear, these frames are discarded.
268 * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
269 * that have reserved frame types and sub types as defined by the
270 * 802.11 specification.
271 * When clear, these frames are discarded.
272 */
273struct acx_rx_config {
274 struct acx_header header;
275
276 u32 config_options;
277 u32 filter_options;
278} __attribute__ ((packed));
279
280struct acx_packet_detection {
281 struct acx_header header;
282
283 u32 threshold;
284} __attribute__ ((packed));
285
286
287enum acx_slot_type {
288 SLOT_TIME_LONG = 0,
289 SLOT_TIME_SHORT = 1,
290 DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
291 MAX_SLOT_TIMES = 0xFF
292};
293
294#define STATION_WONE_INDEX 0
295
296struct acx_slot {
297 struct acx_header header;
298
299 u8 wone_index; /* Reserved */
300 u8 slot_time;
301 u8 reserved[6];
302} __attribute__ ((packed));
303
304
305#define ADDRESS_GROUP_MAX (8)
306#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
307
308struct acx_dot11_grp_addr_tbl {
309 struct acx_header header;
310
311 u8 enabled;
312 u8 num_groups;
313 u8 pad[2];
314 u8 mac_table[ADDRESS_GROUP_MAX_LEN];
315} __attribute__ ((packed));
316
317
318#define RX_TIMEOUT_PS_POLL_MIN 0
319#define RX_TIMEOUT_PS_POLL_MAX (200000)
320#define RX_TIMEOUT_PS_POLL_DEF (15)
321#define RX_TIMEOUT_UPSD_MIN 0
322#define RX_TIMEOUT_UPSD_MAX (200000)
323#define RX_TIMEOUT_UPSD_DEF (15)
324
325struct acx_rx_timeout {
326 struct acx_header header;
327
328 /*
329 * The longest time the STA will wait to receive
330 * traffic from the AP after a PS-poll has been
331 * transmitted.
332 */
333 u16 ps_poll_timeout;
334
335 /*
336 * The longest time the STA will wait to receive
337 * traffic from the AP after a frame has been sent
338 * from an UPSD enabled queue.
339 */
340 u16 upsd_timeout;
341} __attribute__ ((packed));
342
343#define RTS_THRESHOLD_MIN 0
344#define RTS_THRESHOLD_MAX 4096
345#define RTS_THRESHOLD_DEF 2347
346
347struct acx_rts_threshold {
348 struct acx_header header;
349
350 u16 threshold;
351 u8 pad[2];
352} __attribute__ ((packed));
353
354struct acx_beacon_filter_option {
355 struct acx_header header;
356
357 u8 enable;
358
359 /*
360 * The number of beacons without the unicast TIM
361 * bit set that the firmware buffers before
362 * signaling the host about ready frames.
363 * When set to 0 and the filter is enabled, beacons
364 * without the unicast TIM bit set are dropped.
365 */
366 u8 max_num_beacons;
367 u8 pad[2];
368} __attribute__ ((packed));
369
370/*
371 * ACXBeaconFilterEntry (not 221)
372 * Byte Offset Size (Bytes) Definition
373 * =========== ============ ==========
374 * 0 1 IE identifier
375 * 1 1 Treatment bit mask
376 *
377 * ACXBeaconFilterEntry (221)
378 * Byte Offset Size (Bytes) Definition
379 * =========== ============ ==========
380 * 0 1 IE identifier
381 * 1 1 Treatment bit mask
382 * 2 3 OUI
383 * 5 1 Type
384 * 6 2 Version
385 *
386 *
387 * Treatment bit mask - The information element handling:
388 * bit 0 - The information element is compared and transferred
389 * in case of change.
390 * bit 1 - The information element is transferred to the host
391 * with each appearance or disappearance.
392 * Note that both bits can be set at the same time.
393 */
394#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
395#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
396#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
397#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
398#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
399 BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
400 (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
401 BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
402
403struct acx_beacon_filter_ie_table {
404 struct acx_header header;
405
406 u8 num_ie;
407 u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
408 u8 pad[3];
409} __attribute__ ((packed));
410
411enum {
412 SG_ENABLE = 0,
413 SG_DISABLE,
414 SG_SENSE_NO_ACTIVITY,
415 SG_SENSE_ACTIVE
416};
417
418struct acx_bt_wlan_coex {
419 struct acx_header header;
420
421 /*
422 * 0 -> PTA enabled
423 * 1 -> PTA disabled
424 * 2 -> sense no active mode, i.e.
425 * an interrupt is sent upon
426 * BT activity.
427 * 3 -> PTA is switched on in response
428 * to the interrupt sending.
429 */
430 u8 enable;
431 u8 pad[3];
432} __attribute__ ((packed));
433
434#define PTA_ANTENNA_TYPE_DEF (0)
435#define PTA_BT_HP_MAXTIME_DEF (2000)
436#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
437#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
438#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
439#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
440#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
441#define PTA_SIGNALING_TYPE_DEF (1)
442#define PTA_AFH_LEVERAGE_ON_DEF (0)
443#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
444#define PTA_MAX_NUM_CTS_DEF (3)
445#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
446#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
447#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
448#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
449#define PTA_CYCLE_TIME_FAST_DEF (8700)
450#define PTA_RX_FOR_AVALANCHE_DEF (5)
451#define PTA_ELP_HP_DEF (0)
452#define PTA_ANTI_STARVE_PERIOD_DEF (500)
453#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
454#define PTA_ALLOW_PA_SD_DEF (1)
455#define PTA_TIME_BEFORE_BEACON_DEF (6300)
456#define PTA_HPDM_MAX_TIME_DEF (1600)
457#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
458#define PTA_AUTO_MODE_NO_CTS_DEF (0)
459#define PTA_BT_HP_RESPECTED_DEF (3)
460#define PTA_WLAN_RX_MIN_RATE_DEF (24)
461#define PTA_ACK_MODE_DEF (1)
462
463struct acx_bt_wlan_coex_param {
464 struct acx_header header;
465
466 /*
467 * The minimum rate of a received WLAN packet in the STA,
468 * during protective mode, of which a new BT-HP request
469 * during this Rx will always be respected and gain the antenna.
470 */
471 u32 min_rate;
472
473 /* Max time the BT HP will be respected. */
474 u16 bt_hp_max_time;
475
476 /* Max time the WLAN HP will be respected. */
477 u16 wlan_hp_max_time;
478
479 /*
480 * The time between the last BT activity
481 * and the moment when the sense mode returns
482 * to SENSE_INACTIVE.
483 */
484 u16 sense_disable_timer;
485
486 /* Time before the next BT HP instance */
487 u16 rx_time_bt_hp;
488 u16 tx_time_bt_hp;
489
490 /* range: 10-20000 default: 1500 */
491 u16 rx_time_bt_hp_fast;
492 u16 tx_time_bt_hp_fast;
493
494 /* range: 2000-65535 default: 8700 */
495 u16 wlan_cycle_fast;
496
497 /* range: 0 - 15000 (Msec) default: 1000 */
498 u16 bt_anti_starvation_period;
499
500 /* range 400-10000(Usec) default: 3000 */
501 u16 next_bt_lp_packet;
502
503 /* Deafult: worst case for BT DH5 traffic */
504 u16 wake_up_beacon;
505
506 /* range: 0-50000(Usec) default: 1050 */
507 u16 hp_dm_max_guard_time;
508
509 /*
510 * This is to prevent both BT & WLAN antenna
511 * starvation.
512 * Range: 100-50000(Usec) default:2550
513 */
514 u16 next_wlan_packet;
515
516 /* 0 -> shared antenna */
517 u8 antenna_type;
518
519 /*
520 * 0 -> TI legacy
521 * 1 -> Palau
522 */
523 u8 signal_type;
524
525 /*
526 * BT AFH status
527 * 0 -> no AFH
528 * 1 -> from dedicated GPIO
529 * 2 -> AFH on (from host)
530 */
531 u8 afh_leverage_on;
532
533 /*
534 * The number of cycles during which no
535 * TX will be sent after 1 cycle of RX
536 * transaction in protective mode
537 */
538 u8 quiet_cycle_num;
539
540 /*
541 * The maximum number of CTSs that will
542 * be sent for receiving RX packet in
543 * protective mode
544 */
545 u8 max_cts;
546
547 /*
548 * The number of WLAN packets
549 * transferred in common mode before
550 * switching to BT.
551 */
552 u8 wlan_packets_num;
553
554 /*
555 * The number of BT packets
556 * transferred in common mode before
557 * switching to WLAN.
558 */
559 u8 bt_packets_num;
560
561 /* range: 1-255 default: 5 */
562 u8 missed_rx_avalanche;
563
564 /* range: 0-1 default: 1 */
565 u8 wlan_elp_hp;
566
567 /* range: 0 - 15 default: 4 */
568 u8 bt_anti_starvation_cycles;
569
570 u8 ack_mode_dual_ant;
571
572 /*
573 * Allow PA_SD assertion/de-assertion
574 * during enabled BT activity.
575 */
576 u8 pa_sd_enable;
577
578 /*
579 * Enable/Disable PTA in auto mode:
580 * Support Both Active & P.S modes
581 */
582 u8 pta_auto_mode_enable;
583
584 /* range: 0 - 20 default: 1 */
585 u8 bt_hp_respected_num;
586} __attribute__ ((packed));
587
588#define CCA_THRSH_ENABLE_ENERGY_D 0x140A
589#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF
590
591struct acx_energy_detection {
592 struct acx_header header;
593
594 /* The RX Clear Channel Assessment threshold in the PHY */
595 u16 rx_cca_threshold;
596 u8 tx_energy_detection;
597 u8 pad;
598} __attribute__ ((packed));
599
600#define BCN_RX_TIMEOUT_DEF_VALUE 10000
601#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000
602#define RX_BROADCAST_IN_PS_DEF_VALUE 1
603#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
604
605struct acx_beacon_broadcast {
606 struct acx_header header;
607
608 u16 beacon_rx_timeout;
609 u16 broadcast_timeout;
610
611 /* Enables receiving of broadcast packets in PS mode */
612 u8 rx_broadcast_in_ps;
613
614 /* Consecutive PS Poll failures before updating the host */
615 u8 ps_poll_threshold;
616 u8 pad[2];
617} __attribute__ ((packed));
618
619struct acx_event_mask {
620 struct acx_header header;
621
622 u32 event_mask;
623 u32 high_event_mask; /* Unused */
624} __attribute__ ((packed));
625
626#define CFG_RX_FCS BIT(2)
627#define CFG_RX_ALL_GOOD BIT(3)
628#define CFG_UNI_FILTER_EN BIT(4)
629#define CFG_BSSID_FILTER_EN BIT(5)
630#define CFG_MC_FILTER_EN BIT(6)
631#define CFG_MC_ADDR0_EN BIT(7)
632#define CFG_MC_ADDR1_EN BIT(8)
633#define CFG_BC_REJECT_EN BIT(9)
634#define CFG_SSID_FILTER_EN BIT(10)
635#define CFG_RX_INT_FCS_ERROR BIT(11)
636#define CFG_RX_INT_ENCRYPTED BIT(12)
637#define CFG_RX_WR_RX_STATUS BIT(13)
638#define CFG_RX_FILTER_NULTI BIT(14)
639#define CFG_RX_RESERVE BIT(15)
640#define CFG_RX_TIMESTAMP_TSF BIT(16)
641
642#define CFG_RX_RSV_EN BIT(0)
643#define CFG_RX_RCTS_ACK BIT(1)
644#define CFG_RX_PRSP_EN BIT(2)
645#define CFG_RX_PREQ_EN BIT(3)
646#define CFG_RX_MGMT_EN BIT(4)
647#define CFG_RX_FCS_ERROR BIT(5)
648#define CFG_RX_DATA_EN BIT(6)
649#define CFG_RX_CTL_EN BIT(7)
650#define CFG_RX_CF_EN BIT(8)
651#define CFG_RX_BCN_EN BIT(9)
652#define CFG_RX_AUTH_EN BIT(10)
653#define CFG_RX_ASSOC_EN BIT(11)
654
655#define SCAN_PASSIVE BIT(0)
656#define SCAN_5GHZ_BAND BIT(1)
657#define SCAN_TRIGGERED BIT(2)
658#define SCAN_PRIORITY_HIGH BIT(3)
659
660struct acx_feature_config {
661 struct acx_header header;
662
663 u32 options;
664 u32 data_flow_options;
665} __attribute__ ((packed));
666
667struct acx_current_tx_power {
668 struct acx_header header;
669
670 u8 current_tx_power;
671 u8 padding[3];
672} __attribute__ ((packed));
673
674enum acx_wake_up_event {
675 WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
676 WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
677 WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */
678 WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */
679 WAKE_UP_EVENT_BITS_MASK = 0x0F
680};
681
682struct acx_wake_up_condition {
683 struct acx_header header;
684
685 u8 wake_up_event; /* Only one bit can be set */
686 u8 listen_interval;
687 u8 pad[2];
688} __attribute__ ((packed));
689
690struct acx_aid {
691 struct acx_header header;
692
693 /*
694 * To be set when associated with an AP.
695 */
696 u16 aid;
697 u8 pad[2];
698} __attribute__ ((packed));
699
700enum acx_preamble_type {
701 ACX_PREAMBLE_LONG = 0,
702 ACX_PREAMBLE_SHORT = 1
703};
704
705struct acx_preamble {
706 struct acx_header header;
707
708 /*
709 * When set, the WiLink transmits the frames with a short preamble and
710 * when cleared, the WiLink transmits the frames with a long preamble.
711 */
712 u8 preamble;
713 u8 padding[3];
714} __attribute__ ((packed));
715
716enum acx_ctsprotect_type {
717 CTSPROTECT_DISABLE = 0,
718 CTSPROTECT_ENABLE = 1
719};
720
721struct acx_ctsprotect {
722 struct acx_header header;
723 u8 ctsprotect;
724 u8 padding[3];
725} __attribute__ ((packed));
726
727struct acx_tx_statistics {
728 u32 internal_desc_overflow;
729} __attribute__ ((packed));
730
731struct acx_rx_statistics {
732 u32 out_of_mem;
733 u32 hdr_overflow;
734 u32 hw_stuck;
735 u32 dropped;
736 u32 fcs_err;
737 u32 xfr_hint_trig;
738 u32 path_reset;
739 u32 reset_counter;
740} __attribute__ ((packed));
741
742struct acx_dma_statistics {
743 u32 rx_requested;
744 u32 rx_errors;
745 u32 tx_requested;
746 u32 tx_errors;
747} __attribute__ ((packed));
748
749struct acx_isr_statistics {
750 /* host command complete */
751 u32 cmd_cmplt;
752
753 /* fiqisr() */
754 u32 fiqs;
755
756 /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
757 u32 rx_headers;
758
759 /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
760 u32 rx_completes;
761
762 /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
763 u32 rx_mem_overflow;
764
765 /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
766 u32 rx_rdys;
767
768 /* irqisr() */
769 u32 irqs;
770
771 /* (INT_STS_ND & INT_TRIG_TX_PROC) */
772 u32 tx_procs;
773
774 /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
775 u32 decrypt_done;
776
777 /* (INT_STS_ND & INT_TRIG_DMA0) */
778 u32 dma0_done;
779
780 /* (INT_STS_ND & INT_TRIG_DMA1) */
781 u32 dma1_done;
782
783 /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
784 u32 tx_exch_complete;
785
786 /* (INT_STS_ND & INT_TRIG_COMMAND) */
787 u32 commands;
788
789 /* (INT_STS_ND & INT_TRIG_RX_PROC) */
790 u32 rx_procs;
791
792 /* (INT_STS_ND & INT_TRIG_PM_802) */
793 u32 hw_pm_mode_changes;
794
795 /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
796 u32 host_acknowledges;
797
798 /* (INT_STS_ND & INT_TRIG_PM_PCI) */
799 u32 pci_pm;
800
801 /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
802 u32 wakeups;
803
804 /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
805 u32 low_rssi;
806} __attribute__ ((packed));
807
808struct acx_wep_statistics {
809 /* WEP address keys configured */
810 u32 addr_key_count;
811
812 /* default keys configured */
813 u32 default_key_count;
814
815 u32 reserved;
816
817 /* number of times that WEP key not found on lookup */
818 u32 key_not_found;
819
820 /* number of times that WEP key decryption failed */
821 u32 decrypt_fail;
822
823 /* WEP packets decrypted */
824 u32 packets;
825
826 /* WEP decrypt interrupts */
827 u32 interrupt;
828} __attribute__ ((packed));
829
830#define ACX_MISSED_BEACONS_SPREAD 10
831
832struct acx_pwr_statistics {
833 /* the amount of enters into power save mode (both PD & ELP) */
834 u32 ps_enter;
835
836 /* the amount of enters into ELP mode */
837 u32 elp_enter;
838
839 /* the amount of missing beacon interrupts to the host */
840 u32 missing_bcns;
841
842 /* the amount of wake on host-access times */
843 u32 wake_on_host;
844
845 /* the amount of wake on timer-expire */
846 u32 wake_on_timer_exp;
847
848 /* the number of packets that were transmitted with PS bit set */
849 u32 tx_with_ps;
850
851 /* the number of packets that were transmitted with PS bit clear */
852 u32 tx_without_ps;
853
854 /* the number of received beacons */
855 u32 rcvd_beacons;
856
857 /* the number of entering into PowerOn (power save off) */
858 u32 power_save_off;
859
860 /* the number of entries into power save mode */
861 u16 enable_ps;
862
863 /*
864 * the number of exits from power save, not including failed PS
865 * transitions
866 */
867 u16 disable_ps;
868
869 /*
870 * the number of times the TSF counter was adjusted because
871 * of drift
872 */
873 u32 fix_tsf_ps;
874
875 /* Gives statistics about the spread continuous missed beacons.
876 * The 16 LSB are dedicated for the PS mode.
877 * The 16 MSB are dedicated for the PS mode.
878 * cont_miss_bcns_spread[0] - single missed beacon.
879 * cont_miss_bcns_spread[1] - two continuous missed beacons.
880 * cont_miss_bcns_spread[2] - three continuous missed beacons.
881 * ...
882 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
883 */
884 u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
885
886 /* the number of beacons in awake mode */
887 u32 rcvd_awake_beacons;
888} __attribute__ ((packed));
889
890struct acx_mic_statistics {
891 u32 rx_pkts;
892 u32 calc_failure;
893} __attribute__ ((packed));
894
895struct acx_aes_statistics {
896 u32 encrypt_fail;
897 u32 decrypt_fail;
898 u32 encrypt_packets;
899 u32 decrypt_packets;
900 u32 encrypt_interrupt;
901 u32 decrypt_interrupt;
902} __attribute__ ((packed));
903
904struct acx_event_statistics {
905 u32 heart_beat;
906 u32 calibration;
907 u32 rx_mismatch;
908 u32 rx_mem_empty;
909 u32 rx_pool;
910 u32 oom_late;
911 u32 phy_transmit_error;
912 u32 tx_stuck;
913} __attribute__ ((packed));
914
915struct acx_ps_statistics {
916 u32 pspoll_timeouts;
917 u32 upsd_timeouts;
918 u32 upsd_max_sptime;
919 u32 upsd_max_apturn;
920 u32 pspoll_max_apturn;
921 u32 pspoll_utilization;
922 u32 upsd_utilization;
923} __attribute__ ((packed));
924
925struct acx_rxpipe_statistics {
926 u32 rx_prep_beacon_drop;
927 u32 descr_host_int_trig_rx_data;
928 u32 beacon_buffer_thres_host_int_trig_rx_data;
929 u32 missed_beacon_host_int_trig_rx_data;
930 u32 tx_xfr_host_int_trig_rx_data;
931} __attribute__ ((packed));
932
933struct acx_statistics {
934 struct acx_header header;
935
936 struct acx_tx_statistics tx;
937 struct acx_rx_statistics rx;
938 struct acx_dma_statistics dma;
939 struct acx_isr_statistics isr;
940 struct acx_wep_statistics wep;
941 struct acx_pwr_statistics pwr;
942 struct acx_aes_statistics aes;
943 struct acx_mic_statistics mic;
944 struct acx_event_statistics event;
945 struct acx_ps_statistics ps;
946 struct acx_rxpipe_statistics rxpipe;
947} __attribute__ ((packed));
948
949#define ACX_MAX_RATE_CLASSES 8
950#define ACX_RATE_MASK_UNSPECIFIED 0
951#define ACX_RATE_MASK_ALL 0x1eff
952#define ACX_RATE_RETRY_LIMIT 10
953
954struct acx_rate_class {
955 u32 enabled_rates;
956 u8 short_retry_limit;
957 u8 long_retry_limit;
958 u8 aflags;
959 u8 reserved;
960};
961
962struct acx_rate_policy {
963 struct acx_header header;
964
965 u32 rate_class_cnt;
966 struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
967} __attribute__ ((packed));
968
969#define WL1271_ACX_AC_COUNT 4
970
971struct acx_ac_cfg {
972 struct acx_header header;
973 u8 ac;
974 u8 cw_min;
975 u16 cw_max;
976 u8 aifsn;
977 u8 reserved;
978 u16 tx_op_limit;
979} __attribute__ ((packed));
980
981enum wl1271_acx_ac {
982 WL1271_ACX_AC_BE = 0,
983 WL1271_ACX_AC_BK = 1,
984 WL1271_ACX_AC_VI = 2,
985 WL1271_ACX_AC_VO = 3,
986 WL1271_ACX_AC_CTS2SELF = 4,
987 WL1271_ACX_AC_ANY_TID = 0x1F,
988 WL1271_ACX_AC_INVALID = 0xFF,
989};
990
991enum wl1271_acx_ps_scheme {
992 WL1271_ACX_PS_SCHEME_LEGACY = 0,
993 WL1271_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
994 WL1271_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
995 WL1271_ACX_PS_SCHEME_SAPSD = 3,
996};
997
998enum wl1271_acx_ack_policy {
999 WL1271_ACX_ACK_POLICY_LEGACY = 0,
1000 WL1271_ACX_ACK_POLICY_NO_ACK = 1,
1001 WL1271_ACX_ACK_POLICY_BLOCK = 2,
1002};
1003
1004#define WL1271_ACX_TID_COUNT 7
1005
1006struct acx_tid_config {
1007 struct acx_header header;
1008 u8 queue_id;
1009 u8 channel_type;
1010 u8 tsid;
1011 u8 ps_scheme;
1012 u8 ack_policy;
1013 u8 padding[3];
1014 u32 apsd_conf[2];
1015} __attribute__ ((packed));
1016
1017struct acx_frag_threshold {
1018 struct acx_header header;
1019 u16 frag_threshold;
1020 u8 padding[2];
1021} __attribute__ ((packed));
1022
1023#define WL1271_ACX_TX_COMPL_TIMEOUT 5
1024#define WL1271_ACX_TX_COMPL_THRESHOLD 5
1025
1026struct acx_tx_config_options {
1027 struct acx_header header;
1028 u16 tx_compl_timeout; /* msec */
1029 u16 tx_compl_threshold; /* number of packets */
1030} __attribute__ ((packed));
1031
1032#define ACX_RX_MEM_BLOCKS 64
1033#define ACX_TX_MIN_MEM_BLOCKS 64
1034#define ACX_TX_DESCRIPTORS 32
1035#define ACX_NUM_SSID_PROFILES 1
1036
1037struct wl1271_acx_config_memory {
1038 struct acx_header header;
1039
1040 u8 rx_mem_block_num;
1041 u8 tx_min_mem_block_num;
1042 u8 num_stations;
1043 u8 num_ssid_profiles;
1044 u32 total_tx_descriptors;
1045} __attribute__ ((packed));
1046
1047struct wl1271_acx_mem_map {
1048 struct acx_header header;
1049
1050 void *code_start;
1051 void *code_end;
1052
1053 void *wep_defkey_start;
1054 void *wep_defkey_end;
1055
1056 void *sta_table_start;
1057 void *sta_table_end;
1058
1059 void *packet_template_start;
1060 void *packet_template_end;
1061
1062 /* Address of the TX result interface (control block) */
1063 u32 tx_result;
1064 u32 tx_result_queue_start;
1065
1066 void *queue_memory_start;
1067 void *queue_memory_end;
1068
1069 u32 packet_memory_pool_start;
1070 u32 packet_memory_pool_end;
1071
1072 void *debug_buffer1_start;
1073 void *debug_buffer1_end;
1074
1075 void *debug_buffer2_start;
1076 void *debug_buffer2_end;
1077
1078 /* Number of blocks FW allocated for TX packets */
1079 u32 num_tx_mem_blocks;
1080
1081 /* Number of blocks FW allocated for RX packets */
1082 u32 num_rx_mem_blocks;
1083
1084 /* the following 4 fields are valid in SLAVE mode only */
1085 u8 *tx_cbuf;
1086 u8 *rx_cbuf;
1087 void *rx_ctrl;
1088 void *tx_ctrl;
1089} __attribute__ ((packed));
1090
1091enum wl1271_acx_rx_queue_type {
1092 RX_QUEUE_TYPE_RX_LOW_PRIORITY, /* All except the high priority */
1093 RX_QUEUE_TYPE_RX_HIGH_PRIORITY, /* Management and voice packets */
1094 RX_QUEUE_TYPE_NUM,
1095 RX_QUEUE_TYPE_MAX = USHORT_MAX
1096};
1097
1098#define WL1271_RX_INTR_THRESHOLD_DEF 0 /* no pacing, send interrupt on
1099 * every event */
1100#define WL1271_RX_INTR_THRESHOLD_MIN 0
1101#define WL1271_RX_INTR_THRESHOLD_MAX 15
1102
1103#define WL1271_RX_INTR_TIMEOUT_DEF 5
1104#define WL1271_RX_INTR_TIMEOUT_MIN 1
1105#define WL1271_RX_INTR_TIMEOUT_MAX 100
1106
1107struct wl1271_acx_rx_config_opt {
1108 struct acx_header header;
1109
1110 u16 mblk_threshold;
1111 u16 threshold;
1112 u16 timeout;
1113 u8 queue_type;
1114 u8 reserved;
1115} __attribute__ ((packed));
1116
1117enum {
1118 ACX_WAKE_UP_CONDITIONS = 0x0002,
1119 ACX_MEM_CFG = 0x0003,
1120 ACX_SLOT = 0x0004,
1121 ACX_AC_CFG = 0x0007,
1122 ACX_MEM_MAP = 0x0008,
1123 ACX_AID = 0x000A,
1124 /* ACX_FW_REV is missing in the ref driver, but seems to work */
1125 ACX_FW_REV = 0x000D,
1126 ACX_MEDIUM_USAGE = 0x000F,
1127 ACX_RX_CFG = 0x0010,
1128 ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
1129 ACX_STATISTICS = 0x0013, /* Debug API */
1130 ACX_PWR_CONSUMPTION_STATISTICS = 0x0014,
1131 ACX_FEATURE_CFG = 0x0015,
1132 ACX_TID_CFG = 0x001A,
1133 ACX_PS_RX_STREAMING = 0x001B,
1134 ACX_BEACON_FILTER_OPT = 0x001F,
1135 ACX_NOISE_HIST = 0x0021,
1136 ACX_HDK_VERSION = 0x0022, /* ??? */
1137 ACX_PD_THRESHOLD = 0x0023,
1138 ACX_TX_CONFIG_OPT = 0x0024,
1139 ACX_CCA_THRESHOLD = 0x0025,
1140 ACX_EVENT_MBOX_MASK = 0x0026,
1141 ACX_CONN_MONIT_PARAMS = 0x002D,
1142 ACX_CONS_TX_FAILURE = 0x002F,
1143 ACX_BCN_DTIM_OPTIONS = 0x0031,
1144 ACX_SG_ENABLE = 0x0032,
1145 ACX_SG_CFG = 0x0033,
1146 ACX_BEACON_FILTER_TABLE = 0x0038,
1147 ACX_ARP_IP_FILTER = 0x0039,
1148 ACX_ROAMING_STATISTICS_TBL = 0x003B,
1149 ACX_RATE_POLICY = 0x003D,
1150 ACX_CTS_PROTECTION = 0x003E,
1151 ACX_SLEEP_AUTH = 0x003F,
1152 ACX_PREAMBLE_TYPE = 0x0040,
1153 ACX_ERROR_CNT = 0x0041,
1154 ACX_IBSS_FILTER = 0x0044,
1155 ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
1156 ACX_TSF_INFO = 0x0046,
1157 ACX_CONFIG_PS_WMM = 0x0049,
1158 ACX_ENABLE_RX_DATA_FILTER = 0x004A,
1159 ACX_SET_RX_DATA_FILTER = 0x004B,
1160 ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
1161 ACX_RX_CONFIG_OPT = 0x004E,
1162 ACX_FRAG_CFG = 0x004F,
1163 ACX_BET_ENABLE = 0x0050,
1164 ACX_RSSI_SNR_TRIGGER = 0x0051,
1165 ACX_RSSI_SNR_WEIGHTS = 0x0051,
1166 ACX_KEEP_ALIVE_MODE = 0x0052,
1167 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
1168 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
1169 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
1170 ACX_PEER_HT_CAP = 0x0057,
1171 ACX_HT_BSS_OPERATION = 0x0058,
1172 ACX_COEX_ACTIVITY = 0x0059,
1173 DOT11_RX_MSDU_LIFE_TIME = 0x1004,
1174 DOT11_CUR_TX_PWR = 0x100D,
1175 DOT11_RX_DOT11_MODE = 0x1012,
1176 DOT11_RTS_THRESHOLD = 0x1013,
1177 DOT11_GROUP_ADDRESS_TBL = 0x1014,
1178
1179 MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
1180
1181 MAX_IE = 0xFFFF
1182};
1183
1184
1185int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
1186 u8 listen_interval);
1187int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
1188int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
1189int wl1271_acx_tx_power(struct wl1271 *wl, int power);
1190int wl1271_acx_feature_cfg(struct wl1271 *wl);
1191int wl1271_acx_mem_map(struct wl1271 *wl,
1192 struct acx_header *mem_map, size_t len);
1193int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time);
1194int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter);
1195int wl1271_acx_pd_threshold(struct wl1271 *wl);
1196int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
1197int wl1271_acx_group_address_tbl(struct wl1271 *wl);
1198int wl1271_acx_service_period_timeout(struct wl1271 *wl);
1199int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
1200int wl1271_acx_beacon_filter_opt(struct wl1271 *wl);
1201int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1202int wl1271_acx_sg_enable(struct wl1271 *wl);
1203int wl1271_acx_sg_cfg(struct wl1271 *wl);
1204int wl1271_acx_cca_threshold(struct wl1271 *wl);
1205int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
1206int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
1207int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
1208int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
1209int wl1271_acx_cts_protect(struct wl1271 *wl,
1210 enum acx_ctsprotect_type ctsprotect);
1211int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
1212int wl1271_acx_rate_policies(struct wl1271 *wl);
1213int wl1271_acx_ac_cfg(struct wl1271 *wl);
1214int wl1271_acx_tid_cfg(struct wl1271 *wl);
1215int wl1271_acx_frag_threshold(struct wl1271 *wl);
1216int wl1271_acx_tx_config_options(struct wl1271 *wl);
1217int wl1271_acx_mem_cfg(struct wl1271 *wl);
1218int wl1271_acx_init_mem_config(struct wl1271 *wl);
1219int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1220
1221#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
new file mode 100644
index 000000000000..4c22f25fd8f0
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -0,0 +1,540 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_acx.h"
27#include "wl1271_reg.h"
28#include "wl1271_boot.h"
29#include "wl1271_spi.h"
30#include "wl1271_event.h"
31
32static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
33 [PART_DOWN] = {
34 .mem = {
35 .start = 0x00000000,
36 .size = 0x000177c0
37 },
38 .reg = {
39 .start = REGISTERS_BASE,
40 .size = 0x00008800
41 },
42 },
43
44 [PART_WORK] = {
45 .mem = {
46 .start = 0x00040000,
47 .size = 0x00014fc0
48 },
49 .reg = {
50 .start = REGISTERS_BASE,
51 .size = 0x0000b000
52 },
53 },
54
55 [PART_DRPW] = {
56 .mem = {
57 .start = 0x00040000,
58 .size = 0x00014fc0
59 },
60 .reg = {
61 .start = DRPW_BASE,
62 .size = 0x00006000
63 }
64 }
65};
66
67static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
68{
69 u32 cpu_ctrl;
70
71 /* 10.5.0 run the firmware (I) */
72 cpu_ctrl = wl1271_reg_read32(wl, ACX_REG_ECPU_CONTROL);
73
74 /* 10.5.1 run the firmware (II) */
75 cpu_ctrl |= flag;
76 wl1271_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
77}
78
79static void wl1271_boot_fw_version(struct wl1271 *wl)
80{
81 struct wl1271_static_data static_data;
82
83 wl1271_spi_mem_read(wl, wl->cmd_box_addr,
84 &static_data, sizeof(static_data));
85
86 strncpy(wl->chip.fw_ver, static_data.fw_version,
87 sizeof(wl->chip.fw_ver));
88
89 /* make sure the string is NULL-terminated */
90 wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
91}
92
93static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
94 size_t fw_data_len, u32 dest)
95{
96 int addr, chunk_num, partition_limit;
97 u8 *p;
98
99 /* whal_FwCtrl_LoadFwImageSm() */
100
101 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
102
103 wl1271_debug(DEBUG_BOOT, "fw_data_len %d chunk_size %d", fw_data_len,
104 CHUNK_SIZE);
105
106
107 if ((fw_data_len % 4) != 0) {
108 wl1271_error("firmware length not multiple of four");
109 return -EIO;
110 }
111
112 wl1271_set_partition(wl, dest,
113 part_table[PART_DOWN].mem.size,
114 part_table[PART_DOWN].reg.start,
115 part_table[PART_DOWN].reg.size);
116
117 /* 10.1 set partition limit and chunk num */
118 chunk_num = 0;
119 partition_limit = part_table[PART_DOWN].mem.size;
120
121 while (chunk_num < fw_data_len / CHUNK_SIZE) {
122 /* 10.2 update partition, if needed */
123 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
124 if (addr > partition_limit) {
125 addr = dest + chunk_num * CHUNK_SIZE;
126 partition_limit = chunk_num * CHUNK_SIZE +
127 part_table[PART_DOWN].mem.size;
128
129 /* FIXME: Over 80 chars! */
130 wl1271_set_partition(wl,
131 addr,
132 part_table[PART_DOWN].mem.size,
133 part_table[PART_DOWN].reg.start,
134 part_table[PART_DOWN].reg.size);
135 }
136
137 /* 10.3 upload the chunk */
138 addr = dest + chunk_num * CHUNK_SIZE;
139 p = buf + chunk_num * CHUNK_SIZE;
140 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
141 p, addr);
142 wl1271_spi_mem_write(wl, addr, p, CHUNK_SIZE);
143
144 chunk_num++;
145 }
146
147 /* 10.4 upload the last chunk */
148 addr = dest + chunk_num * CHUNK_SIZE;
149 p = buf + chunk_num * CHUNK_SIZE;
150 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%d B) 0x%p to 0x%x",
151 fw_data_len % CHUNK_SIZE, p, addr);
152 wl1271_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
153
154 return 0;
155}
156
157static int wl1271_boot_upload_firmware(struct wl1271 *wl)
158{
159 u32 chunks, addr, len;
160 u8 *fw;
161
162 fw = wl->fw;
163 chunks = be32_to_cpup((u32 *) fw);
164 fw += sizeof(u32);
165
166 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
167
168 while (chunks--) {
169 addr = be32_to_cpup((u32 *) fw);
170 fw += sizeof(u32);
171 len = be32_to_cpup((u32 *) fw);
172 fw += sizeof(u32);
173
174 if (len > 300000) {
175 wl1271_info("firmware chunk too long: %u", len);
176 return -EINVAL;
177 }
178 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
179 chunks, addr, len);
180 wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
181 fw += len;
182 }
183
184 return 0;
185}
186
187static int wl1271_boot_upload_nvs(struct wl1271 *wl)
188{
189 size_t nvs_len, burst_len;
190 int i;
191 u32 dest_addr, val;
192 u8 *nvs_ptr, *nvs, *nvs_aligned;
193
194 nvs = wl->nvs;
195 if (nvs == NULL)
196 return -ENODEV;
197
198 nvs_ptr = nvs;
199
200 nvs_len = wl->nvs_len;
201
202 /* Update the device MAC address into the nvs */
203 nvs[11] = wl->mac_addr[0];
204 nvs[10] = wl->mac_addr[1];
205 nvs[6] = wl->mac_addr[2];
206 nvs[5] = wl->mac_addr[3];
207 nvs[4] = wl->mac_addr[4];
208 nvs[3] = wl->mac_addr[5];
209
210 /*
211 * Layout before the actual NVS tables:
212 * 1 byte : burst length.
213 * 2 bytes: destination address.
214 * n bytes: data to burst copy.
215 *
216 * This is ended by a 0 length, then the NVS tables.
217 */
218
219 /* FIXME: Do we need to check here whether the LSB is 1? */
220 while (nvs_ptr[0]) {
221 burst_len = nvs_ptr[0];
222 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
223
224 /* FIXME: Due to our new wl1271_translate_reg_addr function,
225 we need to add the REGISTER_BASE to the destination */
226 dest_addr += REGISTERS_BASE;
227
228 /* We move our pointer to the data */
229 nvs_ptr += 3;
230
231 for (i = 0; i < burst_len; i++) {
232 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
233 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
234
235 wl1271_debug(DEBUG_BOOT,
236 "nvs burst write 0x%x: 0x%x",
237 dest_addr, val);
238 wl1271_reg_write32(wl, dest_addr, val);
239
240 nvs_ptr += 4;
241 dest_addr += 4;
242 }
243 }
244
245 /*
246 * We've reached the first zero length, the first NVS table
247 * is 7 bytes further.
248 */
249 nvs_ptr += 7;
250 nvs_len -= nvs_ptr - nvs;
251 nvs_len = ALIGN(nvs_len, 4);
252
253 /* FIXME: The driver sets the partition here, but this is not needed,
254 since it sets to the same one as currently in use */
255 /* Now we must set the partition correctly */
256 wl1271_set_partition(wl,
257 part_table[PART_WORK].mem.start,
258 part_table[PART_WORK].mem.size,
259 part_table[PART_WORK].reg.start,
260 part_table[PART_WORK].reg.size);
261
262 /* Copy the NVS tables to a new block to ensure alignment */
263 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
264
265 /* And finally we upload the NVS tables */
266 /* FIXME: In wl1271, we upload everything at once.
267 No endianness handling needed here?! The ref driver doesn't do
268 anything about it at this point */
269 wl1271_spi_mem_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len);
270
271 kfree(nvs_aligned);
272 return 0;
273}
274
275static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
276{
277 enable_irq(wl->irq);
278 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(WL1271_INTR_MASK));
279 wl1271_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
280}
281
282static int wl1271_boot_soft_reset(struct wl1271 *wl)
283{
284 unsigned long timeout;
285 u32 boot_data;
286
287 /* perform soft reset */
288 wl1271_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
289
290 /* SOFT_RESET is self clearing */
291 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
292 while (1) {
293 boot_data = wl1271_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
294 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
295 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
296 break;
297
298 if (time_after(jiffies, timeout)) {
299 /* 1.2 check pWhalBus->uSelfClearTime if the
300 * timeout was reached */
301 wl1271_error("soft reset timeout");
302 return -1;
303 }
304
305 udelay(SOFT_RESET_STALL_TIME);
306 }
307
308 /* disable Rx/Tx */
309 wl1271_reg_write32(wl, ENABLE, 0x0);
310
311 /* disable auto calibration on start*/
312 wl1271_reg_write32(wl, SPARE_A2, 0xffff);
313
314 return 0;
315}
316
317static int wl1271_boot_run_firmware(struct wl1271 *wl)
318{
319 int loop, ret;
320 u32 chip_id, interrupt;
321
322 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
323
324 chip_id = wl1271_reg_read32(wl, CHIP_ID_B);
325
326 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
327
328 if (chip_id != wl->chip.id) {
329 wl1271_error("chip id doesn't match after firmware boot");
330 return -EIO;
331 }
332
333 /* wait for init to complete */
334 loop = 0;
335 while (loop++ < INIT_LOOP) {
336 udelay(INIT_LOOP_DELAY);
337 interrupt = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
338
339 if (interrupt == 0xffffffff) {
340 wl1271_error("error reading hardware complete "
341 "init indication");
342 return -EIO;
343 }
344 /* check that ACX_INTR_INIT_COMPLETE is enabled */
345 else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
346 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
347 WL1271_ACX_INTR_INIT_COMPLETE);
348 break;
349 }
350 }
351
352 if (loop >= INIT_LOOP) {
353 wl1271_error("timeout waiting for the hardware to "
354 "complete initialization");
355 return -EIO;
356 }
357
358 /* get hardware config command mail box */
359 wl->cmd_box_addr = wl1271_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
360
361 /* get hardware config event mail box */
362 wl->event_box_addr = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
363
364 /* set the working partition to its "running" mode offset */
365 wl1271_set_partition(wl,
366 part_table[PART_WORK].mem.start,
367 part_table[PART_WORK].mem.size,
368 part_table[PART_WORK].reg.start,
369 part_table[PART_WORK].reg.size);
370
371 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
372 wl->cmd_box_addr, wl->event_box_addr);
373
374 wl1271_boot_fw_version(wl);
375
376 /*
377 * in case of full asynchronous mode the firmware event must be
378 * ready to receive event from the command mailbox
379 */
380
381 /* enable gpio interrupts */
382 wl1271_boot_enable_interrupts(wl);
383
384 /* unmask all mbox events */
385 wl->event_mask = 0xffffffff;
386
387 ret = wl1271_event_unmask(wl);
388 if (ret < 0) {
389 wl1271_error("EVENT mask setting failed");
390 return ret;
391 }
392
393 wl1271_event_mbox_config(wl);
394
395 /* firmware startup completed */
396 return 0;
397}
398
399static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
400{
401 u32 polarity, status, i;
402
403 wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
404 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
405
406 /* Wait until the command is complete (ie. bit 18 is set) */
407 for (i = 0; i < OCP_CMD_LOOP; i++) {
408 polarity = wl1271_reg_read32(wl, OCP_DATA_READ);
409 if (polarity & OCP_READY_MASK)
410 break;
411 }
412 if (i == OCP_CMD_LOOP) {
413 wl1271_error("OCP command timeout!");
414 return -EIO;
415 }
416
417 status = polarity & OCP_STATUS_MASK;
418 if (status != OCP_STATUS_OK) {
419 wl1271_error("OCP command failed (%d)", status);
420 return -EIO;
421 }
422
423 /* We use HIGH polarity, so unset the LOW bit */
424 polarity &= ~POLARITY_LOW;
425
426 wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
427 wl1271_reg_write32(wl, OCP_DATA_WRITE, polarity);
428 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
429
430 return 0;
431}
432
433int wl1271_boot(struct wl1271 *wl)
434{
435 int ret = 0;
436 u32 tmp, clk, pause;
437
438 if (REF_CLOCK == 0 || REF_CLOCK == 2)
439 /* ref clk: 19.2/38.4 */
440 clk = 0x3;
441 else if (REF_CLOCK == 1 || REF_CLOCK == 3)
442 /* ref clk: 26/52 */
443 clk = 0x5;
444
445 wl1271_reg_write32(wl, PLL_PARAMETERS, clk);
446
447 pause = wl1271_reg_read32(wl, PLL_PARAMETERS);
448
449 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
450
451 pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
452 * WU_COUNTER_PAUSE_VAL instead of
453 * 0x3ff (magic number ). How does
454 * this work?! */
455 pause |= WU_COUNTER_PAUSE_VAL;
456 wl1271_reg_write32(wl, WU_COUNTER_PAUSE, pause);
457
458 /* Continue the ELP wake up sequence */
459 wl1271_reg_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
460 udelay(500);
461
462 wl1271_set_partition(wl,
463 part_table[PART_DRPW].mem.start,
464 part_table[PART_DRPW].mem.size,
465 part_table[PART_DRPW].reg.start,
466 part_table[PART_DRPW].reg.size);
467
468 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
469 to be used by DRPw FW. The RTRIM value will be added by the FW
470 before taking DRPw out of reset */
471
472 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
473 clk = wl1271_reg_read32(wl, DRPW_SCRATCH_START);
474
475 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
476
477 /* 2 */
478 clk |= (REF_CLOCK << 1) << 4;
479 wl1271_reg_write32(wl, DRPW_SCRATCH_START, clk);
480
481 wl1271_set_partition(wl,
482 part_table[PART_WORK].mem.start,
483 part_table[PART_WORK].mem.size,
484 part_table[PART_WORK].reg.start,
485 part_table[PART_WORK].reg.size);
486
487 /* Disable interrupts */
488 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
489
490 ret = wl1271_boot_soft_reset(wl);
491 if (ret < 0)
492 goto out;
493
494 /* 2. start processing NVS file */
495 ret = wl1271_boot_upload_nvs(wl);
496 if (ret < 0)
497 goto out;
498
499 /* write firmware's last address (ie. it's length) to
500 * ACX_EEPROMLESS_IND_REG */
501 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
502
503 wl1271_reg_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
504
505 tmp = wl1271_reg_read32(wl, CHIP_ID_B);
506
507 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
508
509 /* 6. read the EEPROM parameters */
510 tmp = wl1271_reg_read32(wl, SCR_PAD2);
511
512 ret = wl1271_boot_write_irq_polarity(wl);
513 if (ret < 0)
514 goto out;
515
516 /* FIXME: Need to check whether this is really what we want */
517 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
518 WL1271_ACX_ALL_EVENTS_VECTOR);
519
520 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
521 * to upload_fw) */
522
523 ret = wl1271_boot_upload_firmware(wl);
524 if (ret < 0)
525 goto out;
526
527 /* 10.5 start firmware */
528 ret = wl1271_boot_run_firmware(wl);
529 if (ret < 0)
530 goto out;
531
532 /* set the wl1271 default filters */
533 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
534 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
535
536 wl1271_event_mbox_config(wl);
537
538out:
539 return ret;
540}
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
new file mode 100644
index 000000000000..b0d8fb46a439
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -0,0 +1,72 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
28
29int wl1271_boot(struct wl1271 *wl);
30
31#define WL1271_NO_SUBBANDS 8
32#define WL1271_NO_POWER_LEVELS 4
33#define WL1271_FW_VERSION_MAX_LEN 20
34
35struct wl1271_static_data {
36 u8 mac_address[ETH_ALEN];
37 u8 padding[2];
38 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
39 u32 hw_version;
40 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
41};
42
43/* number of times we try to read the INIT interrupt */
44#define INIT_LOOP 20000
45
46/* delay between retries */
47#define INIT_LOOP_DELAY 50
48
49#define REF_CLOCK 2
50#define WU_COUNTER_PAUSE_VAL 0x3FF
51#define WELP_ARM_COMMAND_VAL 0x4
52
53#define OCP_CMD_LOOP 32
54
55#define OCP_CMD_WRITE 0x1
56#define OCP_CMD_READ 0x2
57
58#define OCP_READY_MASK BIT(18)
59#define OCP_STATUS_MASK (BIT(16) | BIT(17))
60
61#define OCP_STATUS_NO_RESP 0x00000
62#define OCP_STATUS_OK 0x10000
63#define OCP_STATUS_REQ_FAILED 0x20000
64#define OCP_STATUS_RESP_ERROR 0x30000
65
66#define OCP_REG_POLARITY 0x30032
67
68#define CMD_MBOX_ADDRESS 0x407B4
69
70#define POLARITY_LOW BIT(1)
71
72#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
new file mode 100644
index 000000000000..2a4351ff54dc
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -0,0 +1,813 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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/platform_device.h>
26#include <linux/crc7.h>
27#include <linux/spi/spi.h>
28#include <linux/etherdevice.h>
29
30#include "wl1271.h"
31#include "wl1271_reg.h"
32#include "wl1271_spi.h"
33#include "wl1271_acx.h"
34#include "wl12xx_80211.h"
35#include "wl1271_cmd.h"
36
37/*
38 * send command to firmware
39 *
40 * @wl: wl struct
41 * @id: command id
42 * @buf: buffer containing the command, must work with dma
43 * @len: length of the buffer
44 */
45int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
46{
47 struct wl1271_cmd_header *cmd;
48 unsigned long timeout;
49 u32 intr;
50 int ret = 0;
51
52 cmd = buf;
53 cmd->id = id;
54 cmd->status = 0;
55
56 WARN_ON(len % 4 != 0);
57
58 wl1271_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
59
60 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
61
62 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
63
64 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
65 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
66 if (time_after(jiffies, timeout)) {
67 wl1271_error("command complete timeout");
68 ret = -ETIMEDOUT;
69 goto out;
70 }
71
72 msleep(1);
73
74 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
75 }
76
77 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
78 WL1271_ACX_INTR_CMD_COMPLETE);
79
80out:
81 return ret;
82}
83
84int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
85{
86 struct wl1271_cmd_cal_channel_tune *cmd;
87 int ret = 0;
88
89 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
90 if (!cmd)
91 return -ENOMEM;
92
93 cmd->test.id = TEST_CMD_CHANNEL_TUNE;
94
95 cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4;
96 /* set up any channel, 7 is in the middle of the range */
97 cmd->channel = 7;
98
99 ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
100 if (ret < 0)
101 wl1271_warning("TEST_CMD_CHANNEL_TUNE failed");
102
103 kfree(cmd);
104 return ret;
105}
106
107int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
108{
109 struct wl1271_cmd_cal_update_ref_point *cmd;
110 int ret = 0;
111
112 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
113 if (!cmd)
114 return -ENOMEM;
115
116 cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
117
118 /* FIXME: still waiting for the correct values */
119 cmd->ref_power = 0;
120 cmd->ref_detector = 0;
121
122 cmd->sub_band = WL1271_PD_REFERENCE_POINT_BAND_B_G;
123
124 ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
125 if (ret < 0)
126 wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed");
127
128 kfree(cmd);
129 return ret;
130}
131
132int wl1271_cmd_cal_p2g(struct wl1271 *wl)
133{
134 struct wl1271_cmd_cal_p2g *cmd;
135 int ret = 0;
136
137 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
138 if (!cmd)
139 return -ENOMEM;
140
141 cmd->test.id = TEST_CMD_P2G_CAL;
142
143 cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G;
144
145 ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
146 if (ret < 0)
147 wl1271_warning("TEST_CMD_P2G_CAL failed");
148
149 kfree(cmd);
150 return ret;
151}
152
153int wl1271_cmd_cal(struct wl1271 *wl)
154{
155 /*
156 * FIXME: we must make sure that we're not sleeping when calibration
157 * is done
158 */
159 int ret;
160
161 wl1271_notice("performing tx calibration");
162
163 ret = wl1271_cmd_cal_channel_tune(wl);
164 if (ret < 0)
165 return ret;
166
167 ret = wl1271_cmd_cal_update_ref_point(wl);
168 if (ret < 0)
169 return ret;
170
171 ret = wl1271_cmd_cal_p2g(wl);
172 if (ret < 0)
173 return ret;
174
175 return ret;
176}
177
178int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
179 u16 beacon_interval, u8 wait)
180{
181 static bool do_cal = true;
182 unsigned long timeout;
183 struct wl1271_cmd_join *join;
184 int ret, i;
185 u8 *bssid;
186
187 /* FIXME: remove when we get calibration from the factory */
188 if (do_cal) {
189 ret = wl1271_cmd_cal(wl);
190 if (ret < 0)
191 wl1271_warning("couldn't calibrate");
192 else
193 do_cal = false;
194 }
195
196
197 join = kzalloc(sizeof(*join), GFP_KERNEL);
198 if (!join) {
199 ret = -ENOMEM;
200 goto out;
201 }
202
203 wl1271_debug(DEBUG_CMD, "cmd join");
204
205 /* Reverse order BSSID */
206 bssid = (u8 *) &join->bssid_lsb;
207 for (i = 0; i < ETH_ALEN; i++)
208 bssid[i] = wl->bssid[ETH_ALEN - i - 1];
209
210 join->rx_config_options = wl->rx_config;
211 join->rx_filter_options = wl->rx_filter;
212
213 join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
214 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
215
216 join->beacon_interval = beacon_interval;
217 join->dtim_interval = dtim_interval;
218 join->bss_type = bss_type;
219 join->channel = wl->channel;
220 join->ssid_len = wl->ssid_len;
221 memcpy(join->ssid, wl->ssid, wl->ssid_len);
222 join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH;
223
224 /* increment the session counter */
225 wl->session_counter++;
226 if (wl->session_counter >= SESSION_COUNTER_MAX)
227 wl->session_counter = 0;
228
229 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
230
231
232 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
233 if (ret < 0) {
234 wl1271_error("failed to initiate cmd join");
235 goto out_free;
236 }
237
238 timeout = msecs_to_jiffies(JOIN_TIMEOUT);
239
240 /*
241 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
242 * simplify locking we just sleep instead, for now
243 */
244 if (wait)
245 msleep(10);
246
247out_free:
248 kfree(join);
249
250out:
251 return ret;
252}
253
254/**
255 * send test command to firmware
256 *
257 * @wl: wl struct
258 * @buf: buffer containing the command, with all headers, must work with dma
259 * @len: length of the buffer
260 * @answer: is answer needed
261 */
262int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
263{
264 int ret;
265
266 wl1271_debug(DEBUG_CMD, "cmd test");
267
268 ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len);
269
270 if (ret < 0) {
271 wl1271_warning("TEST command failed");
272 return ret;
273 }
274
275 if (answer) {
276 struct wl1271_command *cmd_answer;
277
278 /*
279 * The test command got in, we can read the answer.
280 * The answer would be a wl1271_command, where the
281 * parameter array contains the actual answer.
282 */
283 wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
284
285 cmd_answer = buf;
286
287 if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
288 wl1271_error("TEST command answer error: %d",
289 cmd_answer->header.status);
290 }
291
292 return 0;
293}
294
295/**
296 * read acx from firmware
297 *
298 * @wl: wl struct
299 * @id: acx id
300 * @buf: buffer for the response, including all headers, must work with dma
301 * @len: lenght of buf
302 */
303int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
304{
305 struct acx_header *acx = buf;
306 int ret;
307
308 wl1271_debug(DEBUG_CMD, "cmd interrogate");
309
310 acx->id = id;
311
312 /* payload length, does not include any headers */
313 acx->len = len - sizeof(*acx);
314
315 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
316 if (ret < 0) {
317 wl1271_error("INTERROGATE command failed");
318 goto out;
319 }
320
321 /* the interrogate command got in, we can read the answer */
322 wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
323
324 acx = buf;
325 if (acx->cmd.status != CMD_STATUS_SUCCESS)
326 wl1271_error("INTERROGATE command error: %d",
327 acx->cmd.status);
328
329out:
330 return ret;
331}
332
333/**
334 * write acx value to firmware
335 *
336 * @wl: wl struct
337 * @id: acx id
338 * @buf: buffer containing acx, including all headers, must work with dma
339 * @len: length of buf
340 */
341int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
342{
343 struct acx_header *acx = buf;
344 int ret;
345
346 wl1271_debug(DEBUG_CMD, "cmd configure");
347
348 acx->id = id;
349
350 /* payload length, does not include any headers */
351 acx->len = len - sizeof(*acx);
352
353 ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len);
354 if (ret < 0) {
355 wl1271_warning("CONFIGURE command NOK");
356 return ret;
357 }
358
359 return 0;
360}
361
362int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
363{
364 struct cmd_enabledisable_path *cmd;
365 int ret;
366 u16 cmd_rx, cmd_tx;
367
368 wl1271_debug(DEBUG_CMD, "cmd data path");
369
370 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
371 if (!cmd) {
372 ret = -ENOMEM;
373 goto out;
374 }
375
376 cmd->channel = channel;
377
378 if (enable) {
379 cmd_rx = CMD_ENABLE_RX;
380 cmd_tx = CMD_ENABLE_TX;
381 } else {
382 cmd_rx = CMD_DISABLE_RX;
383 cmd_tx = CMD_DISABLE_TX;
384 }
385
386 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
387 if (ret < 0) {
388 wl1271_error("rx %s cmd for channel %d failed",
389 enable ? "start" : "stop", channel);
390 goto out;
391 }
392
393 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
394 enable ? "start" : "stop", channel);
395
396 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
397 if (ret < 0) {
398 wl1271_error("tx %s cmd for channel %d failed",
399 enable ? "start" : "stop", channel);
400 return ret;
401 }
402
403 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
404 enable ? "start" : "stop", channel);
405
406out:
407 kfree(cmd);
408 return ret;
409}
410
411int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
412{
413 struct wl1271_cmd_ps_params *ps_params = NULL;
414 int ret = 0;
415
416 /* FIXME: this should be in ps.c */
417 ret = wl1271_acx_wake_up_conditions(wl, WAKE_UP_EVENT_DTIM_BITMAP,
418 wl->listen_int);
419 if (ret < 0) {
420 wl1271_error("couldn't set wake up conditions");
421 goto out;
422 }
423
424 wl1271_debug(DEBUG_CMD, "cmd set ps mode");
425
426 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
427 if (!ps_params) {
428 ret = -ENOMEM;
429 goto out;
430 }
431
432 ps_params->ps_mode = ps_mode;
433 ps_params->send_null_data = 1;
434 ps_params->retries = 5;
435 ps_params->hang_over_period = 128;
436 ps_params->null_data_rate = 1; /* 1 Mbps */
437
438 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
439 sizeof(*ps_params));
440 if (ret < 0) {
441 wl1271_error("cmd set_ps_mode failed");
442 goto out;
443 }
444
445out:
446 kfree(ps_params);
447 return ret;
448}
449
450int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
451 size_t len)
452{
453 struct cmd_read_write_memory *cmd;
454 int ret = 0;
455
456 wl1271_debug(DEBUG_CMD, "cmd read memory");
457
458 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
459 if (!cmd) {
460 ret = -ENOMEM;
461 goto out;
462 }
463
464 WARN_ON(len > MAX_READ_SIZE);
465 len = min_t(size_t, len, MAX_READ_SIZE);
466
467 cmd->addr = addr;
468 cmd->size = len;
469
470 ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
471 if (ret < 0) {
472 wl1271_error("read memory command failed: %d", ret);
473 goto out;
474 }
475
476 /* the read command got in, we can now read the answer */
477 wl1271_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
478
479 if (cmd->header.status != CMD_STATUS_SUCCESS)
480 wl1271_error("error in read command result: %d",
481 cmd->header.status);
482
483 memcpy(answer, cmd->value, len);
484
485out:
486 kfree(cmd);
487 return ret;
488}
489
490int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
491 u8 active_scan, u8 high_prio, u8 num_channels,
492 u8 probe_requests)
493{
494
495 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
496 struct wl1271_cmd_scan *params = NULL;
497 int i, ret;
498 u16 scan_options = 0;
499
500 if (wl->scanning)
501 return -EINVAL;
502
503 params = kzalloc(sizeof(*params), GFP_KERNEL);
504 if (!params)
505 return -ENOMEM;
506
507 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
508 params->params.rx_filter_options =
509 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
510
511 if (!active_scan)
512 scan_options |= WL1271_SCAN_OPT_PASSIVE;
513 if (high_prio)
514 scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH;
515 params->params.scan_options = scan_options;
516
517 params->params.num_channels = num_channels;
518 params->params.num_probe_requests = probe_requests;
519 params->params.tx_rate = cpu_to_le32(RATE_MASK_2MBPS);
520 params->params.tid_trigger = 0;
521 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
522
523 for (i = 0; i < num_channels; i++) {
524 params->channels[i].min_duration =
525 cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
526 params->channels[i].max_duration =
527 cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
528 memset(&params->channels[i].bssid_lsb, 0xff, 4);
529 memset(&params->channels[i].bssid_msb, 0xff, 2);
530 params->channels[i].early_termination = 0;
531 params->channels[i].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR;
532 params->channels[i].channel = i + 1;
533 }
534
535 if (len && ssid) {
536 params->params.ssid_len = len;
537 memcpy(params->params.ssid, ssid, len);
538 }
539
540 ret = wl1271_cmd_build_probe_req(wl, ssid, len);
541 if (ret < 0) {
542 wl1271_error("PROBE request template failed");
543 goto out;
544 }
545
546 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
547 if (!trigger) {
548 ret = -ENOMEM;
549 goto out;
550 }
551
552 /* disable the timeout */
553 trigger->timeout = 0;
554
555 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
556 sizeof(*trigger));
557 if (ret < 0) {
558 wl1271_error("trigger scan to failed for hw scan");
559 goto out;
560 }
561
562 wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
563
564 wl->scanning = true;
565
566 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
567 if (ret < 0) {
568 wl1271_error("SCAN failed");
569 goto out;
570 }
571
572 wl1271_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
573
574 if (params->header.status != CMD_STATUS_SUCCESS) {
575 wl1271_error("Scan command error: %d",
576 params->header.status);
577 wl->scanning = false;
578 ret = -EIO;
579 goto out;
580 }
581
582out:
583 kfree(params);
584 return ret;
585}
586
587int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
588 void *buf, size_t buf_len)
589{
590 struct wl1271_cmd_template_set *cmd;
591 int ret = 0;
592
593 wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id);
594
595 WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
596 buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
597
598 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
599 if (!cmd) {
600 ret = -ENOMEM;
601 goto out;
602 }
603
604 cmd->len = cpu_to_le16(buf_len);
605 cmd->template_type = template_id;
606 cmd->enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
607 cmd->short_retry_limit = ACX_RATE_RETRY_LIMIT;
608 cmd->long_retry_limit = ACX_RATE_RETRY_LIMIT;
609
610 if (buf)
611 memcpy(cmd->template_data, buf, buf_len);
612
613 ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd));
614 if (ret < 0) {
615 wl1271_warning("cmd set_template failed: %d", ret);
616 goto out_free;
617 }
618
619out_free:
620 kfree(cmd);
621
622out:
623 return ret;
624}
625
626static int wl1271_build_basic_rates(char *rates)
627{
628 u8 index = 0;
629
630 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
631 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
632 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
633 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
634
635 return index;
636}
637
638static int wl1271_build_extended_rates(char *rates)
639{
640 u8 index = 0;
641
642 rates[index++] = IEEE80211_OFDM_RATE_6MB;
643 rates[index++] = IEEE80211_OFDM_RATE_9MB;
644 rates[index++] = IEEE80211_OFDM_RATE_12MB;
645 rates[index++] = IEEE80211_OFDM_RATE_18MB;
646 rates[index++] = IEEE80211_OFDM_RATE_24MB;
647 rates[index++] = IEEE80211_OFDM_RATE_36MB;
648 rates[index++] = IEEE80211_OFDM_RATE_48MB;
649 rates[index++] = IEEE80211_OFDM_RATE_54MB;
650
651 return index;
652}
653
654int wl1271_cmd_build_null_data(struct wl1271 *wl)
655{
656 struct wl12xx_null_data_template template;
657
658 if (!is_zero_ether_addr(wl->bssid)) {
659 memcpy(template.header.da, wl->bssid, ETH_ALEN);
660 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
661 } else {
662 memset(template.header.da, 0xff, ETH_ALEN);
663 memset(template.header.bssid, 0xff, ETH_ALEN);
664 }
665
666 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
667 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
668 IEEE80211_STYPE_NULLFUNC);
669
670 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template,
671 sizeof(template));
672
673}
674
675int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
676{
677 struct wl12xx_ps_poll_template template;
678
679 memcpy(template.bssid, wl->bssid, ETH_ALEN);
680 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
681 template.aid = aid;
682 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
683
684 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template,
685 sizeof(template));
686
687}
688
689int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len)
690{
691 struct wl12xx_probe_req_template template;
692 struct wl12xx_ie_rates *rates;
693 char *ptr;
694 u16 size;
695
696 ptr = (char *)&template;
697 size = sizeof(struct ieee80211_header);
698
699 memset(template.header.da, 0xff, ETH_ALEN);
700 memset(template.header.bssid, 0xff, ETH_ALEN);
701 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
702 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
703
704 /* IEs */
705 /* SSID */
706 template.ssid.header.id = WLAN_EID_SSID;
707 template.ssid.header.len = ssid_len;
708 if (ssid_len && ssid)
709 memcpy(template.ssid.ssid, ssid, ssid_len);
710 size += sizeof(struct wl12xx_ie_header) + ssid_len;
711 ptr += size;
712
713 /* Basic Rates */
714 rates = (struct wl12xx_ie_rates *)ptr;
715 rates->header.id = WLAN_EID_SUPP_RATES;
716 rates->header.len = wl1271_build_basic_rates(rates->rates);
717 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
718 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
719
720 /* Extended rates */
721 rates = (struct wl12xx_ie_rates *)ptr;
722 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
723 rates->header.len = wl1271_build_extended_rates(rates->rates);
724 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
725
726 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
727
728 return wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
729 &template, size);
730}
731
732int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
733{
734 struct wl1271_cmd_set_keys *cmd;
735 int ret = 0;
736
737 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
738
739 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
740 if (!cmd) {
741 ret = -ENOMEM;
742 goto out;
743 }
744
745 cmd->id = id;
746 cmd->key_action = KEY_SET_ID;
747 cmd->key_type = KEY_WEP;
748
749 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
750 if (ret < 0) {
751 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
752 goto out;
753 }
754
755out:
756 kfree(cmd);
757
758 return ret;
759}
760
761int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
762 u8 key_size, const u8 *key, const u8 *addr)
763{
764 struct wl1271_cmd_set_keys *cmd;
765 int ret = 0;
766
767 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
768 if (!cmd) {
769 ret = -ENOMEM;
770 goto out;
771 }
772
773 if (key_type != KEY_WEP)
774 memcpy(cmd->addr, addr, ETH_ALEN);
775
776 cmd->key_action = action;
777 cmd->key_size = key_size;
778 cmd->key_type = key_type;
779
780 /* we have only one SSID profile */
781 cmd->ssid_profile = 0;
782
783 cmd->id = id;
784
785 /* FIXME: this is from wl1251, needs to be checked */
786 if (key_type == KEY_TKIP) {
787 /*
788 * We get the key in the following form:
789 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
790 * but the target is expecting:
791 * TKIP - RX MIC - TX MIC
792 */
793 memcpy(cmd->key, key, 16);
794 memcpy(cmd->key + 16, key + 24, 8);
795 memcpy(cmd->key + 24, key + 16, 8);
796
797 } else {
798 memcpy(cmd->key, key, key_size);
799 }
800
801 wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
802
803 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
804 if (ret < 0) {
805 wl1271_warning("could not set keys");
806 goto out;
807 }
808
809out:
810 kfree(cmd);
811
812 return ret;
813}
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
new file mode 100644
index 000000000000..951a8447a516
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -0,0 +1,464 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_CMD_H__
26#define __WL1271_CMD_H__
27
28#include "wl1271.h"
29
30struct acx_header;
31
32int wl1271_cmd_send(struct wl1271 *wl, u16 type, void *buf, size_t buf_len);
33int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
34 u16 beacon_interval, u8 wait);
35int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
36int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
37int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
38int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable);
39int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode);
40int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
41 size_t len);
42int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
43 u8 active_scan, u8 high_prio, u8 num_channels,
44 u8 probe_requests);
45int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
46 void *buf, size_t buf_len);
47int wl1271_cmd_build_null_data(struct wl1271 *wl);
48int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
49int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len);
50int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
51int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
52 u8 key_size, const u8 *key, const u8 *addr);
53
54enum wl1271_commands {
55 CMD_INTERROGATE = 1, /*use this to read information elements*/
56 CMD_CONFIGURE = 2, /*use this to write information elements*/
57 CMD_ENABLE_RX = 3,
58 CMD_ENABLE_TX = 4,
59 CMD_DISABLE_RX = 5,
60 CMD_DISABLE_TX = 6,
61 CMD_SCAN = 8,
62 CMD_STOP_SCAN = 9,
63 CMD_START_JOIN = 11,
64 CMD_SET_KEYS = 12,
65 CMD_READ_MEMORY = 13,
66 CMD_WRITE_MEMORY = 14,
67 CMD_SET_TEMPLATE = 19,
68 CMD_TEST = 23,
69 CMD_NOISE_HIST = 28,
70 CMD_LNA_CONTROL = 32,
71 CMD_SET_BCN_MODE = 33,
72 CMD_MEASUREMENT = 34,
73 CMD_STOP_MEASUREMENT = 35,
74 CMD_DISCONNECT = 36,
75 CMD_SET_PS_MODE = 37,
76 CMD_CHANNEL_SWITCH = 38,
77 CMD_STOP_CHANNEL_SWICTH = 39,
78 CMD_AP_DISCOVERY = 40,
79 CMD_STOP_AP_DISCOVERY = 41,
80 CMD_SPS_SCAN = 42,
81 CMD_STOP_SPS_SCAN = 43,
82 CMD_HEALTH_CHECK = 45,
83 CMD_DEBUG = 46,
84 CMD_TRIGGER_SCAN_TO = 47,
85 CMD_CONNECTION_SCAN_CFG = 48,
86 CMD_CONNECTION_SCAN_SSID_CFG = 49,
87 CMD_START_PERIODIC_SCAN = 50,
88 CMD_STOP_PERIODIC_SCAN = 51,
89 CMD_SET_STA_STATE = 52,
90
91 NUM_COMMANDS,
92 MAX_COMMAND_ID = 0xFFFF,
93};
94
95#define MAX_CMD_PARAMS 572
96
97enum cmd_templ {
98 CMD_TEMPL_NULL_DATA = 0,
99 CMD_TEMPL_BEACON,
100 CMD_TEMPL_CFG_PROBE_REQ_2_4,
101 CMD_TEMPL_CFG_PROBE_REQ_5,
102 CMD_TEMPL_PROBE_RESPONSE,
103 CMD_TEMPL_QOS_NULL_DATA,
104 CMD_TEMPL_PS_POLL,
105 CMD_TEMPL_KLV,
106 CMD_TEMPL_DISCONNECT,
107 CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */
108 CMD_TEMPL_PROBE_REQ_5, /* for firmware internal use only */
109 CMD_TEMPL_BAR, /* for firmware internal use only */
110 CMD_TEMPL_CTS, /*
111 * For CTS-to-self (FastCTS) mechanism
112 * for BT/WLAN coexistence (SoftGemini). */
113 CMD_TEMPL_MAX = 0xff
114};
115
116/* unit ms */
117#define WL1271_COMMAND_TIMEOUT 2000
118#define WL1271_CMD_TEMPL_MAX_SIZE 252
119
120struct wl1271_cmd_header {
121 u16 id;
122 u16 status;
123 /* payload */
124 u8 data[0];
125} __attribute__ ((packed));
126
127#define WL1271_CMD_MAX_PARAMS 572
128
129struct wl1271_command {
130 struct wl1271_cmd_header header;
131 u8 parameters[WL1271_CMD_MAX_PARAMS];
132} __attribute__ ((packed));
133
134enum {
135 CMD_MAILBOX_IDLE = 0,
136 CMD_STATUS_SUCCESS = 1,
137 CMD_STATUS_UNKNOWN_CMD = 2,
138 CMD_STATUS_UNKNOWN_IE = 3,
139 CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
140 CMD_STATUS_RX_BUSY = 13,
141 CMD_STATUS_INVALID_PARAM = 14,
142 CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
143 CMD_STATUS_OUT_OF_MEMORY = 16,
144 CMD_STATUS_STA_TABLE_FULL = 17,
145 CMD_STATUS_RADIO_ERROR = 18,
146 CMD_STATUS_WRONG_NESTING = 19,
147 CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
148 CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
149 MAX_COMMAND_STATUS = 0xff
150};
151
152
153/*
154 * CMD_READ_MEMORY
155 *
156 * The host issues this command to read the WiLink device memory/registers.
157 *
158 * Note: The Base Band address has special handling (16 bits registers and
159 * addresses). For more information, see the hardware specification.
160 */
161/*
162 * CMD_WRITE_MEMORY
163 *
164 * The host issues this command to write the WiLink device memory/registers.
165 *
166 * The Base Band address has special handling (16 bits registers and
167 * addresses). For more information, see the hardware specification.
168 */
169#define MAX_READ_SIZE 256
170
171struct cmd_read_write_memory {
172 struct wl1271_cmd_header header;
173
174 /* The address of the memory to read from or write to.*/
175 u32 addr;
176
177 /* The amount of data in bytes to read from or write to the WiLink
178 * device.*/
179 u32 size;
180
181 /* The actual value read from or written to the Wilink. The source
182 of this field is the Host in WRITE command or the Wilink in READ
183 command. */
184 u8 value[MAX_READ_SIZE];
185};
186
187#define CMDMBOX_HEADER_LEN 4
188#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
189
190enum {
191 BSS_TYPE_IBSS = 0,
192 BSS_TYPE_STA_BSS = 2,
193 BSS_TYPE_AP_BSS = 3,
194 MAX_BSS_TYPE = 0xFF
195};
196
197#define WL1271_JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
198#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
199
200struct wl1271_cmd_join {
201 struct wl1271_cmd_header header;
202
203 u32 bssid_lsb;
204 u16 bssid_msb;
205 u16 beacon_interval; /* in TBTTs */
206 u32 rx_config_options;
207 u32 rx_filter_options;
208
209 /*
210 * The target uses this field to determine the rate at
211 * which to transmit control frame responses (such as
212 * ACK or CTS frames).
213 */
214 u32 basic_rate_set;
215 u8 dtim_interval;
216 /*
217 * bits 0-2: This bitwise field specifies the type
218 * of BSS to start or join (BSS_TYPE_*).
219 * bit 4: Band - The radio band in which to join
220 * or start.
221 * 0 - 2.4GHz band
222 * 1 - 5GHz band
223 * bits 3, 5-7: Reserved
224 */
225 u8 bss_type;
226 u8 channel;
227 u8 ssid_len;
228 u8 ssid[IW_ESSID_MAX_SIZE];
229 u8 ctrl; /* JOIN_CMD_CTRL_* */
230 u8 reserved[3];
231} __attribute__ ((packed));
232
233struct cmd_enabledisable_path {
234 struct wl1271_cmd_header header;
235
236 u8 channel;
237 u8 padding[3];
238} __attribute__ ((packed));
239
240struct wl1271_cmd_template_set {
241 struct wl1271_cmd_header header;
242
243 u16 len;
244 u8 template_type;
245 u8 index; /* relevant only for KLV_TEMPLATE type */
246 u32 enabled_rates;
247 u8 short_retry_limit;
248 u8 long_retry_limit;
249 u8 aflags;
250 u8 reserved;
251 u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
252} __attribute__ ((packed));
253
254#define TIM_ELE_ID 5
255#define PARTIAL_VBM_MAX 251
256
257struct wl1271_tim {
258 u8 identity;
259 u8 length;
260 u8 dtim_count;
261 u8 dtim_period;
262 u8 bitmap_ctrl;
263 u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
264} __attribute__ ((packed));
265
266enum wl1271_cmd_ps_mode {
267 STATION_ACTIVE_MODE,
268 STATION_POWER_SAVE_MODE
269};
270
271struct wl1271_cmd_ps_params {
272 struct wl1271_cmd_header header;
273
274 u8 ps_mode; /* STATION_* */
275 u8 send_null_data; /* Do we have to send NULL data packet ? */
276 u8 retries; /* Number of retires for the initial NULL data packet */
277
278 /*
279 * TUs during which the target stays awake after switching
280 * to power save mode.
281 */
282 u8 hang_over_period;
283 u32 null_data_rate;
284} __attribute__ ((packed));
285
286/* HW encryption keys */
287#define NUM_ACCESS_CATEGORIES_COPY 4
288#define MAX_KEY_SIZE 32
289
290/* When set, disable HW encryption */
291#define DF_ENCRYPTION_DISABLE 0x01
292/* When set, disable HW decryption */
293#define DF_SNIFF_MODE_ENABLE 0x80
294
295enum wl1271_cmd_key_action {
296 KEY_ADD_OR_REPLACE = 1,
297 KEY_REMOVE = 2,
298 KEY_SET_ID = 3,
299 MAX_KEY_ACTION = 0xffff,
300};
301
302enum wl1271_cmd_key_type {
303 KEY_NONE = 0,
304 KEY_WEP = 1,
305 KEY_TKIP = 2,
306 KEY_AES = 3,
307 KEY_GEM = 4
308};
309
310/* FIXME: Add description for key-types */
311
312struct wl1271_cmd_set_keys {
313 struct wl1271_cmd_header header;
314
315 /* Ignored for default WEP key */
316 u8 addr[ETH_ALEN];
317
318 /* key_action_e */
319 u16 key_action;
320
321 u16 reserved_1;
322
323 /* key size in bytes */
324 u8 key_size;
325
326 /* key_type_e */
327 u8 key_type;
328 u8 ssid_profile;
329
330 /*
331 * TKIP, AES: frame's key id field.
332 * For WEP default key: key id;
333 */
334 u8 id;
335 u8 reserved_2[6];
336 u8 key[MAX_KEY_SIZE];
337 u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
338 u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
339} __attribute__ ((packed));
340
341
342#define WL1271_SCAN_MAX_CHANNELS 24
343#define WL1271_SCAN_DEFAULT_TAG 1
344#define WL1271_SCAN_CURRENT_TX_PWR 0
345#define WL1271_SCAN_OPT_ACTIVE 0
346#define WL1271_SCAN_OPT_PASSIVE 1
347#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
348#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */
349#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */
350
351struct basic_scan_params {
352 u32 rx_config_options;
353 u32 rx_filter_options;
354 /* Scan option flags (WL1271_SCAN_OPT_*) */
355 u16 scan_options;
356 /* Number of scan channels in the list (maximum 30) */
357 u8 num_channels;
358 /* This field indicates the number of probe requests to send
359 per channel for an active scan */
360 u8 num_probe_requests;
361 /* Rate bit field for sending the probes */
362 u32 tx_rate;
363 u8 tid_trigger;
364 u8 ssid_len;
365 /* in order to align */
366 u8 padding1[2];
367 u8 ssid[IW_ESSID_MAX_SIZE];
368 /* Band to scan */
369 u8 band;
370 u8 use_ssid_list;
371 u8 scan_tag;
372 u8 padding2;
373} __attribute__ ((packed));
374
375struct basic_scan_channel_params {
376 /* Duration in TU to wait for frames on a channel for active scan */
377 u32 min_duration;
378 u32 max_duration;
379 u32 bssid_lsb;
380 u16 bssid_msb;
381 u8 early_termination;
382 u8 tx_power_att;
383 u8 channel;
384 /* FW internal use only! */
385 u8 dfs_candidate;
386 u8 activity_detected;
387 u8 pad;
388} __attribute__ ((packed));
389
390struct wl1271_cmd_scan {
391 struct wl1271_cmd_header header;
392
393 struct basic_scan_params params;
394 struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS];
395} __attribute__ ((packed));
396
397struct wl1271_cmd_trigger_scan_to {
398 struct wl1271_cmd_header header;
399
400 u32 timeout;
401};
402
403struct wl1271_cmd_test_header {
404 u8 id;
405 u8 padding[3];
406};
407
408enum wl1271_channel_tune_bands {
409 WL1271_CHANNEL_TUNE_BAND_2_4,
410 WL1271_CHANNEL_TUNE_BAND_5,
411 WL1271_CHANNEL_TUNE_BAND_4_9
412};
413
414#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
415
416#define TEST_CMD_P2G_CAL 0x02
417#define TEST_CMD_CHANNEL_TUNE 0x0d
418#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
419
420struct wl1271_cmd_cal_channel_tune {
421 struct wl1271_cmd_header header;
422
423 struct wl1271_cmd_test_header test;
424
425 u8 band;
426 u8 channel;
427
428 u16 radio_status;
429} __attribute__ ((packed));
430
431struct wl1271_cmd_cal_update_ref_point {
432 struct wl1271_cmd_header header;
433
434 struct wl1271_cmd_test_header test;
435
436 s32 ref_power;
437 s32 ref_detector;
438 u8 sub_band;
439 u8 padding[3];
440} __attribute__ ((packed));
441
442#define MAX_TLV_LENGTH 400
443#define MAX_NVS_VERSION_LENGTH 12
444
445#define WL1271_CAL_P2G_BAND_B_G BIT(0)
446
447struct wl1271_cmd_cal_p2g {
448 struct wl1271_cmd_header header;
449
450 struct wl1271_cmd_test_header test;
451
452 u16 len;
453 u8 buf[MAX_TLV_LENGTH];
454 u8 type;
455 u8 padding;
456
457 s16 radio_status;
458 u8 nvs_version[MAX_NVS_VERSION_LENGTH];
459
460 u8 sub_band_mask;
461 u8 padding2;
462} __attribute__ ((packed));
463
464#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
new file mode 100644
index 000000000000..c1805e5f8964
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -0,0 +1,518 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_debugfs.h"
25
26#include <linux/skbuff.h>
27
28#include "wl1271.h"
29#include "wl1271_acx.h"
30#include "wl1271_ps.h"
31
32/* ms */
33#define WL1271_DEBUGFS_STATS_LIFETIME 1000
34
35/* debugfs macros idea from mac80211 */
36
37#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
38static ssize_t name## _read(struct file *file, char __user *userbuf, \
39 size_t count, loff_t *ppos) \
40{ \
41 struct wl1271 *wl = file->private_data; \
42 char buf[buflen]; \
43 int res; \
44 \
45 res = scnprintf(buf, buflen, fmt "\n", ##value); \
46 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
47} \
48 \
49static const struct file_operations name## _ops = { \
50 .read = name## _read, \
51 .open = wl1271_open_file_generic, \
52};
53
54#define DEBUGFS_ADD(name, parent) \
55 wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
56 wl, &name## _ops); \
57 if (IS_ERR(wl->debugfs.name)) { \
58 ret = PTR_ERR(wl->debugfs.name); \
59 wl->debugfs.name = NULL; \
60 goto out; \
61 }
62
63#define DEBUGFS_DEL(name) \
64 do { \
65 debugfs_remove(wl->debugfs.name); \
66 wl->debugfs.name = NULL; \
67 } while (0)
68
69#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
70static ssize_t sub## _ ##name## _read(struct file *file, \
71 char __user *userbuf, \
72 size_t count, loff_t *ppos) \
73{ \
74 struct wl1271 *wl = file->private_data; \
75 char buf[buflen]; \
76 int res; \
77 \
78 wl1271_debugfs_update_stats(wl); \
79 \
80 res = scnprintf(buf, buflen, fmt "\n", \
81 wl->stats.fw_stats->sub.name); \
82 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
83} \
84 \
85static const struct file_operations sub## _ ##name## _ops = { \
86 .read = sub## _ ##name## _read, \
87 .open = wl1271_open_file_generic, \
88};
89
90#define DEBUGFS_FWSTATS_ADD(sub, name) \
91 DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
92
93#define DEBUGFS_FWSTATS_DEL(sub, name) \
94 DEBUGFS_DEL(sub## _ ##name)
95
96static void wl1271_debugfs_update_stats(struct wl1271 *wl)
97{
98 int ret;
99
100 mutex_lock(&wl->mutex);
101
102 ret = wl1271_ps_elp_wakeup(wl, false);
103 if (ret < 0)
104 goto out;
105
106 if (wl->state == WL1271_STATE_ON &&
107 time_after(jiffies, wl->stats.fw_stats_update +
108 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
109 wl1271_acx_statistics(wl, wl->stats.fw_stats);
110 wl->stats.fw_stats_update = jiffies;
111 }
112
113 wl1271_ps_elp_sleep(wl);
114
115out:
116 mutex_unlock(&wl->mutex);
117}
118
119static int wl1271_open_file_generic(struct inode *inode, struct file *file)
120{
121 file->private_data = inode->i_private;
122 return 0;
123}
124
125DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
126
127DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
128DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
129DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
130DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
131DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
132DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
133DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
134DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
135
136DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
137DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
138DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
139DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
140
141DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
142DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
143DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
144DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
145DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
146DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
147DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
148DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
149DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
150DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
151DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
152DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
153DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
154DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
155DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
156DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
157DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
158DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
159
160DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
161DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
162/* skipping wep.reserved */
163DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
164DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
165DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
166DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
167
168DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
169DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
170DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
171DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
172DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
173DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
174DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
175DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
176DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
177DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
178DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
179DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
180/* skipping cont_miss_bcns_spread for now */
181DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
182
183DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
184DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
185
186DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
187DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
188DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
189DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
190DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
191DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
192
193DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
194DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
195DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
196DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
197DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
198DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
199DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
200DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
201
202DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
203DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
204DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
205DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
206DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
207DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
208DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
209
210DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
211DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
212DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
213 20, "%u");
214DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
215DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
216
217DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
218DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
219 wl->stats.excessive_retries);
220
221static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
222 size_t count, loff_t *ppos)
223{
224 struct wl1271 *wl = file->private_data;
225 u32 queue_len;
226 char buf[20];
227 int res;
228
229 queue_len = skb_queue_len(&wl->tx_queue);
230
231 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
232 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
233}
234
235static const struct file_operations tx_queue_len_ops = {
236 .read = tx_queue_len_read,
237 .open = wl1271_open_file_generic,
238};
239
240static void wl1271_debugfs_delete_files(struct wl1271 *wl)
241{
242 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
243
244 DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
245 DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
246 DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
247 DEBUGFS_FWSTATS_DEL(rx, dropped);
248 DEBUGFS_FWSTATS_DEL(rx, fcs_err);
249 DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
250 DEBUGFS_FWSTATS_DEL(rx, path_reset);
251 DEBUGFS_FWSTATS_DEL(rx, reset_counter);
252
253 DEBUGFS_FWSTATS_DEL(dma, rx_requested);
254 DEBUGFS_FWSTATS_DEL(dma, rx_errors);
255 DEBUGFS_FWSTATS_DEL(dma, tx_requested);
256 DEBUGFS_FWSTATS_DEL(dma, tx_errors);
257
258 DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
259 DEBUGFS_FWSTATS_DEL(isr, fiqs);
260 DEBUGFS_FWSTATS_DEL(isr, rx_headers);
261 DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
262 DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
263 DEBUGFS_FWSTATS_DEL(isr, irqs);
264 DEBUGFS_FWSTATS_DEL(isr, tx_procs);
265 DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
266 DEBUGFS_FWSTATS_DEL(isr, dma0_done);
267 DEBUGFS_FWSTATS_DEL(isr, dma1_done);
268 DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
269 DEBUGFS_FWSTATS_DEL(isr, commands);
270 DEBUGFS_FWSTATS_DEL(isr, rx_procs);
271 DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
272 DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
273 DEBUGFS_FWSTATS_DEL(isr, pci_pm);
274 DEBUGFS_FWSTATS_DEL(isr, wakeups);
275 DEBUGFS_FWSTATS_DEL(isr, low_rssi);
276
277 DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
278 DEBUGFS_FWSTATS_DEL(wep, default_key_count);
279 /* skipping wep.reserved */
280 DEBUGFS_FWSTATS_DEL(wep, key_not_found);
281 DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
282 DEBUGFS_FWSTATS_DEL(wep, packets);
283 DEBUGFS_FWSTATS_DEL(wep, interrupt);
284
285 DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
286 DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
287 DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
288 DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
289 DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
290 DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
291 DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
292 DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
293 DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
294 DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
295 DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
296 DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
297 /* skipping cont_miss_bcns_spread for now */
298 DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
299
300 DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
301 DEBUGFS_FWSTATS_DEL(mic, calc_failure);
302
303 DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
304 DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
305 DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
306 DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
307 DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
308 DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
309
310 DEBUGFS_FWSTATS_DEL(event, heart_beat);
311 DEBUGFS_FWSTATS_DEL(event, calibration);
312 DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
313 DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
314 DEBUGFS_FWSTATS_DEL(event, rx_pool);
315 DEBUGFS_FWSTATS_DEL(event, oom_late);
316 DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
317 DEBUGFS_FWSTATS_DEL(event, tx_stuck);
318
319 DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
320 DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
321 DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
322 DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
323 DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
324 DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
325 DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
326
327 DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
328 DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
329 DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
330 DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
331 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
332
333 DEBUGFS_DEL(tx_queue_len);
334 DEBUGFS_DEL(retry_count);
335 DEBUGFS_DEL(excessive_retries);
336}
337
338static int wl1271_debugfs_add_files(struct wl1271 *wl)
339{
340 int ret = 0;
341
342 DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
343
344 DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
345 DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
346 DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
347 DEBUGFS_FWSTATS_ADD(rx, dropped);
348 DEBUGFS_FWSTATS_ADD(rx, fcs_err);
349 DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
350 DEBUGFS_FWSTATS_ADD(rx, path_reset);
351 DEBUGFS_FWSTATS_ADD(rx, reset_counter);
352
353 DEBUGFS_FWSTATS_ADD(dma, rx_requested);
354 DEBUGFS_FWSTATS_ADD(dma, rx_errors);
355 DEBUGFS_FWSTATS_ADD(dma, tx_requested);
356 DEBUGFS_FWSTATS_ADD(dma, tx_errors);
357
358 DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
359 DEBUGFS_FWSTATS_ADD(isr, fiqs);
360 DEBUGFS_FWSTATS_ADD(isr, rx_headers);
361 DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
362 DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
363 DEBUGFS_FWSTATS_ADD(isr, irqs);
364 DEBUGFS_FWSTATS_ADD(isr, tx_procs);
365 DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
366 DEBUGFS_FWSTATS_ADD(isr, dma0_done);
367 DEBUGFS_FWSTATS_ADD(isr, dma1_done);
368 DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
369 DEBUGFS_FWSTATS_ADD(isr, commands);
370 DEBUGFS_FWSTATS_ADD(isr, rx_procs);
371 DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
372 DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
373 DEBUGFS_FWSTATS_ADD(isr, pci_pm);
374 DEBUGFS_FWSTATS_ADD(isr, wakeups);
375 DEBUGFS_FWSTATS_ADD(isr, low_rssi);
376
377 DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
378 DEBUGFS_FWSTATS_ADD(wep, default_key_count);
379 /* skipping wep.reserved */
380 DEBUGFS_FWSTATS_ADD(wep, key_not_found);
381 DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
382 DEBUGFS_FWSTATS_ADD(wep, packets);
383 DEBUGFS_FWSTATS_ADD(wep, interrupt);
384
385 DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
386 DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
387 DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
388 DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
389 DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
390 DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
391 DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
392 DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
393 DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
394 DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
395 DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
396 DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
397 /* skipping cont_miss_bcns_spread for now */
398 DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
399
400 DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
401 DEBUGFS_FWSTATS_ADD(mic, calc_failure);
402
403 DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
404 DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
405 DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
406 DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
407 DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
408 DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
409
410 DEBUGFS_FWSTATS_ADD(event, heart_beat);
411 DEBUGFS_FWSTATS_ADD(event, calibration);
412 DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
413 DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
414 DEBUGFS_FWSTATS_ADD(event, rx_pool);
415 DEBUGFS_FWSTATS_ADD(event, oom_late);
416 DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
417 DEBUGFS_FWSTATS_ADD(event, tx_stuck);
418
419 DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
420 DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
421 DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
422 DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
423 DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
424 DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
425 DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
426
427 DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
428 DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
429 DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
430 DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
431 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
432
433 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
434 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
435 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
436
437out:
438 if (ret < 0)
439 wl1271_debugfs_delete_files(wl);
440
441 return ret;
442}
443
444void wl1271_debugfs_reset(struct wl1271 *wl)
445{
446 memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
447 wl->stats.retry_count = 0;
448 wl->stats.excessive_retries = 0;
449}
450
451int wl1271_debugfs_init(struct wl1271 *wl)
452{
453 int ret;
454
455 wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
456
457 if (IS_ERR(wl->debugfs.rootdir)) {
458 ret = PTR_ERR(wl->debugfs.rootdir);
459 wl->debugfs.rootdir = NULL;
460 goto err;
461 }
462
463 wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
464 wl->debugfs.rootdir);
465
466 if (IS_ERR(wl->debugfs.fw_statistics)) {
467 ret = PTR_ERR(wl->debugfs.fw_statistics);
468 wl->debugfs.fw_statistics = NULL;
469 goto err_root;
470 }
471
472 wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
473 GFP_KERNEL);
474
475 if (!wl->stats.fw_stats) {
476 ret = -ENOMEM;
477 goto err_fw;
478 }
479
480 wl->stats.fw_stats_update = jiffies;
481
482 ret = wl1271_debugfs_add_files(wl);
483
484 if (ret < 0)
485 goto err_file;
486
487 return 0;
488
489err_file:
490 kfree(wl->stats.fw_stats);
491 wl->stats.fw_stats = NULL;
492
493err_fw:
494 debugfs_remove(wl->debugfs.fw_statistics);
495 wl->debugfs.fw_statistics = NULL;
496
497err_root:
498 debugfs_remove(wl->debugfs.rootdir);
499 wl->debugfs.rootdir = NULL;
500
501err:
502 return ret;
503}
504
505void wl1271_debugfs_exit(struct wl1271 *wl)
506{
507 wl1271_debugfs_delete_files(wl);
508
509 kfree(wl->stats.fw_stats);
510 wl->stats.fw_stats = NULL;
511
512 debugfs_remove(wl->debugfs.fw_statistics);
513 wl->debugfs.fw_statistics = NULL;
514
515 debugfs_remove(wl->debugfs.rootdir);
516 wl->debugfs.rootdir = NULL;
517
518}
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/wl1271_debugfs.h
new file mode 100644
index 000000000000..00a45b2669ad
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.h
@@ -0,0 +1,33 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 WL1271_DEBUGFS_H
25#define WL1271_DEBUGFS_H
26
27#include "wl1271.h"
28
29int wl1271_debugfs_init(struct wl1271 *wl);
30void wl1271_debugfs_exit(struct wl1271 *wl);
31void wl1271_debugfs_reset(struct wl1271 *wl);
32
33#endif /* WL1271_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
new file mode 100644
index 000000000000..f3afd4a6ff33
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -0,0 +1,125 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
25#include "wl1271_reg.h"
26#include "wl1271_spi.h"
27#include "wl1271_event.h"
28#include "wl1271_ps.h"
29
30static int wl1271_event_scan_complete(struct wl1271 *wl,
31 struct event_mailbox *mbox)
32{
33 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
34 mbox->scheduled_scan_status);
35
36 if (wl->scanning) {
37 mutex_unlock(&wl->mutex);
38 ieee80211_scan_completed(wl->hw, false);
39 mutex_lock(&wl->mutex);
40 wl->scanning = false;
41 }
42
43 return 0;
44}
45
46static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
47{
48 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
49 wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
50 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
51}
52
53static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
54{
55 int ret;
56 u32 vector;
57
58 wl1271_event_mbox_dump(mbox);
59
60 vector = mbox->events_vector & ~(mbox->events_mask);
61 wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);
62
63 if (vector & SCAN_COMPLETE_EVENT_ID) {
64 ret = wl1271_event_scan_complete(wl, mbox);
65 if (ret < 0)
66 return ret;
67 }
68
69 if (vector & BSS_LOSE_EVENT_ID) {
70 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
71
72 if (wl->psm_requested && wl->psm) {
73 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
74 if (ret < 0)
75 return ret;
76 }
77 }
78
79 return 0;
80}
81
82int wl1271_event_unmask(struct wl1271 *wl)
83{
84 int ret;
85
86 ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask));
87 if (ret < 0)
88 return ret;
89
90 return 0;
91}
92
93void wl1271_event_mbox_config(struct wl1271 *wl)
94{
95 wl->mbox_ptr[0] = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
96 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
97
98 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
99 wl->mbox_ptr[0], wl->mbox_ptr[1]);
100}
101
102int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
103{
104 struct event_mailbox mbox;
105 int ret;
106
107 wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
108
109 if (mbox_num > 1)
110 return -EINVAL;
111
112 /* first we read the mbox descriptor */
113 wl1271_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
114 sizeof(struct event_mailbox));
115
116 /* process the descriptor */
117 ret = wl1271_event_process(wl, &mbox);
118 if (ret < 0)
119 return ret;
120
121 /* then we let the firmware know it can go on...*/
122 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
123
124 return 0;
125}
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
new file mode 100644
index 000000000000..2cdce7c34bf0
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -0,0 +1,110 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_EVENT_H__
26#define __WL1271_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 MEASUREMENT_START_EVENT_ID = BIT(8),
42 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
43 SCAN_COMPLETE_EVENT_ID = BIT(10),
44 SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(11),
45 AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
46 PS_REPORT_EVENT_ID = BIT(13),
47 PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
48 DISCONNECT_EVENT_COMPLETE_ID = BIT(15),
49 JOIN_EVENT_COMPLETE_ID = BIT(16),
50 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
51 BSS_LOSE_EVENT_ID = BIT(18),
52 REGAINED_BSS_EVENT_ID = BIT(19),
53 ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20),
54 SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
55 SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23),
56 SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
57 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
58 DBG_EVENT_ID = BIT(26),
59 HEALTH_CHECK_REPLY_EVENT_ID = BIT(27),
60 PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28),
61 PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29),
62 BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30),
63 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
64};
65
66struct event_debug_report {
67 u8 debug_event_id;
68 u8 num_params;
69 u16 pad;
70 u32 report_1;
71 u32 report_2;
72 u32 report_3;
73} __attribute__ ((packed));
74
75#define NUM_OF_RSSI_SNR_TRIGGERS 8
76
77struct event_mailbox {
78 u32 events_vector;
79 u32 events_mask;
80 u32 reserved_1;
81 u32 reserved_2;
82
83 u8 dbg_event_id;
84 u8 num_relevant_params;
85 u16 reserved_3;
86 u32 event_report_p1;
87 u32 event_report_p2;
88 u32 event_report_p3;
89
90 u8 number_of_scan_results;
91 u8 scan_tag;
92 u8 reserved_4[2];
93 u32 compl_scheduled_scan_status;
94
95 u16 scheduled_scan_attended_channels;
96 u8 soft_gemini_sense_info;
97 u8 soft_gemini_protective_info;
98 s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
99 u8 channel_switch_status;
100 u8 scheduled_scan_status;
101 u8 ps_status;
102
103 u8 reserved_5[29];
104} __attribute__ ((packed));
105
106int wl1271_event_unmask(struct wl1271 *wl);
107void wl1271_event_mbox_config(struct wl1271 *wl);
108int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
109
110#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
new file mode 100644
index 000000000000..490df217605a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -0,0 +1,397 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_init.h"
28#include "wl12xx_80211.h"
29#include "wl1271_acx.h"
30#include "wl1271_cmd.h"
31#include "wl1271_reg.h"
32
33static int wl1271_init_hwenc_config(struct wl1271 *wl)
34{
35 int ret;
36
37 ret = wl1271_acx_feature_cfg(wl);
38 if (ret < 0) {
39 wl1271_warning("couldn't set feature config");
40 return ret;
41 }
42
43 ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key);
44 if (ret < 0) {
45 wl1271_warning("couldn't set default key");
46 return ret;
47 }
48
49 return 0;
50}
51
52static int wl1271_init_templates_config(struct wl1271 *wl)
53{
54 int ret;
55
56 /* send empty templates for fw memory reservation */
57 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
58 sizeof(struct wl12xx_probe_req_template));
59 if (ret < 0)
60 return ret;
61
62 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
63 sizeof(struct wl12xx_null_data_template));
64 if (ret < 0)
65 return ret;
66
67 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
68 sizeof(struct wl12xx_ps_poll_template));
69 if (ret < 0)
70 return ret;
71
72 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
73 sizeof
74 (struct wl12xx_qos_null_data_template));
75 if (ret < 0)
76 return ret;
77
78 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
79 sizeof
80 (struct wl12xx_probe_resp_template));
81 if (ret < 0)
82 return ret;
83
84 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
85 sizeof
86 (struct wl12xx_beacon_template));
87 if (ret < 0)
88 return ret;
89
90 return 0;
91}
92
93static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
94{
95 int ret;
96
97 ret = wl1271_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
98 if (ret < 0)
99 return ret;
100
101 ret = wl1271_acx_rx_config(wl, config, filter);
102 if (ret < 0)
103 return ret;
104
105 return 0;
106}
107
108static int wl1271_init_phy_config(struct wl1271 *wl)
109{
110 int ret;
111
112 ret = wl1271_acx_pd_threshold(wl);
113 if (ret < 0)
114 return ret;
115
116 ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME);
117 if (ret < 0)
118 return ret;
119
120 ret = wl1271_acx_group_address_tbl(wl);
121 if (ret < 0)
122 return ret;
123
124 ret = wl1271_acx_service_period_timeout(wl);
125 if (ret < 0)
126 return ret;
127
128 ret = wl1271_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
129 if (ret < 0)
130 return ret;
131
132 return 0;
133}
134
135static int wl1271_init_beacon_filter(struct wl1271 *wl)
136{
137 int ret;
138
139 ret = wl1271_acx_beacon_filter_opt(wl);
140 if (ret < 0)
141 return ret;
142
143 ret = wl1271_acx_beacon_filter_table(wl);
144 if (ret < 0)
145 return ret;
146
147 return 0;
148}
149
150static int wl1271_init_pta(struct wl1271 *wl)
151{
152 int ret;
153
154 ret = wl1271_acx_sg_enable(wl);
155 if (ret < 0)
156 return ret;
157
158 ret = wl1271_acx_sg_cfg(wl);
159 if (ret < 0)
160 return ret;
161
162 return 0;
163}
164
165static int wl1271_init_energy_detection(struct wl1271 *wl)
166{
167 int ret;
168
169 ret = wl1271_acx_cca_threshold(wl);
170 if (ret < 0)
171 return ret;
172
173 return 0;
174}
175
176static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
177{
178 int ret;
179
180 ret = wl1271_acx_bcn_dtim_options(wl);
181 if (ret < 0)
182 return ret;
183
184 return 0;
185}
186
187static int wl1271_init_general_parms(struct wl1271 *wl)
188{
189 struct wl1271_general_parms *gen_parms;
190 int ret;
191
192 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
193 if (!gen_parms)
194 return -ENOMEM;
195
196 gen_parms->id = TEST_CMD_INI_FILE_GENERAL_PARAM;
197
198 gen_parms->ref_clk = REF_CLK_38_4_E;
199 /* FIXME: magic numbers */
200 gen_parms->settling_time = 5;
201 gen_parms->clk_valid_on_wakeup = 0;
202 gen_parms->dc2dcmode = 0;
203 gen_parms->single_dual_band = 0;
204 gen_parms->tx_bip_fem_autodetect = 1;
205 gen_parms->tx_bip_fem_manufacturer = 1;
206 gen_parms->settings = 1;
207
208 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
209 if (ret < 0) {
210 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
211 return ret;
212 }
213
214 kfree(gen_parms);
215 return 0;
216}
217
218static int wl1271_init_radio_parms(struct wl1271 *wl)
219{
220 /*
221 * FIXME: All these magic numbers should be moved to some place where
222 * they can be configured (separate file?)
223 */
224
225 struct wl1271_radio_parms *radio_parms;
226 int ret;
227 u8 compensation[] = { 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8, 0xfc, 0x00,
228 0x08, 0x10, 0xf0, 0xf8, 0x00, 0x0a, 0x14 };
229
230 u8 tx_rate_limits_normal[] = { 0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 };
231 u8 tx_rate_limits_degraded[] = { 0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 };
232
233 u8 tx_channel_limits_11b[] = { 0x22, 0x50, 0x50, 0x50,
234 0x50, 0x50, 0x50, 0x50,
235 0x50, 0x50, 0x22, 0x50,
236 0x22, 0x50 };
237
238 u8 tx_channel_limits_ofdm[] = { 0x20, 0x50, 0x50, 0x50,
239 0x50, 0x50, 0x50, 0x50,
240 0x50, 0x50, 0x20, 0x50,
241 0x20, 0x50 };
242
243 u8 tx_pdv_rate_offsets[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
244
245 u8 tx_ibias[] = { 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 };
246
247 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
248 if (!radio_parms)
249 return -ENOMEM;
250
251 radio_parms->id = TEST_CMD_INI_FILE_RADIO_PARAM;
252
253 /* Static radio parameters */
254 radio_parms->rx_trace_loss = 10;
255 radio_parms->tx_trace_loss = 10;
256 memcpy(radio_parms->rx_rssi_and_proc_compens, compensation,
257 sizeof(compensation));
258
259 /* We don't set the 5GHz -- N/A */
260
261 /* Dynamic radio parameters */
262 radio_parms->tx_ref_pd_voltage = cpu_to_le16(0x24e);
263 radio_parms->tx_ref_power = 0x78;
264 radio_parms->tx_offset_db = 0x0;
265
266 memcpy(radio_parms->tx_rate_limits_normal, tx_rate_limits_normal,
267 sizeof(tx_rate_limits_normal));
268 memcpy(radio_parms->tx_rate_limits_degraded, tx_rate_limits_degraded,
269 sizeof(tx_rate_limits_degraded));
270
271 memcpy(radio_parms->tx_channel_limits_11b, tx_channel_limits_11b,
272 sizeof(tx_channel_limits_11b));
273 memcpy(radio_parms->tx_channel_limits_ofdm, tx_channel_limits_ofdm,
274 sizeof(tx_channel_limits_ofdm));
275 memcpy(radio_parms->tx_pdv_rate_offsets, tx_pdv_rate_offsets,
276 sizeof(tx_pdv_rate_offsets));
277 memcpy(radio_parms->tx_ibias, tx_ibias,
278 sizeof(tx_ibias));
279
280 radio_parms->rx_fem_insertion_loss = 0x14;
281
282 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
283 if (ret < 0)
284 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
285
286 kfree(radio_parms);
287 return ret;
288}
289
290int wl1271_hw_init(struct wl1271 *wl)
291{
292 int ret;
293
294 ret = wl1271_init_general_parms(wl);
295 if (ret < 0)
296 return ret;
297
298 ret = wl1271_init_radio_parms(wl);
299 if (ret < 0)
300 return ret;
301
302 /* Template settings */
303 ret = wl1271_init_templates_config(wl);
304 if (ret < 0)
305 return ret;
306
307 /* Default memory configuration */
308 ret = wl1271_acx_init_mem_config(wl);
309 if (ret < 0)
310 return ret;
311
312 /* RX config */
313 ret = wl1271_init_rx_config(wl,
314 RX_CFG_PROMISCUOUS | RX_CFG_TSF,
315 RX_FILTER_OPTION_DEF);
316 /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
317 RX_FILTER_OPTION_FILTER_ALL); */
318 if (ret < 0)
319 goto out_free_memmap;
320
321 /* PHY layer config */
322 ret = wl1271_init_phy_config(wl);
323 if (ret < 0)
324 goto out_free_memmap;
325
326 /* Beacon filtering */
327 ret = wl1271_init_beacon_filter(wl);
328 if (ret < 0)
329 goto out_free_memmap;
330
331 /* Configure TX patch complete interrupt behavior */
332 ret = wl1271_acx_tx_config_options(wl);
333 if (ret < 0)
334 goto out_free_memmap;
335
336 /* RX complete interrupt pacing */
337 ret = wl1271_acx_init_rx_interrupt(wl);
338 if (ret < 0)
339 goto out_free_memmap;
340
341 /* Bluetooth WLAN coexistence */
342 ret = wl1271_init_pta(wl);
343 if (ret < 0)
344 goto out_free_memmap;
345
346 /* Energy detection */
347 ret = wl1271_init_energy_detection(wl);
348 if (ret < 0)
349 goto out_free_memmap;
350
351 /* Beacons and boradcast settings */
352 ret = wl1271_init_beacon_broadcast(wl);
353 if (ret < 0)
354 goto out_free_memmap;
355
356 /* Default fragmentation threshold */
357 ret = wl1271_acx_frag_threshold(wl);
358 if (ret < 0)
359 goto out_free_memmap;
360
361 /* Default TID configuration */
362 ret = wl1271_acx_tid_cfg(wl);
363 if (ret < 0)
364 goto out_free_memmap;
365
366 /* Default AC configuration */
367 ret = wl1271_acx_ac_cfg(wl);
368 if (ret < 0)
369 goto out_free_memmap;
370
371 /* Configure TX rate classes */
372 ret = wl1271_acx_rate_policies(wl);
373 if (ret < 0)
374 goto out_free_memmap;
375
376 /* Enable data path */
377 ret = wl1271_cmd_data_path(wl, wl->channel, 1);
378 if (ret < 0)
379 goto out_free_memmap;
380
381 /* Configure for ELP power saving */
382 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
383 if (ret < 0)
384 goto out_free_memmap;
385
386 /* Configure HW encryption */
387 ret = wl1271_init_hwenc_config(wl);
388 if (ret < 0)
389 goto out_free_memmap;
390
391 return 0;
392
393 out_free_memmap:
394 kfree(wl->target_mem_map);
395
396 return ret;
397}
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/wl1271_init.h
new file mode 100644
index 000000000000..bd8ff0fa2272
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_init.h
@@ -0,0 +1,115 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_INIT_H__
25#define __WL1271_INIT_H__
26
27#include "wl1271.h"
28
29int wl1271_hw_init_power_auth(struct wl1271 *wl);
30int wl1271_hw_init(struct wl1271 *wl);
31
32/* These are not really a TEST_CMD, but the ref driver uses them as such */
33#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
34#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
35
36struct wl1271_general_parms {
37 u8 id;
38 u8 padding[3];
39
40 u8 ref_clk;
41 u8 settling_time;
42 u8 clk_valid_on_wakeup;
43 u8 dc2dcmode;
44 u8 single_dual_band;
45
46 u8 tx_bip_fem_autodetect;
47 u8 tx_bip_fem_manufacturer;
48 u8 settings;
49} __attribute__ ((packed));
50
51enum ref_clk_enum {
52 REF_CLK_19_2_E,
53 REF_CLK_26_E,
54 REF_CLK_38_4_E,
55 REF_CLK_52_E
56};
57
58#define RSSI_AND_PROCESS_COMPENSATION_SIZE 15
59#define NUMBER_OF_SUB_BANDS_5 7
60#define NUMBER_OF_RATE_GROUPS 6
61#define NUMBER_OF_CHANNELS_2_4 14
62#define NUMBER_OF_CHANNELS_5 35
63
64struct wl1271_radio_parms {
65 u8 id;
66 u8 padding[3];
67
68 /* Static radio parameters */
69 /* 2.4GHz */
70 u8 rx_trace_loss;
71 u8 tx_trace_loss;
72 s8 rx_rssi_and_proc_compens[RSSI_AND_PROCESS_COMPENSATION_SIZE];
73
74 /* 5GHz */
75 u8 rx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
76 u8 tx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
77 s8 rx_rssi_and_proc_compens_5[RSSI_AND_PROCESS_COMPENSATION_SIZE];
78
79 /* Dynamic radio parameters */
80 /* 2.4GHz */
81 s16 tx_ref_pd_voltage;
82 s8 tx_ref_power;
83 s8 tx_offset_db;
84
85 s8 tx_rate_limits_normal[NUMBER_OF_RATE_GROUPS];
86 s8 tx_rate_limits_degraded[NUMBER_OF_RATE_GROUPS];
87
88 s8 tx_channel_limits_11b[NUMBER_OF_CHANNELS_2_4];
89 s8 tx_channel_limits_ofdm[NUMBER_OF_CHANNELS_2_4];
90 s8 tx_pdv_rate_offsets[NUMBER_OF_RATE_GROUPS];
91
92 u8 tx_ibias[NUMBER_OF_RATE_GROUPS];
93 u8 rx_fem_insertion_loss;
94
95 u8 padding2;
96
97 /* 5GHz */
98 s16 tx_ref_pd_voltage_5[NUMBER_OF_SUB_BANDS_5];
99 s8 tx_ref_power_5[NUMBER_OF_SUB_BANDS_5];
100 s8 tx_offset_db_5[NUMBER_OF_SUB_BANDS_5];
101
102 s8 tx_rate_limits_normal_5[NUMBER_OF_RATE_GROUPS];
103 s8 tx_rate_limits_degraded_5[NUMBER_OF_RATE_GROUPS];
104
105 s8 tx_channel_limits_ofdm_5[NUMBER_OF_CHANNELS_5];
106 s8 tx_pdv_rate_offsets_5[NUMBER_OF_RATE_GROUPS];
107
108 /* FIXME: this is inconsistent with the types for 2.4GHz */
109 s8 tx_ibias_5[NUMBER_OF_RATE_GROUPS];
110 s8 rx_fem_insertion_loss_5[NUMBER_OF_SUB_BANDS_5];
111
112 u8 padding3[2];
113} __attribute__ ((packed));
114
115#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
new file mode 100644
index 000000000000..3bb45ced99ab
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -0,0 +1,1396 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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/platform_device.h>
26#include <linux/interrupt.h>
27#include <linux/firmware.h>
28#include <linux/delay.h>
29#include <linux/irq.h>
30#include <linux/spi/spi.h>
31#include <linux/crc32.h>
32#include <linux/etherdevice.h>
33#include <linux/spi/wl12xx.h>
34
35#include "wl1271.h"
36#include "wl12xx_80211.h"
37#include "wl1271_reg.h"
38#include "wl1271_spi.h"
39#include "wl1271_event.h"
40#include "wl1271_tx.h"
41#include "wl1271_rx.h"
42#include "wl1271_ps.h"
43#include "wl1271_init.h"
44#include "wl1271_debugfs.h"
45#include "wl1271_cmd.h"
46#include "wl1271_boot.h"
47
48static int wl1271_plt_init(struct wl1271 *wl)
49{
50 int ret;
51
52 ret = wl1271_acx_init_mem_config(wl);
53 if (ret < 0)
54 return ret;
55
56 ret = wl1271_cmd_data_path(wl, wl->channel, 1);
57 if (ret < 0)
58 return ret;
59
60 return 0;
61}
62
63static void wl1271_disable_interrupts(struct wl1271 *wl)
64{
65 disable_irq(wl->irq);
66}
67
68static void wl1271_power_off(struct wl1271 *wl)
69{
70 wl->set_power(false);
71}
72
73static void wl1271_power_on(struct wl1271 *wl)
74{
75 wl->set_power(true);
76}
77
78static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status)
79{
80 u32 total = 0;
81 int i;
82
83 /*
84 * FIXME: Reading the FW status directly from the registers seems to
85 * be the right thing to do, but it doesn't work. And in the
86 * reference driver, there is a workaround called
87 * USE_SDIO_24M_WORKAROUND, which reads the status from memory
88 * instead, so we do the same here.
89 */
90
91 wl1271_spi_mem_read(wl, STATUS_MEM_ADDRESS, status, sizeof(*status));
92
93 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
94 "drv_rx_counter = %d, tx_results_counter = %d)",
95 status->intr,
96 status->fw_rx_counter,
97 status->drv_rx_counter,
98 status->tx_results_counter);
99
100 /* update number of available TX blocks */
101 for (i = 0; i < NUM_TX_QUEUES; i++) {
102 u32 cnt = status->tx_released_blks[i] - wl->tx_blocks_freed[i];
103 wl->tx_blocks_freed[i] = status->tx_released_blks[i];
104 wl->tx_blocks_available += cnt;
105 total += cnt;
106 }
107
108 /* if more blocks are available now, schedule some tx work */
109 if (total && !skb_queue_empty(&wl->tx_queue))
110 schedule_work(&wl->tx_work);
111
112 /* update the host-chipset time offset */
113 wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime;
114}
115
116#define WL1271_IRQ_MAX_LOOPS 10
117static void wl1271_irq_work(struct work_struct *work)
118{
119 u32 intr, ctr = WL1271_IRQ_MAX_LOOPS;
120 int ret;
121 struct wl1271 *wl =
122 container_of(work, struct wl1271, irq_work);
123
124 mutex_lock(&wl->mutex);
125
126 wl1271_debug(DEBUG_IRQ, "IRQ work");
127
128 if (wl->state == WL1271_STATE_OFF)
129 goto out;
130
131 ret = wl1271_ps_elp_wakeup(wl, true);
132 if (ret < 0)
133 goto out;
134
135 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
136
137 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
138 if (!intr) {
139 wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
140 goto out_sleep;
141 }
142
143 intr &= WL1271_INTR_MASK;
144
145 do {
146 wl1271_fw_status(wl, wl->fw_status);
147
148
149 if (intr & (WL1271_ACX_INTR_EVENT_A |
150 WL1271_ACX_INTR_EVENT_B)) {
151 wl1271_debug(DEBUG_IRQ,
152 "WL1271_ACX_INTR_EVENT (0x%x)", intr);
153 if (intr & WL1271_ACX_INTR_EVENT_A)
154 wl1271_event_handle(wl, 0);
155 else
156 wl1271_event_handle(wl, 1);
157 }
158
159 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
160 wl1271_debug(DEBUG_IRQ,
161 "WL1271_ACX_INTR_INIT_COMPLETE");
162
163 if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
164 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
165
166 if (intr & WL1271_ACX_INTR_DATA) {
167 u8 tx_res_cnt = wl->fw_status->tx_results_counter -
168 wl->tx_results_count;
169
170 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
171
172 /* check for tx results */
173 if (tx_res_cnt)
174 wl1271_tx_complete(wl, tx_res_cnt);
175
176 wl1271_rx(wl, wl->fw_status);
177 }
178
179 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
180 intr &= WL1271_INTR_MASK;
181 } while (intr && --ctr);
182
183out_sleep:
184 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(WL1271_INTR_MASK));
185 wl1271_ps_elp_sleep(wl);
186
187out:
188 mutex_unlock(&wl->mutex);
189}
190
191static irqreturn_t wl1271_irq(int irq, void *cookie)
192{
193 struct wl1271 *wl;
194 unsigned long flags;
195
196 wl1271_debug(DEBUG_IRQ, "IRQ");
197
198 wl = cookie;
199
200 /* complete the ELP completion */
201 spin_lock_irqsave(&wl->wl_lock, flags);
202 if (wl->elp_compl) {
203 complete(wl->elp_compl);
204 wl->elp_compl = NULL;
205 }
206
207 schedule_work(&wl->irq_work);
208 spin_unlock_irqrestore(&wl->wl_lock, flags);
209
210 return IRQ_HANDLED;
211}
212
213static int wl1271_fetch_firmware(struct wl1271 *wl)
214{
215 const struct firmware *fw;
216 int ret;
217
218 ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev);
219
220 if (ret < 0) {
221 wl1271_error("could not get firmware: %d", ret);
222 return ret;
223 }
224
225 if (fw->size % 4) {
226 wl1271_error("firmware size is not multiple of 32 bits: %zu",
227 fw->size);
228 ret = -EILSEQ;
229 goto out;
230 }
231
232 wl->fw_len = fw->size;
233 wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
234
235 if (!wl->fw) {
236 wl1271_error("could not allocate memory for the firmware");
237 ret = -ENOMEM;
238 goto out;
239 }
240
241 memcpy(wl->fw, fw->data, wl->fw_len);
242
243 ret = 0;
244
245out:
246 release_firmware(fw);
247
248 return ret;
249}
250
251static int wl1271_fetch_nvs(struct wl1271 *wl)
252{
253 const struct firmware *fw;
254 int ret;
255
256 ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev);
257
258 if (ret < 0) {
259 wl1271_error("could not get nvs file: %d", ret);
260 return ret;
261 }
262
263 if (fw->size % 4) {
264 wl1271_error("nvs size is not multiple of 32 bits: %zu",
265 fw->size);
266 ret = -EILSEQ;
267 goto out;
268 }
269
270 wl->nvs_len = fw->size;
271 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
272
273 if (!wl->nvs) {
274 wl1271_error("could not allocate memory for the nvs file");
275 ret = -ENOMEM;
276 goto out;
277 }
278
279 memcpy(wl->nvs, fw->data, wl->nvs_len);
280
281 ret = 0;
282
283out:
284 release_firmware(fw);
285
286 return ret;
287}
288
289static void wl1271_fw_wakeup(struct wl1271 *wl)
290{
291 u32 elp_reg;
292
293 elp_reg = ELPCTRL_WAKE_UP;
294 wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
295}
296
297static int wl1271_setup(struct wl1271 *wl)
298{
299 wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
300 if (!wl->fw_status)
301 return -ENOMEM;
302
303 wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
304 if (!wl->tx_res_if) {
305 kfree(wl->fw_status);
306 return -ENOMEM;
307 }
308
309 INIT_WORK(&wl->irq_work, wl1271_irq_work);
310 INIT_WORK(&wl->tx_work, wl1271_tx_work);
311 return 0;
312}
313
314static int wl1271_chip_wakeup(struct wl1271 *wl)
315{
316 int ret = 0;
317
318 wl1271_power_on(wl);
319 msleep(WL1271_POWER_ON_SLEEP);
320 wl1271_spi_reset(wl);
321 wl1271_spi_init(wl);
322
323 /* We don't need a real memory partition here, because we only want
324 * to use the registers at this point. */
325 wl1271_set_partition(wl,
326 0x00000000,
327 0x00000000,
328 REGISTERS_BASE,
329 REGISTERS_DOWN_SIZE);
330
331 /* ELP module wake up */
332 wl1271_fw_wakeup(wl);
333
334 /* whal_FwCtrl_BootSm() */
335
336 /* 0. read chip id from CHIP_ID */
337 wl->chip.id = wl1271_reg_read32(wl, CHIP_ID_B);
338
339 /* 1. check if chip id is valid */
340
341 switch (wl->chip.id) {
342 case CHIP_ID_1271_PG10:
343 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
344 wl->chip.id);
345
346 ret = wl1271_setup(wl);
347 if (ret < 0)
348 goto out;
349 break;
350 case CHIP_ID_1271_PG20:
351 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
352 wl->chip.id);
353
354 ret = wl1271_setup(wl);
355 if (ret < 0)
356 goto out;
357 break;
358 default:
359 wl1271_error("unsupported chip id: 0x%x", wl->chip.id);
360 ret = -ENODEV;
361 goto out;
362 }
363
364 if (wl->fw == NULL) {
365 ret = wl1271_fetch_firmware(wl);
366 if (ret < 0)
367 goto out;
368 }
369
370 /* No NVS from netlink, try to get it from the filesystem */
371 if (wl->nvs == NULL) {
372 ret = wl1271_fetch_nvs(wl);
373 if (ret < 0)
374 goto out;
375 }
376
377out:
378 return ret;
379}
380
381static void wl1271_filter_work(struct work_struct *work)
382{
383 struct wl1271 *wl =
384 container_of(work, struct wl1271, filter_work);
385 int ret;
386
387 mutex_lock(&wl->mutex);
388
389 if (wl->state == WL1271_STATE_OFF)
390 goto out;
391
392 ret = wl1271_ps_elp_wakeup(wl, false);
393 if (ret < 0)
394 goto out;
395
396 /* FIXME: replace the magic numbers with proper definitions */
397 ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
398 if (ret < 0)
399 goto out_sleep;
400
401out_sleep:
402 wl1271_ps_elp_sleep(wl);
403
404out:
405 mutex_unlock(&wl->mutex);
406}
407
408int wl1271_plt_start(struct wl1271 *wl)
409{
410 int ret;
411
412 mutex_lock(&wl->mutex);
413
414 wl1271_notice("power up");
415
416 if (wl->state != WL1271_STATE_OFF) {
417 wl1271_error("cannot go into PLT state because not "
418 "in off state: %d", wl->state);
419 ret = -EBUSY;
420 goto out;
421 }
422
423 wl->state = WL1271_STATE_PLT;
424
425 ret = wl1271_chip_wakeup(wl);
426 if (ret < 0)
427 goto out;
428
429 ret = wl1271_boot(wl);
430 if (ret < 0)
431 goto out;
432
433 wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
434
435 ret = wl1271_plt_init(wl);
436 if (ret < 0)
437 goto out;
438
439out:
440 mutex_unlock(&wl->mutex);
441
442 return ret;
443}
444
445int wl1271_plt_stop(struct wl1271 *wl)
446{
447 int ret = 0;
448
449 mutex_lock(&wl->mutex);
450
451 wl1271_notice("power down");
452
453 if (wl->state != WL1271_STATE_PLT) {
454 wl1271_error("cannot power down because not in PLT "
455 "state: %d", wl->state);
456 ret = -EBUSY;
457 goto out;
458 }
459
460 wl1271_disable_interrupts(wl);
461 wl1271_power_off(wl);
462
463 wl->state = WL1271_STATE_OFF;
464
465out:
466 mutex_unlock(&wl->mutex);
467
468 return ret;
469}
470
471
472static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
473{
474 struct wl1271 *wl = hw->priv;
475
476 skb_queue_tail(&wl->tx_queue, skb);
477
478 /*
479 * The chip specific setup must run before the first TX packet -
480 * before that, the tx_work will not be initialized!
481 */
482
483 schedule_work(&wl->tx_work);
484
485 /*
486 * The workqueue is slow to process the tx_queue and we need stop
487 * the queue here, otherwise the queue will get too long.
488 */
489 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) {
490 ieee80211_stop_queues(wl->hw);
491
492 /*
493 * FIXME: this is racy, the variable is not properly
494 * protected. Maybe fix this by removing the stupid
495 * variable altogether and checking the real queue state?
496 */
497 wl->tx_queue_stopped = true;
498 }
499
500 return NETDEV_TX_OK;
501}
502
503static int wl1271_op_start(struct ieee80211_hw *hw)
504{
505 struct wl1271 *wl = hw->priv;
506 int ret = 0;
507
508 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
509
510 mutex_lock(&wl->mutex);
511
512 if (wl->state != WL1271_STATE_OFF) {
513 wl1271_error("cannot start because not in off state: %d",
514 wl->state);
515 ret = -EBUSY;
516 goto out;
517 }
518
519 ret = wl1271_chip_wakeup(wl);
520 if (ret < 0)
521 goto out;
522
523 ret = wl1271_boot(wl);
524 if (ret < 0)
525 goto out;
526
527 ret = wl1271_hw_init(wl);
528 if (ret < 0)
529 goto out;
530
531 wl->state = WL1271_STATE_ON;
532
533 wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
534
535out:
536 if (ret < 0)
537 wl1271_power_off(wl);
538
539 mutex_unlock(&wl->mutex);
540
541 return ret;
542}
543
544static void wl1271_op_stop(struct ieee80211_hw *hw)
545{
546 struct wl1271 *wl = hw->priv;
547 int i;
548
549 wl1271_info("down");
550
551 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
552
553 mutex_lock(&wl->mutex);
554
555 WARN_ON(wl->state != WL1271_STATE_ON);
556
557 if (wl->scanning) {
558 mutex_unlock(&wl->mutex);
559 ieee80211_scan_completed(wl->hw, true);
560 mutex_lock(&wl->mutex);
561 wl->scanning = false;
562 }
563
564 wl->state = WL1271_STATE_OFF;
565
566 wl1271_disable_interrupts(wl);
567
568 mutex_unlock(&wl->mutex);
569
570 cancel_work_sync(&wl->irq_work);
571 cancel_work_sync(&wl->tx_work);
572 cancel_work_sync(&wl->filter_work);
573
574 mutex_lock(&wl->mutex);
575
576 /* let's notify MAC80211 about the remaining pending TX frames */
577 wl1271_tx_flush(wl);
578 wl1271_power_off(wl);
579
580 memset(wl->bssid, 0, ETH_ALEN);
581 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
582 wl->ssid_len = 0;
583 wl->listen_int = 1;
584 wl->bss_type = MAX_BSS_TYPE;
585
586 wl->rx_counter = 0;
587 wl->elp = false;
588 wl->psm = 0;
589 wl->tx_queue_stopped = false;
590 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
591 wl->tx_blocks_available = 0;
592 wl->tx_results_count = 0;
593 wl->tx_packets_count = 0;
594 wl->time_offset = 0;
595 wl->session_counter = 0;
596 for (i = 0; i < NUM_TX_QUEUES; i++)
597 wl->tx_blocks_freed[i] = 0;
598
599 wl1271_debugfs_reset(wl);
600 mutex_unlock(&wl->mutex);
601}
602
603static int wl1271_op_add_interface(struct ieee80211_hw *hw,
604 struct ieee80211_if_init_conf *conf)
605{
606 struct wl1271 *wl = hw->priv;
607 DECLARE_MAC_BUF(mac);
608 int ret = 0;
609
610 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
611 conf->type, print_mac(mac, conf->mac_addr));
612
613 mutex_lock(&wl->mutex);
614
615 switch (conf->type) {
616 case NL80211_IFTYPE_STATION:
617 wl->bss_type = BSS_TYPE_STA_BSS;
618 break;
619 case NL80211_IFTYPE_ADHOC:
620 wl->bss_type = BSS_TYPE_IBSS;
621 break;
622 default:
623 ret = -EOPNOTSUPP;
624 goto out;
625 }
626
627 /* FIXME: what if conf->mac_addr changes? */
628
629out:
630 mutex_unlock(&wl->mutex);
631 return ret;
632}
633
634static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
635 struct ieee80211_if_init_conf *conf)
636{
637 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
638}
639
640#if 0
641static int wl1271_op_config_interface(struct ieee80211_hw *hw,
642 struct ieee80211_vif *vif,
643 struct ieee80211_if_conf *conf)
644{
645 struct wl1271 *wl = hw->priv;
646 struct sk_buff *beacon;
647 DECLARE_MAC_BUF(mac);
648 int ret;
649
650 wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %s",
651 print_mac(mac, conf->bssid));
652 wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
653 conf->ssid_len);
654
655 mutex_lock(&wl->mutex);
656
657 ret = wl1271_ps_elp_wakeup(wl, false);
658 if (ret < 0)
659 goto out;
660
661 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
662
663 ret = wl1271_cmd_build_null_data(wl);
664 if (ret < 0)
665 goto out_sleep;
666
667 wl->ssid_len = conf->ssid_len;
668 if (wl->ssid_len)
669 memcpy(wl->ssid, conf->ssid, wl->ssid_len);
670
671 if (wl->bss_type != BSS_TYPE_IBSS) {
672 /* FIXME: replace the magic numbers with proper definitions */
673 ret = wl1271_cmd_join(wl, wl->bss_type, 5, 100, 1);
674 if (ret < 0)
675 goto out_sleep;
676 }
677
678 if (conf->changed & IEEE80211_IFCC_BEACON) {
679 beacon = ieee80211_beacon_get(hw, vif);
680 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
681 beacon->data, beacon->len);
682
683 if (ret < 0) {
684 dev_kfree_skb(beacon);
685 goto out_sleep;
686 }
687
688 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
689 beacon->data, beacon->len);
690
691 dev_kfree_skb(beacon);
692
693 if (ret < 0)
694 goto out_sleep;
695
696 /* FIXME: replace the magic numbers with proper definitions */
697 ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
698
699 if (ret < 0)
700 goto out_sleep;
701 }
702
703out_sleep:
704 wl1271_ps_elp_sleep(wl);
705
706out:
707 mutex_unlock(&wl->mutex);
708
709 return ret;
710}
711#endif
712
713static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
714{
715 struct wl1271 *wl = hw->priv;
716 struct ieee80211_conf *conf = &hw->conf;
717 int channel, ret = 0;
718
719 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
720
721 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
722 channel,
723 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
724 conf->power_level);
725
726 mutex_lock(&wl->mutex);
727
728 ret = wl1271_ps_elp_wakeup(wl, false);
729 if (ret < 0)
730 goto out;
731
732 if (channel != wl->channel) {
733 u8 old_channel = wl->channel;
734 wl->channel = channel;
735
736 /* FIXME: use beacon interval provided by mac80211 */
737 ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
738 if (ret < 0) {
739 wl->channel = old_channel;
740 goto out_sleep;
741 }
742 }
743
744 ret = wl1271_cmd_build_null_data(wl);
745 if (ret < 0)
746 goto out_sleep;
747
748 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
749 wl1271_info("psm enabled");
750
751 wl->psm_requested = true;
752
753 /*
754 * We enter PSM only if we're already associated.
755 * If we're not, we'll enter it when joining an SSID,
756 * through the bss_info_changed() hook.
757 */
758 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
759 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
760 wl->psm_requested) {
761 wl1271_info("psm disabled");
762
763 wl->psm_requested = false;
764
765 if (wl->psm)
766 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
767 }
768
769 if (conf->power_level != wl->power_level) {
770 ret = wl1271_acx_tx_power(wl, conf->power_level);
771 if (ret < 0)
772 goto out;
773
774 wl->power_level = conf->power_level;
775 }
776
777out_sleep:
778 wl1271_ps_elp_sleep(wl);
779
780out:
781 mutex_unlock(&wl->mutex);
782
783 return ret;
784}
785
786#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
787 FIF_ALLMULTI | \
788 FIF_FCSFAIL | \
789 FIF_BCN_PRBRESP_PROMISC | \
790 FIF_CONTROL | \
791 FIF_OTHER_BSS)
792
793static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
794 unsigned int changed,
795 unsigned int *total,
796 int mc_count,
797 struct dev_addr_list *mc_list)
798{
799 struct wl1271 *wl = hw->priv;
800
801 wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter");
802
803 *total &= WL1271_SUPPORTED_FILTERS;
804 changed &= WL1271_SUPPORTED_FILTERS;
805
806 if (changed == 0)
807 return;
808
809 /* FIXME: wl->rx_config and wl->rx_filter are not protected */
810 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
811 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
812
813 /*
814 * FIXME: workqueues need to be properly cancelled on stop(), for
815 * now let's just disable changing the filter settings. They will
816 * be updated any on config().
817 */
818 /* schedule_work(&wl->filter_work); */
819}
820
821static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
822 struct ieee80211_vif *vif,
823 struct ieee80211_sta *sta,
824 struct ieee80211_key_conf *key_conf)
825{
826 struct wl1271 *wl = hw->priv;
827 const u8 *addr;
828 int ret;
829 u8 key_type;
830
831 static const u8 bcast_addr[ETH_ALEN] =
832 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
833
834 wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
835
836 addr = sta ? sta->addr : bcast_addr;
837
838 wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
839 wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
840 wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
841 key_conf->alg, key_conf->keyidx,
842 key_conf->keylen, key_conf->flags);
843 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
844
845 if (is_zero_ether_addr(addr)) {
846 /* We dont support TX only encryption */
847 ret = -EOPNOTSUPP;
848 goto out;
849 }
850
851 mutex_lock(&wl->mutex);
852
853 ret = wl1271_ps_elp_wakeup(wl, false);
854 if (ret < 0)
855 goto out_unlock;
856
857 switch (key_conf->alg) {
858 case ALG_WEP:
859 key_type = KEY_WEP;
860
861 key_conf->hw_key_idx = key_conf->keyidx;
862 break;
863 case ALG_TKIP:
864 key_type = KEY_TKIP;
865
866 key_conf->hw_key_idx = key_conf->keyidx;
867 break;
868 case ALG_CCMP:
869 key_type = KEY_AES;
870
871 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
872 break;
873 default:
874 wl1271_error("Unknown key algo 0x%x", key_conf->alg);
875
876 ret = -EOPNOTSUPP;
877 goto out_sleep;
878 }
879
880 switch (cmd) {
881 case SET_KEY:
882 ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE,
883 key_conf->keyidx, key_type,
884 key_conf->keylen, key_conf->key,
885 addr);
886 if (ret < 0) {
887 wl1271_error("Could not add or replace key");
888 goto out_sleep;
889 }
890 break;
891
892 case DISABLE_KEY:
893 ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
894 key_conf->keyidx, key_type,
895 key_conf->keylen, key_conf->key,
896 addr);
897 if (ret < 0) {
898 wl1271_error("Could not remove key");
899 goto out_sleep;
900 }
901 break;
902
903 default:
904 wl1271_error("Unsupported key cmd 0x%x", cmd);
905 ret = -EOPNOTSUPP;
906 goto out_sleep;
907
908 break;
909 }
910
911out_sleep:
912 wl1271_ps_elp_sleep(wl);
913
914out_unlock:
915 mutex_unlock(&wl->mutex);
916
917out:
918 return ret;
919}
920
921static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
922 struct cfg80211_scan_request *req)
923{
924 struct wl1271 *wl = hw->priv;
925 int ret;
926 u8 *ssid = NULL;
927 size_t ssid_len = 0;
928
929 wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");
930
931 if (req->n_ssids) {
932 ssid = req->ssids[0].ssid;
933 ssid_len = req->ssids[0].ssid_len;
934 }
935
936 mutex_lock(&wl->mutex);
937
938 ret = wl1271_ps_elp_wakeup(wl, false);
939 if (ret < 0)
940 goto out;
941
942 ret = wl1271_cmd_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
943
944 wl1271_ps_elp_sleep(wl);
945
946out:
947 mutex_unlock(&wl->mutex);
948
949 return ret;
950}
951
952static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
953{
954 struct wl1271 *wl = hw->priv;
955 int ret;
956
957 mutex_lock(&wl->mutex);
958
959 ret = wl1271_ps_elp_wakeup(wl, false);
960 if (ret < 0)
961 goto out;
962
963 ret = wl1271_acx_rts_threshold(wl, (u16) value);
964 if (ret < 0)
965 wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
966
967 wl1271_ps_elp_sleep(wl);
968
969out:
970 mutex_unlock(&wl->mutex);
971
972 return ret;
973}
974
975static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
976 struct ieee80211_vif *vif,
977 struct ieee80211_bss_conf *bss_conf,
978 u32 changed)
979{
980 enum wl1271_cmd_ps_mode mode;
981 struct wl1271 *wl = hw->priv;
982 int ret;
983
984 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
985
986 mutex_lock(&wl->mutex);
987
988 ret = wl1271_ps_elp_wakeup(wl, false);
989 if (ret < 0)
990 goto out;
991
992 if (changed & BSS_CHANGED_ASSOC) {
993 if (bss_conf->assoc) {
994 wl->aid = bss_conf->aid;
995
996 ret = wl1271_cmd_build_ps_poll(wl, wl->aid);
997 if (ret < 0)
998 goto out_sleep;
999
1000 ret = wl1271_acx_aid(wl, wl->aid);
1001 if (ret < 0)
1002 goto out_sleep;
1003
1004 /* If we want to go in PSM but we're not there yet */
1005 if (wl->psm_requested && !wl->psm) {
1006 mode = STATION_POWER_SAVE_MODE;
1007 ret = wl1271_ps_set_mode(wl, mode);
1008 if (ret < 0)
1009 goto out_sleep;
1010 }
1011 }
1012 }
1013 if (changed & BSS_CHANGED_ERP_SLOT) {
1014 if (bss_conf->use_short_slot)
1015 ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT);
1016 else
1017 ret = wl1271_acx_slot(wl, SLOT_TIME_LONG);
1018 if (ret < 0) {
1019 wl1271_warning("Set slot time failed %d", ret);
1020 goto out_sleep;
1021 }
1022 }
1023
1024 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1025 if (bss_conf->use_short_preamble)
1026 wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
1027 else
1028 wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
1029 }
1030
1031 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1032 if (bss_conf->use_cts_prot)
1033 ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE);
1034 else
1035 ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE);
1036 if (ret < 0) {
1037 wl1271_warning("Set ctsprotect failed %d", ret);
1038 goto out_sleep;
1039 }
1040 }
1041
1042out_sleep:
1043 wl1271_ps_elp_sleep(wl);
1044
1045out:
1046 mutex_unlock(&wl->mutex);
1047}
1048
1049
1050/* can't be const, mac80211 writes to this */
1051static struct ieee80211_rate wl1271_rates[] = {
1052 { .bitrate = 10,
1053 .hw_value = 0x1,
1054 .hw_value_short = 0x1, },
1055 { .bitrate = 20,
1056 .hw_value = 0x2,
1057 .hw_value_short = 0x2,
1058 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1059 { .bitrate = 55,
1060 .hw_value = 0x4,
1061 .hw_value_short = 0x4,
1062 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1063 { .bitrate = 110,
1064 .hw_value = 0x20,
1065 .hw_value_short = 0x20,
1066 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1067 { .bitrate = 60,
1068 .hw_value = 0x8,
1069 .hw_value_short = 0x8, },
1070 { .bitrate = 90,
1071 .hw_value = 0x10,
1072 .hw_value_short = 0x10, },
1073 { .bitrate = 120,
1074 .hw_value = 0x40,
1075 .hw_value_short = 0x40, },
1076 { .bitrate = 180,
1077 .hw_value = 0x80,
1078 .hw_value_short = 0x80, },
1079 { .bitrate = 240,
1080 .hw_value = 0x200,
1081 .hw_value_short = 0x200, },
1082 { .bitrate = 360,
1083 .hw_value = 0x400,
1084 .hw_value_short = 0x400, },
1085 { .bitrate = 480,
1086 .hw_value = 0x800,
1087 .hw_value_short = 0x800, },
1088 { .bitrate = 540,
1089 .hw_value = 0x1000,
1090 .hw_value_short = 0x1000, },
1091};
1092
1093/* can't be const, mac80211 writes to this */
1094static struct ieee80211_channel wl1271_channels[] = {
1095 { .hw_value = 1, .center_freq = 2412},
1096 { .hw_value = 2, .center_freq = 2417},
1097 { .hw_value = 3, .center_freq = 2422},
1098 { .hw_value = 4, .center_freq = 2427},
1099 { .hw_value = 5, .center_freq = 2432},
1100 { .hw_value = 6, .center_freq = 2437},
1101 { .hw_value = 7, .center_freq = 2442},
1102 { .hw_value = 8, .center_freq = 2447},
1103 { .hw_value = 9, .center_freq = 2452},
1104 { .hw_value = 10, .center_freq = 2457},
1105 { .hw_value = 11, .center_freq = 2462},
1106 { .hw_value = 12, .center_freq = 2467},
1107 { .hw_value = 13, .center_freq = 2472},
1108};
1109
1110/* can't be const, mac80211 writes to this */
1111static struct ieee80211_supported_band wl1271_band_2ghz = {
1112 .channels = wl1271_channels,
1113 .n_channels = ARRAY_SIZE(wl1271_channels),
1114 .bitrates = wl1271_rates,
1115 .n_bitrates = ARRAY_SIZE(wl1271_rates),
1116};
1117
1118static const struct ieee80211_ops wl1271_ops = {
1119 .start = wl1271_op_start,
1120 .stop = wl1271_op_stop,
1121 .add_interface = wl1271_op_add_interface,
1122 .remove_interface = wl1271_op_remove_interface,
1123 .config = wl1271_op_config,
1124/* .config_interface = wl1271_op_config_interface, */
1125 .configure_filter = wl1271_op_configure_filter,
1126 .tx = wl1271_op_tx,
1127 .set_key = wl1271_op_set_key,
1128 .hw_scan = wl1271_op_hw_scan,
1129 .bss_info_changed = wl1271_op_bss_info_changed,
1130 .set_rts_threshold = wl1271_op_set_rts_threshold,
1131};
1132
1133static int wl1271_register_hw(struct wl1271 *wl)
1134{
1135 int ret;
1136
1137 if (wl->mac80211_registered)
1138 return 0;
1139
1140 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
1141
1142 ret = ieee80211_register_hw(wl->hw);
1143 if (ret < 0) {
1144 wl1271_error("unable to register mac80211 hw: %d", ret);
1145 return ret;
1146 }
1147
1148 wl->mac80211_registered = true;
1149
1150 wl1271_notice("loaded");
1151
1152 return 0;
1153}
1154
1155static int wl1271_init_ieee80211(struct wl1271 *wl)
1156{
1157 /*
1158 * The tx descriptor buffer and the TKIP space.
1159 *
1160 * FIXME: add correct 1271 descriptor size
1161 */
1162 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE;
1163
1164 /* unit us */
1165 /* FIXME: find a proper value */
1166 wl->hw->channel_change_time = 10000;
1167
1168 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1169 IEEE80211_HW_NOISE_DBM;
1170
1171 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1172 wl->hw->wiphy->max_scan_ssids = 1;
1173 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
1174
1175 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
1176
1177 return 0;
1178}
1179
1180static void wl1271_device_release(struct device *dev)
1181{
1182
1183}
1184
1185static struct platform_device wl1271_device = {
1186 .name = "wl1271",
1187 .id = -1,
1188
1189 /* device model insists to have a release function */
1190 .dev = {
1191 .release = wl1271_device_release,
1192 },
1193};
1194
1195#define WL1271_DEFAULT_CHANNEL 0
1196static int __devinit wl1271_probe(struct spi_device *spi)
1197{
1198 struct wl12xx_platform_data *pdata;
1199 struct ieee80211_hw *hw;
1200 struct wl1271 *wl;
1201 int ret, i;
1202 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
1203
1204 pdata = spi->dev.platform_data;
1205 if (!pdata) {
1206 wl1271_error("no platform data");
1207 return -ENODEV;
1208 }
1209
1210 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
1211 if (!hw) {
1212 wl1271_error("could not alloc ieee80211_hw");
1213 return -ENOMEM;
1214 }
1215
1216 wl = hw->priv;
1217 memset(wl, 0, sizeof(*wl));
1218
1219 wl->hw = hw;
1220 dev_set_drvdata(&spi->dev, wl);
1221 wl->spi = spi;
1222
1223 skb_queue_head_init(&wl->tx_queue);
1224
1225 INIT_WORK(&wl->filter_work, wl1271_filter_work);
1226 wl->channel = WL1271_DEFAULT_CHANNEL;
1227 wl->scanning = false;
1228 wl->default_key = 0;
1229 wl->listen_int = 1;
1230 wl->rx_counter = 0;
1231 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1232 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1233 wl->elp = false;
1234 wl->psm = 0;
1235 wl->psm_requested = false;
1236 wl->tx_queue_stopped = false;
1237 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1238
1239 /* We use the default power on sleep time until we know which chip
1240 * we're using */
1241 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
1242 wl->tx_frames[i] = NULL;
1243
1244 spin_lock_init(&wl->wl_lock);
1245
1246 /*
1247 * In case our MAC address is not correctly set,
1248 * we use a random but Nokia MAC.
1249 */
1250 memcpy(wl->mac_addr, nokia_oui, 3);
1251 get_random_bytes(wl->mac_addr + 3, 3);
1252
1253 wl->state = WL1271_STATE_OFF;
1254 mutex_init(&wl->mutex);
1255
1256 wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
1257 if (!wl->rx_descriptor) {
1258 wl1271_error("could not allocate memory for rx descriptor");
1259 ret = -ENOMEM;
1260 goto out_free;
1261 }
1262
1263 /* This is the only SPI value that we need to set here, the rest
1264 * comes from the board-peripherals file */
1265 spi->bits_per_word = 32;
1266
1267 ret = spi_setup(spi);
1268 if (ret < 0) {
1269 wl1271_error("spi_setup failed");
1270 goto out_free;
1271 }
1272
1273 wl->set_power = pdata->set_power;
1274 if (!wl->set_power) {
1275 wl1271_error("set power function missing in platform data");
1276 ret = -ENODEV;
1277 goto out_free;
1278 }
1279
1280 wl->irq = spi->irq;
1281 if (wl->irq < 0) {
1282 wl1271_error("irq missing in platform data");
1283 ret = -ENODEV;
1284 goto out_free;
1285 }
1286
1287 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
1288 if (ret < 0) {
1289 wl1271_error("request_irq() failed: %d", ret);
1290 goto out_free;
1291 }
1292
1293 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
1294
1295 disable_irq(wl->irq);
1296
1297 ret = platform_device_register(&wl1271_device);
1298 if (ret) {
1299 wl1271_error("couldn't register platform device");
1300 goto out_irq;
1301 }
1302 dev_set_drvdata(&wl1271_device.dev, wl);
1303
1304 ret = wl1271_init_ieee80211(wl);
1305 if (ret)
1306 goto out_platform;
1307
1308 ret = wl1271_register_hw(wl);
1309 if (ret)
1310 goto out_platform;
1311
1312 wl1271_debugfs_init(wl);
1313
1314 wl1271_notice("initialized");
1315
1316 return 0;
1317
1318 out_platform:
1319 platform_device_unregister(&wl1271_device);
1320
1321 out_irq:
1322 free_irq(wl->irq, wl);
1323
1324 out_free:
1325 kfree(wl->rx_descriptor);
1326 wl->rx_descriptor = NULL;
1327
1328 ieee80211_free_hw(hw);
1329
1330 return ret;
1331}
1332
1333static int __devexit wl1271_remove(struct spi_device *spi)
1334{
1335 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
1336
1337 ieee80211_unregister_hw(wl->hw);
1338
1339 wl1271_debugfs_exit(wl);
1340 platform_device_unregister(&wl1271_device);
1341 free_irq(wl->irq, wl);
1342 kfree(wl->target_mem_map);
1343 kfree(wl->fw);
1344 wl->fw = NULL;
1345 kfree(wl->nvs);
1346 wl->nvs = NULL;
1347
1348 kfree(wl->rx_descriptor);
1349 wl->rx_descriptor = NULL;
1350
1351 kfree(wl->fw_status);
1352 kfree(wl->tx_res_if);
1353
1354 ieee80211_free_hw(wl->hw);
1355
1356 return 0;
1357}
1358
1359
1360static struct spi_driver wl1271_spi_driver = {
1361 .driver = {
1362 .name = "wl1271",
1363 .bus = &spi_bus_type,
1364 .owner = THIS_MODULE,
1365 },
1366
1367 .probe = wl1271_probe,
1368 .remove = __devexit_p(wl1271_remove),
1369};
1370
1371static int __init wl1271_init(void)
1372{
1373 int ret;
1374
1375 ret = spi_register_driver(&wl1271_spi_driver);
1376 if (ret < 0) {
1377 wl1271_error("failed to register spi driver: %d", ret);
1378 goto out;
1379 }
1380
1381out:
1382 return ret;
1383}
1384
1385static void __exit wl1271_exit(void)
1386{
1387 spi_unregister_driver(&wl1271_spi_driver);
1388
1389 wl1271_notice("unloaded");
1390}
1391
1392module_init(wl1271_init);
1393module_exit(wl1271_exit);
1394
1395MODULE_LICENSE("GPL");
1396MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
new file mode 100644
index 000000000000..1dc74b0c7736
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -0,0 +1,142 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_reg.h"
25#include "wl1271_ps.h"
26#include "wl1271_spi.h"
27
28#define WL1271_WAKEUP_TIMEOUT 500
29
30/* Routines to toggle sleep mode while in ELP */
31void wl1271_ps_elp_sleep(struct wl1271 *wl)
32{
33 /*
34 * FIXME: due to a problem in the firmware (causing a firmware
35 * crash), ELP entry is prevented below. Remove the "true" to
36 * re-enable ELP entry.
37 */
38 if (true || wl->elp || !wl->psm)
39 return;
40
41 /*
42 * Go to ELP unless there is work already pending - pending work
43 * will immediately wakeup the chipset anyway.
44 */
45 if (!work_pending(&wl->irq_work) && !work_pending(&wl->tx_work)) {
46 wl1271_debug(DEBUG_PSM, "chip to elp");
47 wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
48 wl->elp = true;
49 }
50}
51
52int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
53{
54 DECLARE_COMPLETION_ONSTACK(compl);
55 unsigned long flags;
56 int ret;
57 u32 start_time = jiffies;
58 bool pending = false;
59
60 if (!wl->elp)
61 return 0;
62
63 wl1271_debug(DEBUG_PSM, "waking up chip from elp");
64
65 /*
66 * The spinlock is required here to synchronize both the work and
67 * the completion variable in one entity.
68 */
69 spin_lock_irqsave(&wl->wl_lock, flags);
70 if (work_pending(&wl->irq_work) || chip_awake)
71 pending = true;
72 else
73 wl->elp_compl = &compl;
74 spin_unlock_irqrestore(&wl->wl_lock, flags);
75
76 wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
77
78 if (!pending) {
79 ret = wait_for_completion_timeout(
80 &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
81 if (ret == 0) {
82 wl1271_error("ELP wakeup timeout!");
83 ret = -ETIMEDOUT;
84 goto err;
85 } else if (ret < 0) {
86 wl1271_error("ELP wakeup completion error.");
87 goto err;
88 }
89 }
90
91 wl->elp = false;
92
93 wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
94 jiffies_to_msecs(jiffies - start_time));
95 goto out;
96
97err:
98 spin_lock_irqsave(&wl->wl_lock, flags);
99 wl->elp_compl = NULL;
100 spin_unlock_irqrestore(&wl->wl_lock, flags);
101 return ret;
102
103out:
104 return 0;
105}
106
107int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
108{
109 int ret;
110
111 switch (mode) {
112 case STATION_POWER_SAVE_MODE:
113 wl1271_debug(DEBUG_PSM, "entering psm");
114 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
115 if (ret < 0)
116 return ret;
117
118 wl1271_ps_elp_sleep(wl);
119 if (ret < 0)
120 return ret;
121
122 wl->psm = 1;
123 break;
124 case STATION_ACTIVE_MODE:
125 default:
126 wl1271_debug(DEBUG_PSM, "leaving psm");
127 ret = wl1271_ps_elp_wakeup(wl, false);
128 if (ret < 0)
129 return ret;
130
131 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
132 if (ret < 0)
133 return ret;
134
135 wl->psm = 0;
136 break;
137 }
138
139 return ret;
140}
141
142
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
new file mode 100644
index 000000000000..de2bd3c7dc9c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -0,0 +1,35 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_PS_H__
25#define __WL1271_PS_H__
26
27#include "wl1271.h"
28#include "wl1271_acx.h"
29
30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode);
31void wl1271_ps_elp_sleep(struct wl1271 *wl);
32int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
33
34
35#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h
new file mode 100644
index 000000000000..f8ed4a4fc691
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_reg.h
@@ -0,0 +1,758 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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
30#define REGISTERS_BASE 0x00300000
31#define DRPW_BASE 0x00310000
32
33#define REGISTERS_DOWN_SIZE 0x00008800
34#define REGISTERS_WORK_SIZE 0x0000b000
35
36#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
37#define STATUS_MEM_ADDRESS 0x40400
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 Host Software Reset - 32bit RW
48 ------------------------------------------
49 [31:1] Reserved
50 0 SOFT_RESET Soft Reset - When this bit is set,
51 it holds the Wlan hardware in a soft reset state.
52 This reset disables all MAC and baseband processor
53 clocks except the CardBus/PCI interface clock.
54 It also initializes all MAC state machines except
55 the host interface. It does not reload the
56 contents of the EEPROM. When this bit is cleared
57 (not self-clearing), the Wlan hardware
58 exits the software reset state.
59===============================================*/
60#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000)
61
62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
65/*
66 * Interrupt registers.
67 * 64 bit interrupt sources registers ws ced.
68 * sme interupts were removed and new ones were added.
69 * Order was changed.
70 */
71#define FIQ_MASK (REGISTERS_BASE + 0x0400)
72#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
73#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
74#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
75#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
76#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
77#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
78#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
79#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
80#define IRQ_MASK (REGISTERS_BASE + 0x0418)
81#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
82#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
83#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
84#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
85#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
86#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
87#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
88#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
89#define ECPU_MASK (REGISTERS_BASE + 0x0448)
90#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
91#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
92#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
93#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
94#define INT_STS_ND (REGISTERS_BASE + 0x0464)
95#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
96#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
97#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
98#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
99#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
100#define INT_ACK (REGISTERS_BASE + 0x046C)
101#define INT_ACK_L (REGISTERS_BASE + 0x046C)
102#define INT_ACK_H (REGISTERS_BASE + 0x0470)
103#define INT_TRIG (REGISTERS_BASE + 0x0474)
104#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
105#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
106#define HOST_STS_L (REGISTERS_BASE + 0x045C)
107#define HOST_STS_H (REGISTERS_BASE + 0x0460)
108#define HOST_MASK (REGISTERS_BASE + 0x0430)
109#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
110#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
111#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
112#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
113#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
114#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
115#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
116#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
117
118#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
119#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
120
121/* Host Interrupts*/
122#define HINT_MASK (REGISTERS_BASE + 0x0494)
123#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
124#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
125#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
126/*1150 spec calls this HINT_STS_RAW*/
127#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
128#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
129#define HINT_ACK (REGISTERS_BASE + 0x04A8)
130#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
131
132/*=============================================
133 Host Interrupt Mask Register - 32bit (RW)
134 ------------------------------------------
135 Setting a bit in this register masks the
136 corresponding interrupt to the host.
137 0 - RX0 - Rx first dubble buffer Data Interrupt
138 1 - TXD - Tx Data Interrupt
139 2 - TXXFR - Tx Transfer Interrupt
140 3 - RX1 - Rx second dubble buffer Data Interrupt
141 4 - RXXFR - Rx Transfer Interrupt
142 5 - EVENT_A - Event Mailbox interrupt
143 6 - EVENT_B - Event Mailbox interrupt
144 7 - WNONHST - Wake On Host Interrupt
145 8 - TRACE_A - Debug Trace interrupt
146 9 - TRACE_B - Debug Trace interrupt
147 10 - CDCMP - Command Complete Interrupt
148 11 -
149 12 -
150 13 -
151 14 - ICOMP - Initialization Complete Interrupt
152 16 - SG SE - Soft Gemini - Sense enable interrupt
153 17 - SG SD - Soft Gemini - Sense disable interrupt
154 18 - -
155 19 - -
156 20 - -
157 21- -
158 Default: 0x0001
159*==============================================*/
160#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC)
161
162/*=============================================
163 Host Interrupt Mask Set 16bit, (Write only)
164 ------------------------------------------
165 Setting a bit in this register sets
166 the corresponding bin in ACX_HINT_MASK register
167 without effecting the mask
168 state of other bits (0 = no effect).
169==============================================*/
170#define ACX_REG_HINT_MASK_SET (REGISTERS_BASE + 0x04E0)
171
172/*=============================================
173 Host Interrupt Mask Clear 16bit,(Write only)
174 ------------------------------------------
175 Setting a bit in this register clears
176 the corresponding bin in ACX_HINT_MASK register
177 without effecting the mask
178 state of other bits (0 = no effect).
179=============================================*/
180#define ACX_REG_HINT_MASK_CLR (REGISTERS_BASE + 0x04E4)
181
182/*=============================================
183 Host Interrupt Status Nondestructive Read
184 16bit,(Read only)
185 ------------------------------------------
186 The host can read this register to determine
187 which interrupts are active.
188 Reading this register doesn't
189 effect its content.
190=============================================*/
191#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8)
192
193/*=============================================
194 Host Interrupt Status Clear on Read Register
195 16bit,(Read only)
196 ------------------------------------------
197 The host can read this register to determine
198 which interrupts are active.
199 Reading this register clears it,
200 thus making all interrupts inactive.
201==============================================*/
202#define ACX_REG_INTERRUPT_CLEAR (REGISTERS_BASE + 0x04F8)
203
204/*=============================================
205 Host Interrupt Acknowledge Register
206 16bit,(Write only)
207 ------------------------------------------
208 The host can set individual bits in this
209 register to clear (acknowledge) the corresp.
210 interrupt status bits in the HINT_STS_CLR and
211 HINT_STS_ND registers, thus making the
212 assotiated interrupt inactive. (0-no effect)
213==============================================*/
214#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0)
215
216#define RX_DRIVER_DUMMY_WRITE_ADDRESS (REGISTERS_BASE + 0x0534)
217#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538)
218
219/* Device Configuration registers*/
220#define SOR_CFG (REGISTERS_BASE + 0x0800)
221
222/* Embedded ARM CPU Control */
223
224/*===============================================
225 Halt eCPU - 32bit RW
226 ------------------------------------------
227 0 HALT_ECPU Halt Embedded CPU - This bit is the
228 compliment of bit 1 (MDATA2) in the SOR_CFG register.
229 During a hardware reset, this bit holds
230 the inverse of MDATA2.
231 When downloading firmware from the host,
232 set this bit (pull down MDATA2).
233 The host clears this bit after downloading the firmware into
234 zero-wait-state SSRAM.
235 When loading firmware from Flash, clear this bit (pull up MDATA2)
236 so that the eCPU can run the bootloader code in Flash
237 HALT_ECPU eCPU State
238 --------------------
239 1 halt eCPU
240 0 enable eCPU
241 ===============================================*/
242#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804)
243
244#define HI_CFG (REGISTERS_BASE + 0x0808)
245
246/*===============================================
247 EEPROM Burst Read Start - 32bit RW
248 ------------------------------------------
249 [31:1] Reserved
250 0 ACX_EE_START - EEPROM Burst Read Start 0
251 Setting this bit starts a burst read from
252 the external EEPROM.
253 If this bit is set (after reset) before an EEPROM read/write,
254 the burst read starts at EEPROM address 0.
255 Otherwise, it starts at the address
256 following the address of the previous access.
257 TheWlan hardware hardware clears this bit automatically.
258
259 Default: 0x00000000
260*================================================*/
261#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C)
262
263#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4)
264#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8)
265#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC)
266#define OCP_CMD (REGISTERS_BASE + 0x09C0)
267
268#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
269
270#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
271
272#define CHIP_ID_1271_PG10 (0x4030101)
273#define CHIP_ID_1271_PG20 (0x4030111)
274
275#define ENABLE (REGISTERS_BASE + 0x5450)
276
277/* Power Management registers */
278#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
279#define ELP_CMD (REGISTERS_BASE + 0x5808)
280#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
281#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
282#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
283
284#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
285
286/* Scratch Pad registers*/
287#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
288#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
289#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
290#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
291#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
292#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
293#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
294#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
295#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
296#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
297#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
298#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
299#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
300#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
301
302/* Spare registers*/
303#define SPARE_A1 (REGISTERS_BASE + 0x0994)
304#define SPARE_A2 (REGISTERS_BASE + 0x0998)
305#define SPARE_A3 (REGISTERS_BASE + 0x099C)
306#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
307#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
308#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
309#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
310#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
311#define SPARE_B1 (REGISTERS_BASE + 0x5420)
312#define SPARE_B2 (REGISTERS_BASE + 0x5424)
313#define SPARE_B3 (REGISTERS_BASE + 0x5428)
314#define SPARE_B4 (REGISTERS_BASE + 0x542C)
315#define SPARE_B5 (REGISTERS_BASE + 0x5430)
316#define SPARE_B6 (REGISTERS_BASE + 0x5434)
317#define SPARE_B7 (REGISTERS_BASE + 0x5438)
318#define SPARE_B8 (REGISTERS_BASE + 0x543C)
319
320#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040)
321#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008)
322#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100)
323#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C)
324
325
326#define ACX_SLV_SOFT_RESET_BIT BIT(1)
327#define ACX_REG_EEPROM_START_BIT BIT(1)
328
329/* Command/Information Mailbox Pointers */
330
331/*===============================================
332 Command Mailbox Pointer - 32bit RW
333 ------------------------------------------
334 This register holds the start address of
335 the command mailbox located in the Wlan hardware memory.
336 The host must read this pointer after a reset to
337 find the location of the command mailbox.
338 The Wlan hardware initializes the command mailbox
339 pointer with the default address of the command mailbox.
340 The command mailbox pointer is not valid until after
341 the host receives the Init Complete interrupt from
342 the Wlan hardware.
343 ===============================================*/
344#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
345
346/*===============================================
347 Information Mailbox Pointer - 32bit RW
348 ------------------------------------------
349 This register holds the start address of
350 the information mailbox located in the Wlan hardware memory.
351 The host must read this pointer after a reset to find
352 the location of the information mailbox.
353 The Wlan hardware initializes the information mailbox pointer
354 with the default address of the information mailbox.
355 The information mailbox pointer is not valid
356 until after the host receives the Init Complete interrupt from
357 the Wlan hardware.
358 ===============================================*/
359#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
360
361
362/* Misc */
363
364#define REG_ENABLE_TX_RX (ENABLE)
365/*
366 * Rx configuration (filter) information element
367 * ---------------------------------------------
368 */
369#define REG_RX_CONFIG (RX_CFG)
370#define REG_RX_FILTER (RX_FILTER_CFG)
371
372
373#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
374
375/* promiscuous - receives all valid frames */
376#define RX_CFG_PROMISCUOUS 0x0008
377
378/* receives frames from any BSSID */
379#define RX_CFG_BSSID 0x0020
380
381/* receives frames destined to any MAC address */
382#define RX_CFG_MAC 0x0010
383
384#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
385#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
386#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
387#define RX_CFG_ENABLE_ANY_BSSID 0x0000
388
389/* discards all broadcast frames */
390#define RX_CFG_DISABLE_BCAST 0x0200
391
392#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
393#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
394#define RX_CFG_COPY_RX_STATUS 0x2000
395#define RX_CFG_TSF 0x10000
396
397#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
398 RX_CFG_ENABLE_ONLY_MY_BSSID)
399
400#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
401 | RX_CFG_ENABLE_ANY_BSSID)
402
403#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
404 RX_CFG_ENABLE_ANY_BSSID)
405
406#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
407 | RX_CFG_ENABLE_ONLY_MY_BSSID)
408
409#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
410 | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
411 | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
412
413#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
414
415#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
416 RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
417
418#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
419 RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
420
421#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
422 | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
423 | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
424
425#define RX_FILTER_OPTION_FILTER_ALL 0
426
427#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
428 | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
429
430#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
431 | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
432 | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
433 | CFG_RX_PRSP_EN)
434
435
436/*===============================================
437 Phy regs
438 ===============================================*/
439#define ACX_PHY_ADDR_REG SBB_ADDR
440#define ACX_PHY_DATA_REG SBB_DATA
441#define ACX_PHY_CTRL_REG SBB_CTL
442#define ACX_PHY_REG_WR_MASK 0x00000001ul
443#define ACX_PHY_REG_RD_MASK 0x00000002ul
444
445
446/*===============================================
447 EEPROM Read/Write Request 32bit RW
448 ------------------------------------------
449 1 EE_READ - EEPROM Read Request 1 - Setting this bit
450 loads a single byte of data into the EE_DATA
451 register from the EEPROM location specified in
452 the EE_ADDR register.
453 The Wlan hardware hardware clears this bit automatically.
454 EE_DATA is valid when this bit is cleared.
455
456 0 EE_WRITE - EEPROM Write Request - Setting this bit
457 writes a single byte of data from the EE_DATA register into the
458 EEPROM location specified in the EE_ADDR register.
459 The Wlan hardware hardware clears this bit automatically.
460*===============================================*/
461#define ACX_EE_CTL_REG EE_CTL
462#define EE_WRITE 0x00000001ul
463#define EE_READ 0x00000002ul
464
465/*===============================================
466 EEPROM Address - 32bit RW
467 ------------------------------------------
468 This register specifies the address
469 within the EEPROM from/to which to read/write data.
470 ===============================================*/
471#define ACX_EE_ADDR_REG EE_ADDR
472
473/*===============================================
474 EEPROM Data - 32bit RW
475 ------------------------------------------
476 This register either holds the read 8 bits of
477 data from the EEPROM or the write data
478 to be written to the EEPROM.
479 ===============================================*/
480#define ACX_EE_DATA_REG EE_DATA
481
482/*===============================================
483 EEPROM Base Address - 32bit RW
484 ------------------------------------------
485 This register holds the upper nine bits
486 [23:15] of the 24-bit Wlan hardware memory
487 address for burst reads from EEPROM accesses.
488 The EEPROM provides the lower 15 bits of this address.
489 The MSB of the address from the EEPROM is ignored.
490 ===============================================*/
491#define ACX_EE_CFG EE_CFG
492
493/*===============================================
494 GPIO Output Values -32bit, RW
495 ------------------------------------------
496 [31:16] Reserved
497 [15: 0] Specify the output values (at the output driver inputs) for
498 GPIO[15:0], respectively.
499 ===============================================*/
500#define ACX_GPIO_OUT_REG GPIO_OUT
501#define ACX_MAX_GPIO_LINES 15
502
503/*===============================================
504 Contention window -32bit, RW
505 ------------------------------------------
506 [31:26] Reserved
507 [25:16] Max (0x3ff)
508 [15:07] Reserved
509 [06:00] Current contention window value - default is 0x1F
510 ===============================================*/
511#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
512#define ACX_CONT_WIND_MIN_MASK 0x0000007f
513#define ACX_CONT_WIND_MAX 0x03ff0000
514
515/*
516 * Indirect slave register/memory registers
517 * ----------------------------------------
518 */
519#define HW_SLAVE_REG_ADDR_REG 0x00000004
520#define HW_SLAVE_REG_DATA_REG 0x00000008
521#define HW_SLAVE_REG_CTRL_REG 0x0000000c
522
523#define SLAVE_AUTO_INC 0x00010000
524#define SLAVE_NO_AUTO_INC 0x00000000
525#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
526
527#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
528#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
529#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
530#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
531
532#define HW_FUNC_EVENT_INT_EN 0x8000
533#define HW_FUNC_EVENT_MASK_REG 0x00000034
534
535#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
536
537/*===============================================
538 HI_CFG Interface Configuration Register Values
539 ------------------------------------------
540 ===============================================*/
541#define HI_CFG_UART_ENABLE 0x00000004
542#define HI_CFG_RST232_ENABLE 0x00000008
543#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
544#define HI_CFG_HOST_INT_ENABLE 0x00000020
545#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
546#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
547#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
548#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
549#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
550
551/*
552 * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
553 * for platforms using active high interrupt level
554 */
555#ifdef USE_ACTIVE_HIGH
556#define HI_CFG_DEF_VAL \
557 (HI_CFG_UART_ENABLE | \
558 HI_CFG_RST232_ENABLE | \
559 HI_CFG_CLOCK_REQ_SELECT | \
560 HI_CFG_HOST_INT_ENABLE)
561#else
562#define HI_CFG_DEF_VAL \
563 (HI_CFG_UART_ENABLE | \
564 HI_CFG_RST232_ENABLE | \
565 HI_CFG_CLOCK_REQ_SELECT | \
566 HI_CFG_HOST_INT_ENABLE)
567
568#endif
569
570#define REF_FREQ_19_2 0
571#define REF_FREQ_26_0 1
572#define REF_FREQ_38_4 2
573#define REF_FREQ_40_0 3
574#define REF_FREQ_33_6 4
575#define REF_FREQ_NUM 5
576
577#define LUT_PARAM_INTEGER_DIVIDER 0
578#define LUT_PARAM_FRACTIONAL_DIVIDER 1
579#define LUT_PARAM_ATTN_BB 2
580#define LUT_PARAM_ALPHA_BB 3
581#define LUT_PARAM_STOP_TIME_BB 4
582#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
583#define LUT_PARAM_NUM 6
584
585#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
586#define USE_EEPROM 0
587#define SOFT_RESET_MAX_TIME 1000000
588#define SOFT_RESET_STALL_TIME 1000
589#define NVS_DATA_BUNDARY_ALIGNMENT 4
590
591
592/* Firmware image load chunk size */
593#define CHUNK_SIZE 512
594
595/* Firmware image header size */
596#define FW_HDR_SIZE 8
597
598#define ECPU_CONTROL_HALT 0x00000101
599
600
601/******************************************************************************
602
603 CHANNELS, BAND & REG DOMAINS definitions
604
605******************************************************************************/
606
607
608enum {
609 RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
610 RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
611 RADIO_BAND_JAPAN_4_9_GHZ = 2,
612 DEFAULT_BAND = RADIO_BAND_2_4GHZ,
613 INVALID_BAND = 0xFE,
614 MAX_RADIO_BANDS = 0xFF
615};
616
617enum {
618 NO_RATE = 0,
619 RATE_1MBPS = 0x0A,
620 RATE_2MBPS = 0x14,
621 RATE_5_5MBPS = 0x37,
622 RATE_6MBPS = 0x0B,
623 RATE_9MBPS = 0x0F,
624 RATE_11MBPS = 0x6E,
625 RATE_12MBPS = 0x0A,
626 RATE_18MBPS = 0x0E,
627 RATE_22MBPS = 0xDC,
628 RATE_24MBPS = 0x09,
629 RATE_36MBPS = 0x0D,
630 RATE_48MBPS = 0x08,
631 RATE_54MBPS = 0x0C
632};
633
634enum {
635 RATE_INDEX_1MBPS = 0,
636 RATE_INDEX_2MBPS = 1,
637 RATE_INDEX_5_5MBPS = 2,
638 RATE_INDEX_6MBPS = 3,
639 RATE_INDEX_9MBPS = 4,
640 RATE_INDEX_11MBPS = 5,
641 RATE_INDEX_12MBPS = 6,
642 RATE_INDEX_18MBPS = 7,
643 RATE_INDEX_22MBPS = 8,
644 RATE_INDEX_24MBPS = 9,
645 RATE_INDEX_36MBPS = 10,
646 RATE_INDEX_48MBPS = 11,
647 RATE_INDEX_54MBPS = 12,
648 RATE_INDEX_MAX = RATE_INDEX_54MBPS,
649 MAX_RATE_INDEX,
650 INVALID_RATE_INDEX = MAX_RATE_INDEX,
651 RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
652};
653
654enum {
655 RATE_MASK_1MBPS = 0x1,
656 RATE_MASK_2MBPS = 0x2,
657 RATE_MASK_5_5MBPS = 0x4,
658 RATE_MASK_11MBPS = 0x20,
659};
660
661#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
662#define OFDM_RATE_BIT BIT(6)
663#define PBCC_RATE_BIT BIT(7)
664
665enum {
666 CCK_LONG = 0,
667 CCK_SHORT = SHORT_PREAMBLE_BIT,
668 PBCC_LONG = PBCC_RATE_BIT,
669 PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
670 OFDM = OFDM_RATE_BIT
671};
672
673/******************************************************************************
674
675Transmit-Descriptor RATE-SET field definitions...
676
677Define a new "Rate-Set" for TX path that incorporates the
678Rate & Modulation info into a single 16-bit field.
679
680TxdRateSet_t:
681b15 - Indicates Preamble type (1=SHORT, 0=LONG).
682 Notes:
683 Must be LONG (0) for 1Mbps rate.
684 Does not apply (set to 0) for RevG-OFDM rates.
685b14 - Indicates PBCC encoding (1=PBCC, 0=not).
686 Notes:
687 Does not apply (set to 0) for rates 1 and 2 Mbps.
688 Does not apply (set to 0) for RevG-OFDM rates.
689b13 - Unused (set to 0).
690b12-b0 - Supported Rate indicator bits as defined below.
691
692******************************************************************************/
693
694
695#define TNETW1251_CHIP_ID_PG1_0 0x07010101
696#define TNETW1251_CHIP_ID_PG1_1 0x07020101
697#define TNETW1251_CHIP_ID_PG1_2 0x07030101
698
699/*************************************************************************
700
701 Interrupt Trigger Register (Host -> WiLink)
702
703**************************************************************************/
704
705/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
706
707/*
708 * Host Command Interrupt. Setting this bit masks
709 * the interrupt that the host issues to inform
710 * the FW that it has sent a command
711 * to the Wlan hardware Command Mailbox.
712 */
713#define INTR_TRIG_CMD BIT(0)
714
715/*
716 * Host Event Acknowlegde Interrupt. The host
717 * sets this bit to acknowledge that it received
718 * the unsolicited information from the event
719 * mailbox.
720 */
721#define INTR_TRIG_EVENT_ACK BIT(1)
722
723/*
724 * The host sets this bit to inform the Wlan
725 * FW that a TX packet is in the XFER
726 * Buffer #0.
727 */
728#define INTR_TRIG_TX_PROC0 BIT(2)
729
730/*
731 * The host sets this bit to inform the FW
732 * that it read a packet from RX XFER
733 * Buffer #0.
734 */
735#define INTR_TRIG_RX_PROC0 BIT(3)
736
737#define INTR_TRIG_DEBUG_ACK BIT(4)
738
739#define INTR_TRIG_STATE_CHANGED BIT(5)
740
741
742/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
743
744/*
745 * The host sets this bit to inform the FW
746 * that it read a packet from RX XFER
747 * Buffer #1.
748 */
749#define INTR_TRIG_RX_PROC1 BIT(17)
750
751/*
752 * The host sets this bit to inform the Wlan
753 * hardware that a TX packet is in the XFER
754 * Buffer #1.
755 */
756#define INTR_TRIG_TX_PROC1 BIT(18)
757
758#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
new file mode 100644
index 000000000000..ad8b6904c5eb
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -0,0 +1,200 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
25#include "wl1271_acx.h"
26#include "wl1271_reg.h"
27#include "wl1271_rx.h"
28#include "wl1271_spi.h"
29
30static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
31 u32 drv_rx_counter)
32{
33 return status->rx_pkt_descs[drv_rx_counter] & RX_MEM_BLOCK_MASK;
34}
35
36static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
37 u32 drv_rx_counter)
38{
39 return (status->rx_pkt_descs[drv_rx_counter] & RX_BUF_SIZE_MASK) >>
40 RX_BUF_SIZE_SHIFT_DIV;
41}
42
43/* The values of this table must match the wl1271_rates[] array */
44static u8 wl1271_rx_rate_to_idx[] = {
45 /* MCS rates are used only with 11n */
46 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
47 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
48 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
49 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
50 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
51 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
52 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
53 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
54
55 11, /* WL1271_RATE_54 */
56 10, /* WL1271_RATE_48 */
57 9, /* WL1271_RATE_36 */
58 8, /* WL1271_RATE_24 */
59
60 /* TI-specific rate */
61 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
62
63 7, /* WL1271_RATE_18 */
64 6, /* WL1271_RATE_12 */
65 3, /* WL1271_RATE_11 */
66 5, /* WL1271_RATE_9 */
67 4, /* WL1271_RATE_6 */
68 2, /* WL1271_RATE_5_5 */
69 1, /* WL1271_RATE_2 */
70 0 /* WL1271_RATE_1 */
71};
72
73static void wl1271_rx_status(struct wl1271 *wl,
74 struct wl1271_rx_descriptor *desc,
75 struct ieee80211_rx_status *status,
76 u8 beacon)
77{
78 memset(status, 0, sizeof(struct ieee80211_rx_status));
79
80 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
81 status->band = IEEE80211_BAND_2GHZ;
82 else
83 wl1271_warning("unsupported band 0x%x",
84 desc->flags & WL1271_RX_DESC_BAND_MASK);
85
86 /*
87 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the
88 * timestamp from the beacon (acx_tsf_info). In BSS mode (infra) we
89 * only need the mactime for monitor mode. For now the mactime is
90 * not valid, so RX_FLAG_TSFT should not be set
91 */
92 status->signal = desc->rssi;
93
94 /* FIXME: Should this be optimized? */
95 status->qual = (desc->rssi - WL1271_RX_MIN_RSSI) * 100 /
96 (WL1271_RX_MAX_RSSI - WL1271_RX_MIN_RSSI);
97 status->qual = min(status->qual, 100);
98 status->qual = max(status->qual, 0);
99
100 /*
101 * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
102 * need to divide by two for now, but TI has been discussing about
103 * changing it. This needs to be rechecked.
104 */
105 status->noise = desc->rssi - (desc->snr >> 1);
106
107 status->freq = ieee80211_channel_to_frequency(desc->channel);
108
109 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
110 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
111
112 if (likely(!(desc->flags & WL1271_RX_DESC_DECRYPT_FAIL)))
113 status->flag |= RX_FLAG_DECRYPTED;
114
115 if (unlikely(desc->flags & WL1271_RX_DESC_MIC_FAIL))
116 status->flag |= RX_FLAG_MMIC_ERROR;
117 }
118
119 status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
120
121 if (status->rate_idx == WL1271_RX_RATE_UNSUPPORTED)
122 wl1271_warning("unsupported rate");
123}
124
125static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
126{
127 struct ieee80211_rx_status rx_status;
128 struct wl1271_rx_descriptor *desc;
129 struct sk_buff *skb;
130 u16 *fc;
131 u8 *buf;
132 u8 beacon = 0;
133
134 skb = dev_alloc_skb(length);
135 if (!skb) {
136 wl1271_error("Couldn't allocate RX frame");
137 return;
138 }
139
140 buf = skb_put(skb, length);
141 wl1271_spi_reg_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
142
143 /* the data read starts with the descriptor */
144 desc = (struct wl1271_rx_descriptor *) buf;
145
146 /* now we pull the descriptor out of the buffer */
147 skb_pull(skb, sizeof(*desc));
148
149 fc = (u16 *)skb->data;
150 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
151 beacon = 1;
152
153 wl1271_rx_status(wl, desc, &rx_status, beacon);
154
155 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
156 beacon ? "beacon" : "");
157
158 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
159 ieee80211_rx(wl->hw, skb);
160}
161
162void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
163{
164 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
165 u32 buf_size;
166 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
167 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
168 u32 mem_block;
169
170 while (drv_rx_counter != fw_rx_counter) {
171 mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
172 buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter);
173
174 if (buf_size == 0) {
175 wl1271_warning("received empty data");
176 break;
177 }
178
179 wl->rx_mem_pool_addr.addr =
180 (mem_block << 8) + wl_mem_map->packet_memory_pool_start;
181 wl->rx_mem_pool_addr.addr_extra =
182 wl->rx_mem_pool_addr.addr + 4;
183
184 /* Choose the block we want to read */
185 wl1271_spi_reg_write(wl, WL1271_SLV_REG_DATA,
186 &wl->rx_mem_pool_addr,
187 sizeof(wl->rx_mem_pool_addr), false);
188
189 wl1271_rx_handle_data(wl, buf_size);
190
191 wl->rx_counter++;
192 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
193 }
194
195 wl1271_reg_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
196
197 /* This is a workaround for some problems in the chip */
198 wl1271_reg_write32(wl, RX_DRIVER_DUMMY_WRITE_ADDRESS, 0x1);
199
200}
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
new file mode 100644
index 000000000000..d1ca60e43a25
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -0,0 +1,121 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_RX_H__
26#define __WL1271_RX_H__
27
28#include <linux/bitops.h>
29
30#define WL1271_RX_MAX_RSSI -30
31#define WL1271_RX_MIN_RSSI -95
32
33#define WL1271_RX_ALIGN_TO 4
34#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \
35 ~(WL1271_RX_ALIGN_TO - 1))
36
37#define SHORT_PREAMBLE_BIT BIT(0)
38#define OFDM_RATE_BIT BIT(6)
39#define PBCC_RATE_BIT BIT(7)
40
41#define PLCP_HEADER_LENGTH 8
42#define RX_DESC_PACKETID_SHIFT 11
43#define RX_MAX_PACKET_ID 3
44
45#define NUM_RX_PKT_DESC_MOD_MASK 7
46#define WL1271_RX_RATE_UNSUPPORTED 0xFF
47
48#define RX_DESC_VALID_FCS 0x0001
49#define RX_DESC_MATCH_RXADDR1 0x0002
50#define RX_DESC_MCAST 0x0004
51#define RX_DESC_STAINTIM 0x0008
52#define RX_DESC_VIRTUAL_BM 0x0010
53#define RX_DESC_BCAST 0x0020
54#define RX_DESC_MATCH_SSID 0x0040
55#define RX_DESC_MATCH_BSSID 0x0080
56#define RX_DESC_ENCRYPTION_MASK 0x0300
57#define RX_DESC_MEASURMENT 0x0400
58#define RX_DESC_SEQNUM_MASK 0x1800
59#define RX_DESC_MIC_FAIL 0x2000
60#define RX_DESC_DECRYPT_FAIL 0x4000
61
62/*
63 * RX Descriptor flags:
64 *
65 * Bits 0-1 - band
66 * Bit 2 - STBC
67 * Bit 3 - A-MPDU
68 * Bit 4 - HT
69 * Bits 5-7 - encryption
70 */
71#define WL1271_RX_DESC_BAND_MASK 0x03
72#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0
73
74#define WL1271_RX_DESC_BAND_BG 0x00
75#define WL1271_RX_DESC_BAND_J 0x01
76#define WL1271_RX_DESC_BAND_A 0x02
77
78#define WL1271_RX_DESC_STBC BIT(2)
79#define WL1271_RX_DESC_A_MPDU BIT(3)
80#define WL1271_RX_DESC_HT BIT(4)
81
82#define WL1271_RX_DESC_ENCRYPT_WEP 0x20
83#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40
84#define WL1271_RX_DESC_ENCRYPT_AES 0x60
85#define WL1271_RX_DESC_ENCRYPT_GEM 0x80
86
87/*
88 * RX Descriptor status
89 *
90 * Bits 0-2 - status
91 * Bits 3-7 - reserved
92 */
93#define WL1271_RX_DESC_STATUS_MASK 0x07
94
95#define WL1271_RX_DESC_SUCCESS 0x00
96#define WL1271_RX_DESC_DECRYPT_FAIL 0x01
97#define WL1271_RX_DESC_MIC_FAIL 0x02
98#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
99
100#define RX_MEM_BLOCK_MASK 0xFF
101#define RX_BUF_SIZE_MASK 0xFFF00
102#define RX_BUF_SIZE_SHIFT_DIV 6
103
104struct wl1271_rx_descriptor {
105 u16 length;
106 u8 status;
107 u8 flags;
108 u8 rate;
109 u8 channel;
110 s8 rssi;
111 u8 snr;
112 u32 timestamp;
113 u8 packet_class;
114 u8 process_id;
115 u8 pad_len;
116 u8 reserved;
117} __attribute__ ((packed));
118
119void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
120
121#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
new file mode 100644
index 000000000000..4a12880c16a8
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -0,0 +1,382 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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/platform_device.h>
26#include <linux/crc7.h>
27#include <linux/spi/spi.h>
28
29#include "wl1271.h"
30#include "wl12xx_80211.h"
31#include "wl1271_spi.h"
32
33static int wl1271_translate_reg_addr(struct wl1271 *wl, int addr)
34{
35 return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
36}
37
38static int wl1271_translate_mem_addr(struct wl1271 *wl, int addr)
39{
40 return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
41}
42
43
44void wl1271_spi_reset(struct wl1271 *wl)
45{
46 u8 *cmd;
47 struct spi_transfer t;
48 struct spi_message m;
49
50 cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
51 if (!cmd) {
52 wl1271_error("could not allocate cmd for spi reset");
53 return;
54 }
55
56 memset(&t, 0, sizeof(t));
57 spi_message_init(&m);
58
59 memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
60
61 t.tx_buf = cmd;
62 t.len = WSPI_INIT_CMD_LEN;
63 spi_message_add_tail(&t, &m);
64
65 spi_sync(wl->spi, &m);
66
67 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
68}
69
70void wl1271_spi_init(struct wl1271 *wl)
71{
72 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
73 struct spi_transfer t;
74 struct spi_message m;
75
76 cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
77 if (!cmd) {
78 wl1271_error("could not allocate cmd for spi init");
79 return;
80 }
81
82 memset(crc, 0, sizeof(crc));
83 memset(&t, 0, sizeof(t));
84 spi_message_init(&m);
85
86 /*
87 * Set WSPI_INIT_COMMAND
88 * the data is being send from the MSB to LSB
89 */
90 cmd[2] = 0xff;
91 cmd[3] = 0xff;
92 cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
93 cmd[0] = 0;
94 cmd[7] = 0;
95 cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
96 cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
97
98 if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
99 cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
100 else
101 cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
102
103 cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
104 | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
105
106 crc[0] = cmd[1];
107 crc[1] = cmd[0];
108 crc[2] = cmd[7];
109 crc[3] = cmd[6];
110 crc[4] = cmd[5];
111
112 cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
113 cmd[4] |= WSPI_INIT_CMD_END;
114
115 t.tx_buf = cmd;
116 t.len = WSPI_INIT_CMD_LEN;
117 spi_message_add_tail(&t, &m);
118
119 spi_sync(wl->spi, &m);
120
121 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
122}
123
124/* Set the SPI partitions to access the chip addresses
125 *
126 * There are two VIRTUAL (SPI) partitions (the memory partition and the
127 * registers partition), which are mapped to two different areas of the
128 * PHYSICAL (hardware) memory. This function also makes other checks to
129 * ensure that the partitions are not overlapping. In the diagram below, the
130 * memory partition comes before the register partition, but the opposite is
131 * also supported.
132 *
133 * PHYSICAL address
134 * space
135 *
136 * | |
137 * ...+----+--> mem_start
138 * VIRTUAL address ... | |
139 * space ... | | [PART_0]
140 * ... | |
141 * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
142 * | | ... | |
143 * |MEM | ... | |
144 * | | ... | |
145 * part_size <--+----+... | | {unused area)
146 * | | ... | |
147 * |REG | ... | |
148 * part_size | | ... | |
149 * + <--+----+... ...+----+--> reg_start
150 * reg_size ... | |
151 * ... | | [PART_1]
152 * ... | |
153 * ...+----+--> reg_start + reg_size
154 * | |
155 *
156 */
157int wl1271_set_partition(struct wl1271 *wl,
158 u32 mem_start, u32 mem_size,
159 u32 reg_start, u32 reg_size)
160{
161 struct wl1271_partition *partition;
162 struct spi_transfer t;
163 struct spi_message m;
164 size_t len, cmd_len;
165 u32 *cmd;
166 int addr;
167
168 cmd_len = sizeof(u32) + 2 * sizeof(struct wl1271_partition);
169 cmd = kzalloc(cmd_len, GFP_KERNEL);
170 if (!cmd)
171 return -ENOMEM;
172
173 spi_message_init(&m);
174 memset(&t, 0, sizeof(t));
175
176 partition = (struct wl1271_partition *) (cmd + 1);
177 addr = HW_ACCESS_PART0_SIZE_ADDR;
178 len = 2 * sizeof(struct wl1271_partition);
179
180 *cmd |= WSPI_CMD_WRITE;
181 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
182 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
183
184 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
185 mem_start, mem_size);
186 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
187 reg_start, reg_size);
188
189 /* Make sure that the two partitions together don't exceed the
190 * address range */
191 if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
192 wl1271_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
193 " address range. Truncating partition[0].");
194 mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
195 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
196 mem_start, mem_size);
197 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
198 reg_start, reg_size);
199 }
200
201 if ((mem_start < reg_start) &&
202 ((mem_start + mem_size) > reg_start)) {
203 /* Guarantee that the memory partition doesn't overlap the
204 * registers partition */
205 wl1271_debug(DEBUG_SPI, "End of partition[0] is "
206 "overlapping partition[1]. Adjusted.");
207 mem_size = reg_start - mem_start;
208 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
209 mem_start, mem_size);
210 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
211 reg_start, reg_size);
212 } else if ((reg_start < mem_start) &&
213 ((reg_start + reg_size) > mem_start)) {
214 /* Guarantee that the register partition doesn't overlap the
215 * memory partition */
216 wl1271_debug(DEBUG_SPI, "End of partition[1] is"
217 " overlapping partition[0]. Adjusted.");
218 reg_size = mem_start - reg_start;
219 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
220 mem_start, mem_size);
221 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
222 reg_start, reg_size);
223 }
224
225 partition[0].start = mem_start;
226 partition[0].size = mem_size;
227 partition[1].start = reg_start;
228 partition[1].size = reg_size;
229
230 wl->physical_mem_addr = mem_start;
231 wl->physical_reg_addr = reg_start;
232
233 wl->virtual_mem_addr = 0;
234 wl->virtual_reg_addr = mem_size;
235
236 t.tx_buf = cmd;
237 t.len = cmd_len;
238 spi_message_add_tail(&t, &m);
239
240 spi_sync(wl->spi, &m);
241
242 kfree(cmd);
243
244 return 0;
245}
246
247void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
248 size_t len, bool fixed)
249{
250 struct spi_transfer t[3];
251 struct spi_message m;
252 u8 *busy_buf;
253 u32 *cmd;
254
255 cmd = &wl->buffer_cmd;
256 busy_buf = wl->buffer_busyword;
257
258 *cmd = 0;
259 *cmd |= WSPI_CMD_READ;
260 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
261 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
262
263 if (fixed)
264 *cmd |= WSPI_CMD_FIXED;
265
266 spi_message_init(&m);
267 memset(t, 0, sizeof(t));
268
269 t[0].tx_buf = cmd;
270 t[0].len = 4;
271 spi_message_add_tail(&t[0], &m);
272
273 /* Busy and non busy words read */
274 t[1].rx_buf = busy_buf;
275 t[1].len = WL1271_BUSY_WORD_LEN;
276 spi_message_add_tail(&t[1], &m);
277
278 t[2].rx_buf = buf;
279 t[2].len = len;
280 spi_message_add_tail(&t[2], &m);
281
282 spi_sync(wl->spi, &m);
283
284 /* FIXME: check busy words */
285
286 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
287 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
288}
289
290void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
291 size_t len, bool fixed)
292{
293 struct spi_transfer t[2];
294 struct spi_message m;
295 u32 *cmd;
296
297 cmd = &wl->buffer_cmd;
298
299 *cmd = 0;
300 *cmd |= WSPI_CMD_WRITE;
301 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
302 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
303
304 if (fixed)
305 *cmd |= WSPI_CMD_FIXED;
306
307 spi_message_init(&m);
308 memset(t, 0, sizeof(t));
309
310 t[0].tx_buf = cmd;
311 t[0].len = sizeof(*cmd);
312 spi_message_add_tail(&t[0], &m);
313
314 t[1].tx_buf = buf;
315 t[1].len = len;
316 spi_message_add_tail(&t[1], &m);
317
318 spi_sync(wl->spi, &m);
319
320 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
321 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
322}
323
324void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf,
325 size_t len)
326{
327 int physical;
328
329 physical = wl1271_translate_mem_addr(wl, addr);
330
331 wl1271_spi_read(wl, physical, buf, len, false);
332}
333
334void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf,
335 size_t len)
336{
337 int physical;
338
339 physical = wl1271_translate_mem_addr(wl, addr);
340
341 wl1271_spi_write(wl, physical, buf, len, false);
342}
343
344void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
345 bool fixed)
346{
347 int physical;
348
349 physical = wl1271_translate_reg_addr(wl, addr);
350
351 wl1271_spi_read(wl, physical, buf, len, fixed);
352}
353
354void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
355 bool fixed)
356{
357 int physical;
358
359 physical = wl1271_translate_reg_addr(wl, addr);
360
361 wl1271_spi_write(wl, physical, buf, len, fixed);
362}
363
364u32 wl1271_mem_read32(struct wl1271 *wl, int addr)
365{
366 return wl1271_read32(wl, wl1271_translate_mem_addr(wl, addr));
367}
368
369void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val)
370{
371 wl1271_write32(wl, wl1271_translate_mem_addr(wl, addr), val);
372}
373
374u32 wl1271_reg_read32(struct wl1271 *wl, int addr)
375{
376 return wl1271_read32(wl, wl1271_translate_reg_addr(wl, addr));
377}
378
379void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
380{
381 wl1271_write32(wl, wl1271_translate_reg_addr(wl, addr), val);
382}
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
new file mode 100644
index 000000000000..2c9968458646
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -0,0 +1,113 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_SPI_H__
26#define __WL1271_SPI_H__
27
28#include "wl1271_reg.h"
29
30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
31
32#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
33#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
34#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
35#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
36
37#define HW_ACCESS_REGISTER_SIZE 4
38
39#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
40
41#define WSPI_CMD_READ 0x40000000
42#define WSPI_CMD_WRITE 0x00000000
43#define WSPI_CMD_FIXED 0x20000000
44#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
45#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
46#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
47
48#define WSPI_INIT_CMD_CRC_LEN 5
49
50#define WSPI_INIT_CMD_START 0x00
51#define WSPI_INIT_CMD_TX 0x40
52/* the extra bypass bit is sampled by the TNET as '1' */
53#define WSPI_INIT_CMD_BYPASS_BIT 0x80
54#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
55#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
56#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
57#define WSPI_INIT_CMD_IOD 0x40
58#define WSPI_INIT_CMD_IP 0x20
59#define WSPI_INIT_CMD_CS 0x10
60#define WSPI_INIT_CMD_WS 0x08
61#define WSPI_INIT_CMD_WSPI 0x01
62#define WSPI_INIT_CMD_END 0x01
63
64#define WSPI_INIT_CMD_LEN 8
65
66#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
67 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
68#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
69
70
71/* Raw target IO, address is not translated */
72void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
73 size_t len, bool fixed);
74void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
75 size_t len, bool fixed);
76
77/* Memory target IO, address is tranlated to partition 0 */
78void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf, size_t len);
79void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf, size_t len);
80u32 wl1271_mem_read32(struct wl1271 *wl, int addr);
81void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val);
82
83/* Registers IO */
84void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
85 bool fixed);
86void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
87 bool fixed);
88u32 wl1271_reg_read32(struct wl1271 *wl, int addr);
89void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
90
91/* INIT and RESET words */
92void wl1271_spi_reset(struct wl1271 *wl);
93void wl1271_spi_init(struct wl1271 *wl);
94int wl1271_set_partition(struct wl1271 *wl,
95 u32 part_start, u32 part_size,
96 u32 reg_start, u32 reg_size);
97
98static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
99{
100 wl1271_spi_read(wl, addr, &wl->buffer_32,
101 sizeof(wl->buffer_32), false);
102
103 return wl->buffer_32;
104}
105
106static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
107{
108 wl->buffer_32 = val;
109 wl1271_spi_write(wl, addr, &wl->buffer_32,
110 sizeof(wl->buffer_32), false);
111}
112
113#endif /* __WL1271_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
new file mode 100644
index 000000000000..ff221258b941
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -0,0 +1,378 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
28#include "wl1271_spi.h"
29#include "wl1271_reg.h"
30#include "wl1271_ps.h"
31#include "wl1271_tx.h"
32
33static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
34{
35 int i;
36
37 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
38 if (wl->tx_frames[i] == NULL) {
39 wl->tx_frames[i] = skb;
40 return i;
41 }
42
43 return -EBUSY;
44}
45
46static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
47{
48 struct wl1271_tx_hw_descr *desc;
49 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
50 u32 total_blocks, excluded;
51 int id, ret = -EBUSY;
52
53 /* allocate free identifier for the packet */
54 id = wl1271_tx_id(wl, skb);
55 if (id < 0)
56 return id;
57
58 /* approximate the number of blocks required for this packet
59 in the firmware */
60 /* FIXME: try to figure out what is done here and make it cleaner */
61 total_blocks = (skb->len) >> TX_HW_BLOCK_SHIFT_DIV;
62 excluded = (total_blocks << 2) + (skb->len & 0xff) + 34;
63 total_blocks += (excluded > 252) ? 2 : 1;
64 total_blocks += TX_HW_BLOCK_SPARE;
65
66 if (total_blocks <= wl->tx_blocks_available) {
67 desc = (struct wl1271_tx_hw_descr *)skb_push(
68 skb, total_len - skb->len);
69
70 desc->extra_mem_blocks = TX_HW_BLOCK_SPARE;
71 desc->total_mem_blocks = total_blocks;
72 desc->id = id;
73
74 wl->tx_blocks_available -= total_blocks;
75
76 ret = 0;
77
78 wl1271_debug(DEBUG_TX,
79 "tx_allocate: size: %d, blocks: %d, id: %d",
80 total_len, total_blocks, id);
81 } else
82 wl->tx_frames[id] = NULL;
83
84 return ret;
85}
86
87static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
88 u32 extra, struct ieee80211_tx_info *control)
89{
90 struct wl1271_tx_hw_descr *desc;
91 int pad;
92
93 desc = (struct wl1271_tx_hw_descr *) skb->data;
94
95 /* configure packet life time */
96 desc->start_time = jiffies_to_usecs(jiffies) - wl->time_offset;
97 desc->life_time = TX_HW_MGMT_PKT_LIFETIME_TU;
98
99 /* configure the tx attributes */
100 desc->tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
101 /* FIXME: do we know the packet priority? can we identify mgmt
102 packets, and use max prio for them at least? */
103 desc->tid = 0;
104 desc->aid = TX_HW_DEFAULT_AID;
105 desc->reserved = 0;
106
107 /* align the length (and store in terms of words) */
108 pad = WL1271_TX_ALIGN(skb->len);
109 desc->length = pad >> 2;
110
111 /* calculate number of padding bytes */
112 pad = pad - skb->len;
113 desc->tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
114
115 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
116 return 0;
117}
118
119static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
120 struct ieee80211_tx_info *control)
121{
122
123 struct wl1271_tx_hw_descr *desc;
124 int len;
125
126 /* FIXME: This is a workaround for getting non-aligned packets.
127 This happens at least with EAPOL packets from the user space.
128 Our DMA requires packets to be aligned on a 4-byte boundary.
129 */
130 if (unlikely((long)skb->data & 0x03)) {
131 int offset = (4 - (long)skb->data) & 0x03;
132 wl1271_debug(DEBUG_TX, "skb offset %d", offset);
133
134 /* check whether the current skb can be used */
135 if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
136 unsigned char *src = skb->data;
137
138 /* align the buffer on a 4-byte boundary */
139 skb_reserve(skb, offset);
140 memmove(skb->data, src, skb->len);
141 } else {
142 wl1271_info("No handler, fixme!");
143 return -EINVAL;
144 }
145 }
146
147 len = WL1271_TX_ALIGN(skb->len);
148
149 /* perform a fixed address block write with the packet */
150 wl1271_spi_reg_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
151
152 /* write packet new counter into the write access register */
153 wl->tx_packets_count++;
154 wl1271_reg_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
155
156 desc = (struct wl1271_tx_hw_descr *) skb->data;
157 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
158 desc->id, skb, len, desc->length);
159
160 return 0;
161}
162
163/* caller must hold wl->mutex */
164static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
165{
166 struct ieee80211_tx_info *info;
167 u32 extra = 0;
168 int ret = 0;
169 u8 idx;
170
171 if (!skb)
172 return -EINVAL;
173
174 info = IEEE80211_SKB_CB(skb);
175
176 if (info->control.hw_key &&
177 info->control.hw_key->alg == ALG_TKIP)
178 extra = WL1271_TKIP_IV_SPACE;
179
180 if (info->control.hw_key) {
181 idx = info->control.hw_key->hw_key_idx;
182
183 /* FIXME: do we have to do this if we're not using WEP? */
184 if (unlikely(wl->default_key != idx)) {
185 ret = wl1271_cmd_set_default_wep_key(wl, idx);
186 if (ret < 0)
187 return ret;
188 }
189 }
190
191 ret = wl1271_tx_allocate(wl, skb, extra);
192 if (ret < 0)
193 return ret;
194
195 ret = wl1271_tx_fill_hdr(wl, skb, extra, info);
196 if (ret < 0)
197 return ret;
198
199 ret = wl1271_tx_send_packet(wl, skb, info);
200 if (ret < 0)
201 return ret;
202
203 return ret;
204}
205
206void wl1271_tx_work(struct work_struct *work)
207{
208 struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
209 struct sk_buff *skb;
210 bool woken_up = false;
211 int ret;
212
213 mutex_lock(&wl->mutex);
214
215 if (unlikely(wl->state == WL1271_STATE_OFF))
216 goto out;
217
218 while ((skb = skb_dequeue(&wl->tx_queue))) {
219 if (!woken_up) {
220 ret = wl1271_ps_elp_wakeup(wl, false);
221 if (ret < 0)
222 goto out;
223 woken_up = true;
224 }
225
226 ret = wl1271_tx_frame(wl, skb);
227 if (ret == -EBUSY) {
228 /* firmware buffer is full, stop queues */
229 wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
230 "stop queues");
231 ieee80211_stop_queues(wl->hw);
232 wl->tx_queue_stopped = true;
233 skb_queue_head(&wl->tx_queue, skb);
234 goto out;
235 } else if (ret < 0) {
236 dev_kfree_skb(skb);
237 goto out;
238 } else if (wl->tx_queue_stopped) {
239 /* firmware buffer has space, restart queues */
240 wl1271_debug(DEBUG_TX,
241 "complete_packet: waking queues");
242 ieee80211_wake_queues(wl->hw);
243 wl->tx_queue_stopped = false;
244 }
245 }
246
247out:
248 if (woken_up)
249 wl1271_ps_elp_sleep(wl);
250
251 mutex_unlock(&wl->mutex);
252}
253
254static void wl1271_tx_complete_packet(struct wl1271 *wl,
255 struct wl1271_tx_hw_res_descr *result)
256{
257
258 struct ieee80211_tx_info *info;
259 struct sk_buff *skb;
260 u32 header_len;
261 int id = result->id;
262
263 /* check for id legality */
264 if (id >= TX_HW_RESULT_QUEUE_LEN || wl->tx_frames[id] == NULL) {
265 wl1271_warning("TX result illegal id: %d", id);
266 return;
267 }
268
269 skb = wl->tx_frames[id];
270 info = IEEE80211_SKB_CB(skb);
271
272 /* update packet status */
273 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
274 if (result->status == TX_SUCCESS)
275 info->flags |= IEEE80211_TX_STAT_ACK;
276 if (result->status & TX_RETRY_EXCEEDED) {
277 /* FIXME */
278 /* info->status.excessive_retries = 1; */
279 wl->stats.excessive_retries++;
280 }
281 }
282
283 /* FIXME */
284 /* info->status.retry_count = result->ack_failures; */
285 wl->stats.retry_count += result->ack_failures;
286
287 /* get header len */
288 if (info->control.hw_key &&
289 info->control.hw_key->alg == ALG_TKIP)
290 header_len = WL1271_TKIP_IV_SPACE +
291 sizeof(struct wl1271_tx_hw_descr);
292 else
293 header_len = sizeof(struct wl1271_tx_hw_descr);
294
295 wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
296 " status 0x%x",
297 result->id, skb, result->ack_failures,
298 result->rate_class_index, result->status);
299
300 /* remove private header from packet */
301 skb_pull(skb, header_len);
302
303 /* return the packet to the stack */
304 ieee80211_tx_status(wl->hw, skb);
305 wl->tx_frames[result->id] = NULL;
306}
307
308/* Called upon reception of a TX complete interrupt */
309void wl1271_tx_complete(struct wl1271 *wl, u32 count)
310{
311 struct wl1271_acx_mem_map *memmap =
312 (struct wl1271_acx_mem_map *)wl->target_mem_map;
313 u32 i;
314
315 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
316
317 /* read the tx results from the chipset */
318 wl1271_spi_mem_read(wl, memmap->tx_result,
319 wl->tx_res_if, sizeof(*wl->tx_res_if));
320
321 /* verify that the result buffer is not getting overrun */
322 if (count > TX_HW_RESULT_QUEUE_LEN) {
323 wl1271_warning("TX result overflow from chipset: %d", count);
324 count = TX_HW_RESULT_QUEUE_LEN;
325 }
326
327 /* process the results */
328 for (i = 0; i < count; i++) {
329 struct wl1271_tx_hw_res_descr *result;
330 u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK;
331
332 /* process the packet */
333 result = &(wl->tx_res_if->tx_results_queue[offset]);
334 wl1271_tx_complete_packet(wl, result);
335
336 wl->tx_results_count++;
337 }
338
339 /* write host counter to chipset (to ack) */
340 wl1271_mem_write32(wl, memmap->tx_result +
341 offsetof(struct wl1271_tx_hw_res_if,
342 tx_result_host_counter),
343 wl->tx_res_if->tx_result_fw_counter);
344}
345
346/* caller must hold wl->mutex */
347void wl1271_tx_flush(struct wl1271 *wl)
348{
349 int i;
350 struct sk_buff *skb;
351 struct ieee80211_tx_info *info;
352
353 /* TX failure */
354/* control->flags = 0; FIXME */
355
356 while ((skb = skb_dequeue(&wl->tx_queue))) {
357 info = IEEE80211_SKB_CB(skb);
358
359 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb);
360
361 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
362 continue;
363
364 ieee80211_tx_status(wl->hw, skb);
365 }
366
367 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
368 if (wl->tx_frames[i] != NULL) {
369 skb = wl->tx_frames[i];
370 info = IEEE80211_SKB_CB(skb);
371
372 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
373 continue;
374
375 ieee80211_tx_status(wl->hw, skb);
376 wl->tx_frames[i] = NULL;
377 }
378}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
new file mode 100644
index 000000000000..4a614067ddba
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -0,0 +1,130 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_TX_H__
26#define __WL1271_TX_H__
27
28#define TX_HW_BLOCK_SPARE 2
29#define TX_HW_BLOCK_SHIFT_DIV 8
30
31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
32/* The chipset reference driver states, that the "aid" value 1
33 * is for infra-BSS, but is still always used */
34#define TX_HW_DEFAULT_AID 1
35
36#define TX_HW_ATTR_SAVE_RETRIES BIT(0)
37#define TX_HW_ATTR_HEADER_PAD BIT(1)
38#define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4))
39#define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \
40 BIT(8) | BIT(9))
41#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
42#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
43
44#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
45#define TX_HW_ATTR_OFST_HEADER_PAD 1
46#define TX_HW_ATTR_OFST_SESSION_COUNTER 2
47#define TX_HW_ATTR_OFST_RATE_POLICY 5
48#define TX_HW_ATTR_OFST_LAST_WORD_PAD 10
49#define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12
50
51#define TX_HW_RESULT_QUEUE_LEN 16
52#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf
53
54#define WL1271_TX_ALIGN_TO 4
55#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \
56 ~(WL1271_TX_ALIGN_TO - 1))
57#define WL1271_TKIP_IV_SPACE 4
58
59struct wl1271_tx_hw_descr {
60 /* Length of packet in words, including descriptor+header+data */
61 u16 length;
62 /* Number of extra memory blocks to allocate for this packet in
63 addition to the number of blocks derived from the packet length */
64 u8 extra_mem_blocks;
65 /* Total number of memory blocks allocated by the host for this packet.
66 Must be equal or greater than the actual blocks number allocated by
67 HW!! */
68 u8 total_mem_blocks;
69 /* Device time (in us) when the packet arrived to the driver */
70 u32 start_time;
71 /* Max delay in TUs until transmission. The last device time the
72 packet can be transmitted is: startTime+(1024*LifeTime) */
73 u16 life_time;
74 /* Bitwise fields - see TX_ATTR... definitions above. */
75 u16 tx_attr;
76 /* Packet identifier used also in the Tx-Result. */
77 u8 id;
78 /* The packet TID value (as User-Priority) */
79 u8 tid;
80 /* Identifier of the remote STA in IBSS, 1 in infra-BSS */
81 u8 aid;
82 u8 reserved;
83} __attribute__ ((packed));
84
85enum wl1271_tx_hw_res_status {
86 TX_SUCCESS = 0,
87 TX_HW_ERROR = 1,
88 TX_DISABLED = 2,
89 TX_RETRY_EXCEEDED = 3,
90 TX_TIMEOUT = 4,
91 TX_KEY_NOT_FOUND = 5,
92 TX_PEER_NOT_FOUND = 6,
93 TX_SESSION_MISMATCH = 7
94};
95
96struct wl1271_tx_hw_res_descr {
97 /* Packet Identifier - same value used in the Tx descriptor.*/
98 u8 id;
99 /* The status of the transmission, indicating success or one of
100 several possible reasons for failure. */
101 u8 status;
102 /* Total air access duration including all retrys and overheads.*/
103 u16 medium_usage;
104 /* The time passed from host xfer to Tx-complete.*/
105 u32 fw_handling_time;
106 /* Total media delay
107 (from 1st EDCA AIFS counter until TX Complete). */
108 u32 medium_delay;
109 /* LS-byte of last TKIP seq-num (saved per AC for recovery). */
110 u8 lsb_security_sequence_number;
111 /* Retry count - number of transmissions without successful ACK.*/
112 u8 ack_failures;
113 /* The rate that succeeded getting ACK
114 (Valid only if status=SUCCESS). */
115 u8 rate_class_index;
116 /* for 4-byte alignment. */
117 u8 spare;
118} __attribute__ ((packed));
119
120struct wl1271_tx_hw_res_if {
121 u32 tx_result_fw_counter;
122 u32 tx_result_host_counter;
123 struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
124} __attribute__ ((packed));
125
126void wl1271_tx_work(struct work_struct *work);
127void wl1271_tx_complete(struct wl1271 *wl, u32 count);
128void wl1271_tx_flush(struct wl1271 *wl);
129
130#endif