wl1271: Fix multicast list handling
[deliverable/linux.git] / drivers / net / wireless / wl12xx / wl1271_main.c
CommitLineData
f5fc0f86
LC
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>
1fba4974 33#include <linux/vmalloc.h>
f5fc0f86
LC
34#include <linux/spi/wl12xx.h>
35
36#include "wl1271.h"
37#include "wl12xx_80211.h"
38#include "wl1271_reg.h"
39#include "wl1271_spi.h"
40#include "wl1271_event.h"
41#include "wl1271_tx.h"
42#include "wl1271_rx.h"
43#include "wl1271_ps.h"
44#include "wl1271_init.h"
45#include "wl1271_debugfs.h"
46#include "wl1271_cmd.h"
47#include "wl1271_boot.h"
48
8a08048a
JO
49static struct conf_drv_settings default_conf = {
50 .sg = {
51 .per_threshold = 7500,
52 .max_scan_compensation_time = 120000,
53 .nfs_sample_interval = 400,
54 .load_ratio = 50,
55 .auto_ps_mode = 0,
56 .probe_req_compensation = 170,
57 .scan_window_compensation = 50,
58 .antenna_config = 0,
59 .beacon_miss_threshold = 60,
60 .rate_adaptation_threshold = CONF_HW_BIT_RATE_12MBPS,
61 .rate_adaptation_snr = 0
62 },
63 .rx = {
64 .rx_msdu_life_time = 512000,
65 .packet_detection_threshold = 0,
66 .ps_poll_timeout = 15,
67 .upsd_timeout = 15,
68 .rts_threshold = 2347,
69 .rx_cca_threshold = 0xFFEF,
70 .irq_blk_threshold = 0,
71 .irq_pkt_threshold = USHORT_MAX,
72 .irq_timeout = 5,
73 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
74 },
75 .tx = {
76 .tx_energy_detection = 0,
77 .rc_conf = {
78 .enabled_rates = CONF_TX_RATE_MASK_UNSPECIFIED,
79 .short_retry_limit = 10,
80 .long_retry_limit = 10,
81 .aflags = 0
45b531a8 82 },
8a08048a
JO
83 .ac_conf_count = 4,
84 .ac_conf = {
85 [0] = {
86 .ac = CONF_TX_AC_BE,
87 .cw_min = 15,
88 .cw_max = 63,
89 .aifsn = 3,
90 .tx_op_limit = 0,
45b531a8 91 },
8a08048a
JO
92 [1] = {
93 .ac = CONF_TX_AC_BK,
94 .cw_min = 15,
95 .cw_max = 63,
96 .aifsn = 7,
97 .tx_op_limit = 0,
45b531a8 98 },
8a08048a
JO
99 [2] = {
100 .ac = CONF_TX_AC_VI,
101 .cw_min = 15,
102 .cw_max = 63,
103 .aifsn = CONF_TX_AIFS_PIFS,
104 .tx_op_limit = 3008,
105 },
106 [3] = {
107 .ac = CONF_TX_AC_VO,
108 .cw_min = 15,
109 .cw_max = 63,
110 .aifsn = CONF_TX_AIFS_PIFS,
111 .tx_op_limit = 1504,
45b531a8 112 },
51f2be24 113 },
8a08048a
JO
114 .tid_conf_count = 7,
115 .tid_conf = {
116 [0] = {
117 .queue_id = 0,
118 .channel_type = CONF_CHANNEL_TYPE_DCF,
119 .tsid = CONF_TX_AC_BE,
120 .ps_scheme = CONF_PS_SCHEME_LEGACY,
121 .ack_policy = CONF_ACK_POLICY_LEGACY,
122 .apsd_conf = {0, 0},
123 },
124 [1] = {
125 .queue_id = 1,
126 .channel_type = CONF_CHANNEL_TYPE_DCF,
127 .tsid = CONF_TX_AC_BE,
128 .ps_scheme = CONF_PS_SCHEME_LEGACY,
129 .ack_policy = CONF_ACK_POLICY_LEGACY,
130 .apsd_conf = {0, 0},
51f2be24 131 },
8a08048a
JO
132 [2] = {
133 .queue_id = 2,
134 .channel_type = CONF_CHANNEL_TYPE_DCF,
135 .tsid = CONF_TX_AC_BE,
136 .ps_scheme = CONF_PS_SCHEME_LEGACY,
137 .ack_policy = CONF_ACK_POLICY_LEGACY,
138 .apsd_conf = {0, 0},
51f2be24 139 },
8a08048a
JO
140 [3] = {
141 .queue_id = 3,
142 .channel_type = CONF_CHANNEL_TYPE_DCF,
143 .tsid = CONF_TX_AC_BE,
144 .ps_scheme = CONF_PS_SCHEME_LEGACY,
145 .ack_policy = CONF_ACK_POLICY_LEGACY,
146 .apsd_conf = {0, 0},
147 },
148 [4] = {
149 .queue_id = 4,
150 .channel_type = CONF_CHANNEL_TYPE_DCF,
151 .tsid = CONF_TX_AC_BE,
152 .ps_scheme = CONF_PS_SCHEME_LEGACY,
153 .ack_policy = CONF_ACK_POLICY_LEGACY,
154 .apsd_conf = {0, 0},
155 },
156 [5] = {
157 .queue_id = 5,
158 .channel_type = CONF_CHANNEL_TYPE_DCF,
159 .tsid = CONF_TX_AC_BE,
160 .ps_scheme = CONF_PS_SCHEME_LEGACY,
161 .ack_policy = CONF_ACK_POLICY_LEGACY,
162 .apsd_conf = {0, 0},
163 },
164 [6] = {
165 .queue_id = 6,
166 .channel_type = CONF_CHANNEL_TYPE_DCF,
167 .tsid = CONF_TX_AC_BE,
168 .ps_scheme = CONF_PS_SCHEME_LEGACY,
169 .ack_policy = CONF_ACK_POLICY_LEGACY,
170 .apsd_conf = {0, 0},
171 }
172 },
173 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
174 .tx_compl_timeout = 5,
175 .tx_compl_threshold = 5
176 },
177 .conn = {
178 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
179 .listen_interval = 0,
180 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
181 .bcn_filt_ie_count = 1,
182 .bcn_filt_ie = {
183 [0] = {
184 .ie = WLAN_EID_CHANNEL_SWITCH,
185 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
51f2be24 186 }
47fab7d5 187 },
8a08048a
JO
188 .synch_fail_thold = 5,
189 .bss_lose_timeout = 100,
190 .beacon_rx_timeout = 10000,
191 .broadcast_timeout = 20000,
192 .rx_broadcast_in_ps = 1,
193 .ps_poll_threshold = 4,
194 .sig_trigger_count = 2,
195 .sig_trigger = {
196 [0] = {
197 .threshold = -75,
198 .pacing = 500,
199 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
200 .type = CONF_TRIG_EVENT_TYPE_EDGE,
201 .direction = CONF_TRIG_EVENT_DIR_LOW,
202 .hysteresis = 2,
203 .index = 0,
204 .enable = 1
47fab7d5 205 },
8a08048a
JO
206 [1] = {
207 .threshold = -75,
208 .pacing = 500,
209 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
210 .type = CONF_TRIG_EVENT_TYPE_EDGE,
211 .direction = CONF_TRIG_EVENT_DIR_HIGH,
212 .hysteresis = 2,
213 .index = 1,
214 .enable = 1
215 }
216 },
217 .sig_weights = {
218 .rssi_bcn_avg_weight = 10,
219 .rssi_pkt_avg_weight = 10,
220 .snr_bcn_avg_weight = 10,
221 .snr_pkt_avg_weight = 10
11f70f97
JO
222 },
223 .bet_enable = CONF_BET_MODE_ENABLE,
224 .bet_max_consecutive = 100
8a08048a
JO
225 },
226 .init = {
227 .sr_err_tbl = {
228 [0] = {
229 .len = 7,
230 .upper_limit = 0x03,
231 .values = {
232 0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
233 0x00 }
47fab7d5 234 },
8a08048a
JO
235 [1] = {
236 .len = 7,
237 .upper_limit = 0x03,
238 .values = {
239 0x18, 0x10, 0x05, 0xf6, 0xf0, 0xe8,
240 0x00 }
241 },
242 [2] = {
243 .len = 7,
244 .upper_limit = 0x03,
245 .values = {
246 0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
247 0x00 }
47fab7d5 248 }
8a08048a
JO
249 },
250 .sr_enable = 1,
251 .genparam = {
252 /*
253 * FIXME: The correct value CONF_REF_CLK_38_4_E
254 * causes the firmware to crash on boot.
255 * The value 5 apparently is an
256 * unnoficial XTAL configuration of the
257 * same frequency, which appears to work.
258 */
259 .ref_clk = 5,
260 .settling_time = 5,
261 .clk_valid_on_wakeup = 0,
262 .dc2dcmode = 0,
1ebec3d7 263 .single_dual_band = CONF_SINGLE_BAND,
8a08048a
JO
264 .tx_bip_fem_autodetect = 0,
265 .tx_bip_fem_manufacturer = 1,
266 .settings = 1,
267 },
268 .radioparam = {
8a08048a
JO
269 .rx_trace_loss = 10,
270 .tx_trace_loss = 10,
271 .rx_rssi_and_proc_compens = {
272 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8,
273 0xfc, 0x00, 0x08, 0x10, 0xf0, 0xf8,
274 0x00, 0x0a, 0x14 },
275 .rx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },
276 .tx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },
277 .rx_rssi_and_proc_compens_5 = {
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00 },
281 .tx_ref_pd_voltage = 0x24e,
282 .tx_ref_power = 0x78,
283 .tx_offset_db = 0x0,
284 .tx_rate_limits_normal = {
285 0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 },
286 .tx_rate_limits_degraded = {
287 0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 },
288 .tx_channel_limits_11b = {
289 0x22, 0x50, 0x50, 0x50, 0x50, 0x50,
290 0x50, 0x50, 0x50, 0x50, 0x22, 0x50,
291 0x22, 0x50 },
292 .tx_channel_limits_ofdm = {
293 0x20, 0x50, 0x50, 0x50, 0x50, 0x50,
294 0x50, 0x50, 0x50, 0x50, 0x20, 0x50,
295 0x20, 0x50 },
296 .tx_pdv_rate_offsets = {
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
298 .tx_ibias = {
299 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 },
300 .rx_fem_insertion_loss = 0x14,
1ebec3d7
TP
301 .tx_ref_pd_voltage_5 = {
302 0x0190, 0x01a4, 0x01c3, 0x01d8,
303 0x020a, 0x021c },
304 .tx_ref_power_5 = {
305 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
306 .tx_offset_db_5 = {
8a08048a 307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1ebec3d7
TP
308 .tx_rate_limits_normal_5 = {
309 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
8a08048a 310 .tx_rate_limits_degraded_5 = {
1ebec3d7 311 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
8a08048a 312 .tx_channel_limits_ofdm_5 = {
1ebec3d7
TP
313 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
314 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
315 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
316 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
317 0x50, 0x50, 0x50 },
8a08048a 318 .tx_pdv_rate_offsets_5 = {
1ebec3d7 319 0x01, 0x02, 0x02, 0x02, 0x02, 0x00 },
8a08048a 320 .tx_ibias_5 = {
1ebec3d7
TP
321 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
322 .rx_fem_insertion_loss_5 = {
323 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }
2b60100b 324 }
8a08048a
JO
325 }
326};
327
328static void wl1271_conf_init(struct wl1271 *wl)
329{
2b60100b
JO
330
331 /*
332 * This function applies the default configuration to the driver. This
333 * function is invoked upon driver load (spi probe.)
334 *
335 * The configuration is stored in a run-time structure in order to
336 * facilitate for run-time adjustment of any of the parameters. Making
337 * changes to the configuration structure will apply the new values on
338 * the next interface up (wl1271_op_start.)
339 */
340
341 /* apply driver default configuration */
8a08048a 342 memcpy(&wl->conf, &default_conf, sizeof(default_conf));
1ebec3d7
TP
343
344 if (wl1271_11a_enabled())
345 wl->conf.init.genparam.single_dual_band = CONF_DUAL_BAND;
2b60100b
JO
346}
347
348
f5fc0f86
LC
349static int wl1271_plt_init(struct wl1271 *wl)
350{
351 int ret;
352
353 ret = wl1271_acx_init_mem_config(wl);
354 if (ret < 0)
355 return ret;
356
357 ret = wl1271_cmd_data_path(wl, wl->channel, 1);
358 if (ret < 0)
359 return ret;
360
361 return 0;
362}
363
364static void wl1271_disable_interrupts(struct wl1271 *wl)
365{
366 disable_irq(wl->irq);
367}
368
369static void wl1271_power_off(struct wl1271 *wl)
370{
371 wl->set_power(false);
372}
373
374static void wl1271_power_on(struct wl1271 *wl)
375{
376 wl->set_power(true);
377}
378
c15f63bf
JO
379static void wl1271_fw_status(struct wl1271 *wl,
380 struct wl1271_fw_status *status)
f5fc0f86
LC
381{
382 u32 total = 0;
383 int i;
384
74621417
JO
385 wl1271_spi_read(wl, FW_STATUS_ADDR, status,
386 sizeof(*status), false);
f5fc0f86
LC
387
388 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
389 "drv_rx_counter = %d, tx_results_counter = %d)",
390 status->intr,
391 status->fw_rx_counter,
392 status->drv_rx_counter,
393 status->tx_results_counter);
394
395 /* update number of available TX blocks */
396 for (i = 0; i < NUM_TX_QUEUES; i++) {
397 u32 cnt = status->tx_released_blks[i] - wl->tx_blocks_freed[i];
398 wl->tx_blocks_freed[i] = status->tx_released_blks[i];
399 wl->tx_blocks_available += cnt;
400 total += cnt;
401 }
402
403 /* if more blocks are available now, schedule some tx work */
404 if (total && !skb_queue_empty(&wl->tx_queue))
a64b07e8 405 ieee80211_queue_work(wl->hw, &wl->tx_work);
f5fc0f86
LC
406
407 /* update the host-chipset time offset */
408 wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime;
409}
410
f5fc0f86
LC
411static void wl1271_irq_work(struct work_struct *work)
412{
f5fc0f86 413 int ret;
c15f63bf 414 u32 intr;
f5fc0f86
LC
415 struct wl1271 *wl =
416 container_of(work, struct wl1271, irq_work);
417
418 mutex_lock(&wl->mutex);
419
420 wl1271_debug(DEBUG_IRQ, "IRQ work");
421
422 if (wl->state == WL1271_STATE_OFF)
423 goto out;
424
425 ret = wl1271_ps_elp_wakeup(wl, true);
426 if (ret < 0)
427 goto out;
428
74621417 429 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
f5fc0f86 430
c15f63bf
JO
431 wl1271_fw_status(wl, wl->fw_status);
432 intr = wl->fw_status->intr;
f5fc0f86
LC
433 if (!intr) {
434 wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
435 goto out_sleep;
436 }
437
438 intr &= WL1271_INTR_MASK;
439
c15f63bf
JO
440 if (intr & (WL1271_ACX_INTR_EVENT_A |
441 WL1271_ACX_INTR_EVENT_B)) {
442 wl1271_debug(DEBUG_IRQ,
443 "WL1271_ACX_INTR_EVENT (0x%x)", intr);
444 if (intr & WL1271_ACX_INTR_EVENT_A)
445 wl1271_event_handle(wl, 0);
446 else
447 wl1271_event_handle(wl, 1);
448 }
f5fc0f86 449
c15f63bf
JO
450 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
451 wl1271_debug(DEBUG_IRQ,
452 "WL1271_ACX_INTR_INIT_COMPLETE");
f5fc0f86 453
c15f63bf
JO
454 if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
455 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
f5fc0f86 456
c15f63bf
JO
457 if (intr & WL1271_ACX_INTR_DATA) {
458 u8 tx_res_cnt = wl->fw_status->tx_results_counter -
459 wl->tx_results_count;
f5fc0f86 460
c15f63bf 461 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
f5fc0f86 462
c15f63bf
JO
463 /* check for tx results */
464 if (tx_res_cnt)
465 wl1271_tx_complete(wl, tx_res_cnt);
f5fc0f86 466
c15f63bf
JO
467 wl1271_rx(wl, wl->fw_status);
468 }
f5fc0f86
LC
469
470out_sleep:
74621417 471 wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
73d0a13c 472 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
f5fc0f86
LC
473 wl1271_ps_elp_sleep(wl);
474
475out:
476 mutex_unlock(&wl->mutex);
477}
478
479static irqreturn_t wl1271_irq(int irq, void *cookie)
480{
481 struct wl1271 *wl;
482 unsigned long flags;
483
484 wl1271_debug(DEBUG_IRQ, "IRQ");
485
486 wl = cookie;
487
488 /* complete the ELP completion */
489 spin_lock_irqsave(&wl->wl_lock, flags);
490 if (wl->elp_compl) {
491 complete(wl->elp_compl);
492 wl->elp_compl = NULL;
493 }
494
a64b07e8 495 ieee80211_queue_work(wl->hw, &wl->irq_work);
f5fc0f86
LC
496 spin_unlock_irqrestore(&wl->wl_lock, flags);
497
498 return IRQ_HANDLED;
499}
500
501static int wl1271_fetch_firmware(struct wl1271 *wl)
502{
503 const struct firmware *fw;
504 int ret;
505
506 ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev);
507
508 if (ret < 0) {
509 wl1271_error("could not get firmware: %d", ret);
510 return ret;
511 }
512
513 if (fw->size % 4) {
514 wl1271_error("firmware size is not multiple of 32 bits: %zu",
515 fw->size);
516 ret = -EILSEQ;
517 goto out;
518 }
519
520 wl->fw_len = fw->size;
1fba4974 521 wl->fw = vmalloc(wl->fw_len);
f5fc0f86
LC
522
523 if (!wl->fw) {
524 wl1271_error("could not allocate memory for the firmware");
525 ret = -ENOMEM;
526 goto out;
527 }
528
529 memcpy(wl->fw, fw->data, wl->fw_len);
530
531 ret = 0;
532
533out:
534 release_firmware(fw);
535
536 return ret;
537}
538
539static int wl1271_fetch_nvs(struct wl1271 *wl)
540{
541 const struct firmware *fw;
542 int ret;
543
544 ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev);
545
546 if (ret < 0) {
547 wl1271_error("could not get nvs file: %d", ret);
548 return ret;
549 }
550
551 if (fw->size % 4) {
552 wl1271_error("nvs size is not multiple of 32 bits: %zu",
553 fw->size);
554 ret = -EILSEQ;
555 goto out;
556 }
557
558 wl->nvs_len = fw->size;
559 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
560
561 if (!wl->nvs) {
562 wl1271_error("could not allocate memory for the nvs file");
563 ret = -ENOMEM;
564 goto out;
565 }
566
567 memcpy(wl->nvs, fw->data, wl->nvs_len);
568
569 ret = 0;
570
571out:
572 release_firmware(fw);
573
574 return ret;
575}
576
577static void wl1271_fw_wakeup(struct wl1271 *wl)
578{
579 u32 elp_reg;
580
581 elp_reg = ELPCTRL_WAKE_UP;
74621417 582 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
f5fc0f86
LC
583}
584
585static int wl1271_setup(struct wl1271 *wl)
586{
587 wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
588 if (!wl->fw_status)
589 return -ENOMEM;
590
591 wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
592 if (!wl->tx_res_if) {
593 kfree(wl->fw_status);
594 return -ENOMEM;
595 }
596
597 INIT_WORK(&wl->irq_work, wl1271_irq_work);
598 INIT_WORK(&wl->tx_work, wl1271_tx_work);
599 return 0;
600}
601
602static int wl1271_chip_wakeup(struct wl1271 *wl)
603{
451de97a 604 struct wl1271_partition_set partition;
f5fc0f86
LC
605 int ret = 0;
606
607 wl1271_power_on(wl);
608 msleep(WL1271_POWER_ON_SLEEP);
609 wl1271_spi_reset(wl);
610 wl1271_spi_init(wl);
611
612 /* We don't need a real memory partition here, because we only want
613 * to use the registers at this point. */
451de97a
JO
614 memset(&partition, 0, sizeof(partition));
615 partition.reg.start = REGISTERS_BASE;
616 partition.reg.size = REGISTERS_DOWN_SIZE;
617 wl1271_set_partition(wl, &partition);
f5fc0f86
LC
618
619 /* ELP module wake up */
620 wl1271_fw_wakeup(wl);
621
622 /* whal_FwCtrl_BootSm() */
623
624 /* 0. read chip id from CHIP_ID */
74621417 625 wl->chip.id = wl1271_spi_read32(wl, CHIP_ID_B);
f5fc0f86
LC
626
627 /* 1. check if chip id is valid */
628
629 switch (wl->chip.id) {
630 case CHIP_ID_1271_PG10:
631 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
632 wl->chip.id);
633
634 ret = wl1271_setup(wl);
635 if (ret < 0)
eb5b28d0 636 goto out_power_off;
f5fc0f86
LC
637 break;
638 case CHIP_ID_1271_PG20:
639 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
640 wl->chip.id);
641
642 ret = wl1271_setup(wl);
643 if (ret < 0)
eb5b28d0 644 goto out_power_off;
f5fc0f86
LC
645 break;
646 default:
647 wl1271_error("unsupported chip id: 0x%x", wl->chip.id);
648 ret = -ENODEV;
eb5b28d0 649 goto out_power_off;
f5fc0f86
LC
650 }
651
652 if (wl->fw == NULL) {
653 ret = wl1271_fetch_firmware(wl);
654 if (ret < 0)
eb5b28d0 655 goto out_power_off;
f5fc0f86
LC
656 }
657
658 /* No NVS from netlink, try to get it from the filesystem */
659 if (wl->nvs == NULL) {
660 ret = wl1271_fetch_nvs(wl);
661 if (ret < 0)
eb5b28d0 662 goto out_power_off;
f5fc0f86
LC
663 }
664
eb5b28d0
JO
665 goto out;
666
667out_power_off:
668 wl1271_power_off(wl);
669
f5fc0f86
LC
670out:
671 return ret;
672}
673
c87dec9f
JO
674struct wl1271_filter_params {
675 unsigned int filters;
676 unsigned int changed;
677 int mc_list_length;
678 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
679};
680
681#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
682 FIF_ALLMULTI | \
683 FIF_FCSFAIL | \
684 FIF_BCN_PRBRESP_PROMISC | \
685 FIF_CONTROL | \
686 FIF_OTHER_BSS)
687
f5fc0f86
LC
688static void wl1271_filter_work(struct work_struct *work)
689{
690 struct wl1271 *wl =
691 container_of(work, struct wl1271, filter_work);
c87dec9f
JO
692 struct wl1271_filter_params *fp;
693 unsigned long flags;
694 bool enabled = true;
f5fc0f86
LC
695 int ret;
696
c87dec9f
JO
697 /* first, get the filter parameters */
698 spin_lock_irqsave(&wl->wl_lock, flags);
699 fp = wl->filter_params;
700 wl->filter_params = NULL;
701 spin_unlock_irqrestore(&wl->wl_lock, flags);
702
703 if (!fp)
704 return;
705
706 /* then, lock the mutex without risk of lock-up */
f5fc0f86
LC
707 mutex_lock(&wl->mutex);
708
709 if (wl->state == WL1271_STATE_OFF)
710 goto out;
711
712 ret = wl1271_ps_elp_wakeup(wl, false);
713 if (ret < 0)
714 goto out;
715
c87dec9f
JO
716 /* configure the mc filter regardless of the changed flags */
717 if (fp->filters & FIF_ALLMULTI)
718 enabled = false;
719
720 ret = wl1271_acx_group_address_tbl(wl, enabled,
721 fp->mc_list, fp->mc_list_length);
722 if (ret < 0)
723 goto out_sleep;
724
725 /* determine, whether supported filter values have changed */
726 if (fp->changed == 0)
727 goto out;
728
729 /* apply configured filters */
0535d9f4 730 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
f5fc0f86
LC
731 if (ret < 0)
732 goto out_sleep;
733
734out_sleep:
735 wl1271_ps_elp_sleep(wl);
736
737out:
738 mutex_unlock(&wl->mutex);
c87dec9f 739 kfree(fp);
f5fc0f86
LC
740}
741
742int wl1271_plt_start(struct wl1271 *wl)
743{
744 int ret;
745
746 mutex_lock(&wl->mutex);
747
748 wl1271_notice("power up");
749
750 if (wl->state != WL1271_STATE_OFF) {
751 wl1271_error("cannot go into PLT state because not "
752 "in off state: %d", wl->state);
753 ret = -EBUSY;
754 goto out;
755 }
756
757 wl->state = WL1271_STATE_PLT;
758
759 ret = wl1271_chip_wakeup(wl);
760 if (ret < 0)
761 goto out;
762
763 ret = wl1271_boot(wl);
764 if (ret < 0)
eb5b28d0 765 goto out_power_off;
f5fc0f86
LC
766
767 wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
768
769 ret = wl1271_plt_init(wl);
770 if (ret < 0)
eb5b28d0
JO
771 goto out_irq_disable;
772
773 goto out;
774
775out_irq_disable:
776 wl1271_disable_interrupts(wl);
777
778out_power_off:
779 wl1271_power_off(wl);
f5fc0f86
LC
780
781out:
782 mutex_unlock(&wl->mutex);
783
784 return ret;
785}
786
787int wl1271_plt_stop(struct wl1271 *wl)
788{
789 int ret = 0;
790
791 mutex_lock(&wl->mutex);
792
793 wl1271_notice("power down");
794
795 if (wl->state != WL1271_STATE_PLT) {
796 wl1271_error("cannot power down because not in PLT "
797 "state: %d", wl->state);
798 ret = -EBUSY;
799 goto out;
800 }
801
802 wl1271_disable_interrupts(wl);
803 wl1271_power_off(wl);
804
805 wl->state = WL1271_STATE_OFF;
806
807out:
808 mutex_unlock(&wl->mutex);
809
810 return ret;
811}
812
813
814static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
815{
816 struct wl1271 *wl = hw->priv;
817
818 skb_queue_tail(&wl->tx_queue, skb);
819
820 /*
821 * The chip specific setup must run before the first TX packet -
822 * before that, the tx_work will not be initialized!
823 */
824
a64b07e8 825 ieee80211_queue_work(wl->hw, &wl->tx_work);
f5fc0f86
LC
826
827 /*
828 * The workqueue is slow to process the tx_queue and we need stop
829 * the queue here, otherwise the queue will get too long.
830 */
831 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) {
832 ieee80211_stop_queues(wl->hw);
833
834 /*
835 * FIXME: this is racy, the variable is not properly
836 * protected. Maybe fix this by removing the stupid
837 * variable altogether and checking the real queue state?
838 */
839 wl->tx_queue_stopped = true;
840 }
841
842 return NETDEV_TX_OK;
843}
844
845static int wl1271_op_start(struct ieee80211_hw *hw)
846{
847 struct wl1271 *wl = hw->priv;
848 int ret = 0;
849
850 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
851
852 mutex_lock(&wl->mutex);
853
854 if (wl->state != WL1271_STATE_OFF) {
855 wl1271_error("cannot start because not in off state: %d",
856 wl->state);
857 ret = -EBUSY;
858 goto out;
859 }
860
861 ret = wl1271_chip_wakeup(wl);
862 if (ret < 0)
863 goto out;
864
865 ret = wl1271_boot(wl);
866 if (ret < 0)
eb5b28d0 867 goto out_power_off;
f5fc0f86
LC
868
869 ret = wl1271_hw_init(wl);
870 if (ret < 0)
eb5b28d0 871 goto out_irq_disable;
f5fc0f86
LC
872
873 wl->state = WL1271_STATE_ON;
874
875 wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
876
eb5b28d0 877 goto out;
f5fc0f86 878
eb5b28d0
JO
879out_irq_disable:
880 wl1271_disable_interrupts(wl);
881
882out_power_off:
883 wl1271_power_off(wl);
884
885out:
f5fc0f86
LC
886 mutex_unlock(&wl->mutex);
887
888 return ret;
889}
890
891static void wl1271_op_stop(struct ieee80211_hw *hw)
892{
893 struct wl1271 *wl = hw->priv;
c87dec9f 894 unsigned long flags;
f5fc0f86
LC
895 int i;
896
897 wl1271_info("down");
898
899 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
900
c87dec9f
JO
901 /* complete/cancel ongoing work */
902 cancel_work_sync(&wl->filter_work);
903 spin_lock_irqsave(&wl->wl_lock, flags);
904 kfree(wl->filter_params);
905 wl->filter_params = NULL;
906 spin_unlock_irqrestore(&wl->wl_lock, flags);
907
f5fc0f86
LC
908 mutex_lock(&wl->mutex);
909
910 WARN_ON(wl->state != WL1271_STATE_ON);
911
912 if (wl->scanning) {
913 mutex_unlock(&wl->mutex);
914 ieee80211_scan_completed(wl->hw, true);
915 mutex_lock(&wl->mutex);
916 wl->scanning = false;
917 }
918
919 wl->state = WL1271_STATE_OFF;
920
921 wl1271_disable_interrupts(wl);
922
923 mutex_unlock(&wl->mutex);
924
925 cancel_work_sync(&wl->irq_work);
926 cancel_work_sync(&wl->tx_work);
927 cancel_work_sync(&wl->filter_work);
928
929 mutex_lock(&wl->mutex);
930
931 /* let's notify MAC80211 about the remaining pending TX frames */
932 wl1271_tx_flush(wl);
933 wl1271_power_off(wl);
934
935 memset(wl->bssid, 0, ETH_ALEN);
936 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
937 wl->ssid_len = 0;
f5fc0f86 938 wl->bss_type = MAX_BSS_TYPE;
8a5a37a6 939 wl->band = IEEE80211_BAND_2GHZ;
f5fc0f86
LC
940
941 wl->rx_counter = 0;
942 wl->elp = false;
943 wl->psm = 0;
944 wl->tx_queue_stopped = false;
945 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
946 wl->tx_blocks_available = 0;
947 wl->tx_results_count = 0;
948 wl->tx_packets_count = 0;
ac4e4ce5
JO
949 wl->tx_security_last_seq = 0;
950 wl->tx_security_seq_16 = 0;
951 wl->tx_security_seq_32 = 0;
f5fc0f86
LC
952 wl->time_offset = 0;
953 wl->session_counter = 0;
d6e19d13
LC
954 wl->joined = false;
955
f5fc0f86
LC
956 for (i = 0; i < NUM_TX_QUEUES; i++)
957 wl->tx_blocks_freed[i] = 0;
958
959 wl1271_debugfs_reset(wl);
960 mutex_unlock(&wl->mutex);
961}
962
963static int wl1271_op_add_interface(struct ieee80211_hw *hw,
964 struct ieee80211_if_init_conf *conf)
965{
966 struct wl1271 *wl = hw->priv;
f5fc0f86
LC
967 int ret = 0;
968
e5539bcb
JL
969 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
970 conf->type, conf->mac_addr);
f5fc0f86
LC
971
972 mutex_lock(&wl->mutex);
b771eee5
JO
973 if (wl->vif) {
974 ret = -EBUSY;
975 goto out;
976 }
977
978 wl->vif = conf->vif;
f5fc0f86
LC
979
980 switch (conf->type) {
981 case NL80211_IFTYPE_STATION:
982 wl->bss_type = BSS_TYPE_STA_BSS;
983 break;
984 case NL80211_IFTYPE_ADHOC:
985 wl->bss_type = BSS_TYPE_IBSS;
986 break;
987 default:
988 ret = -EOPNOTSUPP;
989 goto out;
990 }
991
992 /* FIXME: what if conf->mac_addr changes? */
993
994out:
995 mutex_unlock(&wl->mutex);
996 return ret;
997}
998
999static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1000 struct ieee80211_if_init_conf *conf)
1001{
b771eee5
JO
1002 struct wl1271 *wl = hw->priv;
1003
1004 mutex_lock(&wl->mutex);
f5fc0f86 1005 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
b771eee5
JO
1006 wl->vif = NULL;
1007 mutex_unlock(&wl->mutex);
f5fc0f86
LC
1008}
1009
1010#if 0
1011static int wl1271_op_config_interface(struct ieee80211_hw *hw,
1012 struct ieee80211_vif *vif,
1013 struct ieee80211_if_conf *conf)
1014{
1015 struct wl1271 *wl = hw->priv;
1016 struct sk_buff *beacon;
f5fc0f86
LC
1017 int ret;
1018
3264690b
DM
1019 wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
1020 conf->bssid);
f5fc0f86
LC
1021 wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
1022 conf->ssid_len);
1023
1024 mutex_lock(&wl->mutex);
1025
1026 ret = wl1271_ps_elp_wakeup(wl, false);
1027 if (ret < 0)
1028 goto out;
1029
ae751bab
LC
1030 if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) {
1031 wl1271_debug(DEBUG_MAC80211, "bssid changed");
1032
1033 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
1034
1035 ret = wl1271_cmd_join(wl);
1036 if (ret < 0)
1037 goto out_sleep;
1038 }
f5fc0f86
LC
1039
1040 ret = wl1271_cmd_build_null_data(wl);
1041 if (ret < 0)
1042 goto out_sleep;
1043
1044 wl->ssid_len = conf->ssid_len;
1045 if (wl->ssid_len)
1046 memcpy(wl->ssid, conf->ssid, wl->ssid_len);
1047
f5fc0f86
LC
1048 if (conf->changed & IEEE80211_IFCC_BEACON) {
1049 beacon = ieee80211_beacon_get(hw, vif);
1050 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1051 beacon->data, beacon->len);
1052
1053 if (ret < 0) {
1054 dev_kfree_skb(beacon);
1055 goto out_sleep;
1056 }
1057
1058 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
1059 beacon->data, beacon->len);
1060
1061 dev_kfree_skb(beacon);
1062
f5fc0f86
LC
1063 if (ret < 0)
1064 goto out_sleep;
1065 }
1066
1067out_sleep:
1068 wl1271_ps_elp_sleep(wl);
1069
1070out:
1071 mutex_unlock(&wl->mutex);
1072
1073 return ret;
1074}
1075#endif
1076
1077static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1078{
1079 struct wl1271 *wl = hw->priv;
1080 struct ieee80211_conf *conf = &hw->conf;
1081 int channel, ret = 0;
1082
1083 channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
1084
1085 wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
1086 channel,
1087 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
1088 conf->power_level);
1089
1090 mutex_lock(&wl->mutex);
1091
8a5a37a6
JO
1092 wl->band = conf->channel->band;
1093
f5fc0f86
LC
1094 ret = wl1271_ps_elp_wakeup(wl, false);
1095 if (ret < 0)
1096 goto out;
1097
1098 if (channel != wl->channel) {
ae751bab
LC
1099 /*
1100 * We assume that the stack will configure the right channel
1101 * before associating, so we don't need to send a join
1102 * command here. We will join the right channel when the
1103 * BSSID changes
1104 */
f5fc0f86 1105 wl->channel = channel;
f5fc0f86
LC
1106 }
1107
1108 ret = wl1271_cmd_build_null_data(wl);
1109 if (ret < 0)
1110 goto out_sleep;
1111
1112 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
1113 wl1271_info("psm enabled");
1114
1115 wl->psm_requested = true;
1116
1117 /*
1118 * We enter PSM only if we're already associated.
1119 * If we're not, we'll enter it when joining an SSID,
1120 * through the bss_info_changed() hook.
1121 */
1122 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
1123 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1124 wl->psm_requested) {
1125 wl1271_info("psm disabled");
1126
1127 wl->psm_requested = false;
1128
1129 if (wl->psm)
1130 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
1131 }
1132
1133 if (conf->power_level != wl->power_level) {
1134 ret = wl1271_acx_tx_power(wl, conf->power_level);
1135 if (ret < 0)
1136 goto out;
1137
1138 wl->power_level = conf->power_level;
1139 }
1140
1141out_sleep:
1142 wl1271_ps_elp_sleep(wl);
1143
1144out:
1145 mutex_unlock(&wl->mutex);
1146
1147 return ret;
1148}
1149
c87dec9f
JO
1150static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
1151 struct dev_addr_list *mc_list)
1152{
1153 struct wl1271 *wl = hw->priv;
1154 struct wl1271_filter_params *fp;
1155 unsigned long flags;
1156 int i;
1157
1158 /*
1159 * FIXME: we should return a hash that will be passed to
1160 * configure_filter() instead of saving everything in the context.
1161 */
1162
74441130 1163 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
c87dec9f
JO
1164 if (!fp) {
1165 wl1271_error("Out of memory setting filters.");
1166 return 0;
1167 }
1168
1169 /* update multicast filtering parameters */
1170 if (mc_count > ACX_MC_ADDRESS_GROUP_MAX) {
1171 mc_count = 0;
1172 fp->filters |= FIF_ALLMULTI;
1173 }
1174
1175 fp->mc_list_length = 0;
1176 for (i = 0; i < mc_count; i++) {
1177 if (mc_list->da_addrlen == ETH_ALEN) {
1178 memcpy(fp->mc_list[fp->mc_list_length],
1179 mc_list->da_addr, ETH_ALEN);
1180 fp->mc_list_length++;
1181 } else
1182 wl1271_warning("Unknown mc address length.");
74441130 1183 mc_list = mc_list->next;
c87dec9f
JO
1184 }
1185
0535d9f4
LC
1186 /* FIXME: We still need to set our filters properly */
1187
c87dec9f
JO
1188 spin_lock_irqsave(&wl->wl_lock, flags);
1189 kfree(wl->filter_params);
1190 wl->filter_params = fp;
1191 spin_unlock_irqrestore(&wl->wl_lock, flags);
1192
1193 return 1;
1194}
f5fc0f86
LC
1195
1196static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1197 unsigned int changed,
c87dec9f 1198 unsigned int *total, u64 multicast)
f5fc0f86
LC
1199{
1200 struct wl1271 *wl = hw->priv;
1201
1202 wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter");
1203
1204 *total &= WL1271_SUPPORTED_FILTERS;
1205 changed &= WL1271_SUPPORTED_FILTERS;
1206
c87dec9f 1207 if (!multicast)
f5fc0f86
LC
1208 return;
1209
f5fc0f86 1210 /*
c87dec9f
JO
1211 * FIXME: for now we are still using a workqueue for filter
1212 * configuration, but with the new mac80211, this is not needed,
1213 * since configure_filter can now sleep. We now have
1214 * prepare_multicast, which needs to be atomic instead.
f5fc0f86 1215 */
c87dec9f
JO
1216
1217 /* store current filter config */
1218 wl->filter_params->filters = *total;
1219 wl->filter_params->changed = changed;
1220
1221 ieee80211_queue_work(wl->hw, &wl->filter_work);
f5fc0f86
LC
1222}
1223
1224static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1225 struct ieee80211_vif *vif,
1226 struct ieee80211_sta *sta,
1227 struct ieee80211_key_conf *key_conf)
1228{
1229 struct wl1271 *wl = hw->priv;
1230 const u8 *addr;
1231 int ret;
ac4e4ce5
JO
1232 u32 tx_seq_32 = 0;
1233 u16 tx_seq_16 = 0;
f5fc0f86
LC
1234 u8 key_type;
1235
1236 static const u8 bcast_addr[ETH_ALEN] =
1237 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1238
1239 wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
1240
1241 addr = sta ? sta->addr : bcast_addr;
1242
1243 wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
1244 wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
1245 wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
1246 key_conf->alg, key_conf->keyidx,
1247 key_conf->keylen, key_conf->flags);
1248 wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
1249
1250 if (is_zero_ether_addr(addr)) {
1251 /* We dont support TX only encryption */
1252 ret = -EOPNOTSUPP;
1253 goto out;
1254 }
1255
1256 mutex_lock(&wl->mutex);
1257
1258 ret = wl1271_ps_elp_wakeup(wl, false);
1259 if (ret < 0)
1260 goto out_unlock;
1261
1262 switch (key_conf->alg) {
1263 case ALG_WEP:
1264 key_type = KEY_WEP;
1265
1266 key_conf->hw_key_idx = key_conf->keyidx;
1267 break;
1268 case ALG_TKIP:
1269 key_type = KEY_TKIP;
1270
1271 key_conf->hw_key_idx = key_conf->keyidx;
ac4e4ce5
JO
1272 tx_seq_32 = wl->tx_security_seq_32;
1273 tx_seq_16 = wl->tx_security_seq_16;
f5fc0f86
LC
1274 break;
1275 case ALG_CCMP:
1276 key_type = KEY_AES;
1277
1278 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
ac4e4ce5
JO
1279 tx_seq_32 = wl->tx_security_seq_32;
1280 tx_seq_16 = wl->tx_security_seq_16;
f5fc0f86
LC
1281 break;
1282 default:
1283 wl1271_error("Unknown key algo 0x%x", key_conf->alg);
1284
1285 ret = -EOPNOTSUPP;
1286 goto out_sleep;
1287 }
1288
1289 switch (cmd) {
1290 case SET_KEY:
1291 ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE,
1292 key_conf->keyidx, key_type,
1293 key_conf->keylen, key_conf->key,
ac4e4ce5 1294 addr, tx_seq_32, tx_seq_16);
f5fc0f86
LC
1295 if (ret < 0) {
1296 wl1271_error("Could not add or replace key");
1297 goto out_sleep;
1298 }
1299 break;
1300
1301 case DISABLE_KEY:
1302 ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
1303 key_conf->keyidx, key_type,
1304 key_conf->keylen, key_conf->key,
ac4e4ce5 1305 addr, 0, 0);
f5fc0f86
LC
1306 if (ret < 0) {
1307 wl1271_error("Could not remove key");
1308 goto out_sleep;
1309 }
1310 break;
1311
1312 default:
1313 wl1271_error("Unsupported key cmd 0x%x", cmd);
1314 ret = -EOPNOTSUPP;
1315 goto out_sleep;
1316
1317 break;
1318 }
1319
1320out_sleep:
1321 wl1271_ps_elp_sleep(wl);
1322
1323out_unlock:
1324 mutex_unlock(&wl->mutex);
1325
1326out:
1327 return ret;
1328}
1329
1330static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1331 struct cfg80211_scan_request *req)
1332{
1333 struct wl1271 *wl = hw->priv;
1334 int ret;
1335 u8 *ssid = NULL;
abb0b3bf 1336 size_t len = 0;
f5fc0f86
LC
1337
1338 wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");
1339
1340 if (req->n_ssids) {
1341 ssid = req->ssids[0].ssid;
abb0b3bf 1342 len = req->ssids[0].ssid_len;
f5fc0f86
LC
1343 }
1344
1345 mutex_lock(&wl->mutex);
1346
1347 ret = wl1271_ps_elp_wakeup(wl, false);
1348 if (ret < 0)
1349 goto out;
1350
abb0b3bf
TP
1351 if (wl1271_11a_enabled())
1352 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0,
1353 WL1271_SCAN_BAND_DUAL, 3);
1354 else
1355 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0,
1356 WL1271_SCAN_BAND_2_4_GHZ, 3);
f5fc0f86
LC
1357
1358 wl1271_ps_elp_sleep(wl);
1359
1360out:
1361 mutex_unlock(&wl->mutex);
1362
1363 return ret;
1364}
1365
1366static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1367{
1368 struct wl1271 *wl = hw->priv;
1369 int ret;
1370
1371 mutex_lock(&wl->mutex);
1372
1373 ret = wl1271_ps_elp_wakeup(wl, false);
1374 if (ret < 0)
1375 goto out;
1376
1377 ret = wl1271_acx_rts_threshold(wl, (u16) value);
1378 if (ret < 0)
1379 wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
1380
1381 wl1271_ps_elp_sleep(wl);
1382
1383out:
1384 mutex_unlock(&wl->mutex);
1385
1386 return ret;
1387}
1388
8a5a37a6
JO
1389static u32 wl1271_enabled_rates_get(struct wl1271 *wl, u64 basic_rate_set)
1390{
1391 struct ieee80211_supported_band *band;
1392 u32 enabled_rates = 0;
1393 int bit;
1394
1395 band = wl->hw->wiphy->bands[wl->band];
1396 for (bit = 0; bit < band->n_bitrates; bit++) {
1397 if (basic_rate_set & 0x1)
1398 enabled_rates |= band->bitrates[bit].hw_value;
1399 basic_rate_set >>= 1;
1400 }
1401
1402 return enabled_rates;
1403}
1404
f5fc0f86
LC
1405static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1406 struct ieee80211_vif *vif,
1407 struct ieee80211_bss_conf *bss_conf,
1408 u32 changed)
1409{
1410 enum wl1271_cmd_ps_mode mode;
1411 struct wl1271 *wl = hw->priv;
1412 int ret;
1413
1414 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
1415
1416 mutex_lock(&wl->mutex);
1417
1418 ret = wl1271_ps_elp_wakeup(wl, false);
1419 if (ret < 0)
1420 goto out;
1421
1422 if (changed & BSS_CHANGED_ASSOC) {
1423 if (bss_conf->assoc) {
1424 wl->aid = bss_conf->aid;
1425
ae751bab
LC
1426 /*
1427 * with wl1271, we don't need to update the
1428 * beacon_int and dtim_period, because the firmware
1429 * updates it by itself when the first beacon is
1430 * received after a join.
1431 */
f5fc0f86
LC
1432 ret = wl1271_cmd_build_ps_poll(wl, wl->aid);
1433 if (ret < 0)
1434 goto out_sleep;
1435
1436 ret = wl1271_acx_aid(wl, wl->aid);
1437 if (ret < 0)
1438 goto out_sleep;
1439
1440 /* If we want to go in PSM but we're not there yet */
1441 if (wl->psm_requested && !wl->psm) {
1442 mode = STATION_POWER_SAVE_MODE;
1443 ret = wl1271_ps_set_mode(wl, mode);
1444 if (ret < 0)
1445 goto out_sleep;
1446 }
d94cd297
JO
1447 } else {
1448 /* use defaults when not associated */
d94cd297
JO
1449 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
1450 wl->aid = 0;
f5fc0f86 1451 }
d94cd297 1452
f5fc0f86 1453 }
8a5a37a6 1454
f5fc0f86
LC
1455 if (changed & BSS_CHANGED_ERP_SLOT) {
1456 if (bss_conf->use_short_slot)
1457 ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT);
1458 else
1459 ret = wl1271_acx_slot(wl, SLOT_TIME_LONG);
1460 if (ret < 0) {
1461 wl1271_warning("Set slot time failed %d", ret);
1462 goto out_sleep;
1463 }
1464 }
1465
1466 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1467 if (bss_conf->use_short_preamble)
1468 wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
1469 else
1470 wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
1471 }
1472
1473 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1474 if (bss_conf->use_cts_prot)
1475 ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE);
1476 else
1477 ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE);
1478 if (ret < 0) {
1479 wl1271_warning("Set ctsprotect failed %d", ret);
1480 goto out_sleep;
1481 }
1482 }
1483
8a5a37a6 1484 if (changed & BSS_CHANGED_BASIC_RATES) {
d94cd297 1485 wl->basic_rate_set = wl1271_enabled_rates_get(
8a5a37a6 1486 wl, bss_conf->basic_rates);
d94cd297 1487
ae751bab 1488 ret = wl1271_acx_rate_policies(wl, wl->basic_rate_set);
8a5a37a6
JO
1489 if (ret < 0) {
1490 wl1271_warning("Set rate policies failed %d", ret);
1491 goto out_sleep;
1492 }
1493 }
1494
f5fc0f86
LC
1495out_sleep:
1496 wl1271_ps_elp_sleep(wl);
1497
1498out:
1499 mutex_unlock(&wl->mutex);
1500}
1501
1502
1503/* can't be const, mac80211 writes to this */
1504static struct ieee80211_rate wl1271_rates[] = {
1505 { .bitrate = 10,
2b60100b
JO
1506 .hw_value = CONF_HW_BIT_RATE_1MBPS,
1507 .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
f5fc0f86 1508 { .bitrate = 20,
2b60100b
JO
1509 .hw_value = CONF_HW_BIT_RATE_2MBPS,
1510 .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
f5fc0f86
LC
1511 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1512 { .bitrate = 55,
2b60100b
JO
1513 .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
1514 .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
f5fc0f86
LC
1515 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1516 { .bitrate = 110,
2b60100b
JO
1517 .hw_value = CONF_HW_BIT_RATE_11MBPS,
1518 .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
f5fc0f86
LC
1519 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
1520 { .bitrate = 60,
2b60100b
JO
1521 .hw_value = CONF_HW_BIT_RATE_6MBPS,
1522 .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
f5fc0f86 1523 { .bitrate = 90,
2b60100b
JO
1524 .hw_value = CONF_HW_BIT_RATE_9MBPS,
1525 .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
f5fc0f86 1526 { .bitrate = 120,
2b60100b
JO
1527 .hw_value = CONF_HW_BIT_RATE_12MBPS,
1528 .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
f5fc0f86 1529 { .bitrate = 180,
2b60100b
JO
1530 .hw_value = CONF_HW_BIT_RATE_18MBPS,
1531 .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
f5fc0f86 1532 { .bitrate = 240,
2b60100b
JO
1533 .hw_value = CONF_HW_BIT_RATE_24MBPS,
1534 .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
f5fc0f86 1535 { .bitrate = 360,
2b60100b
JO
1536 .hw_value = CONF_HW_BIT_RATE_36MBPS,
1537 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
f5fc0f86 1538 { .bitrate = 480,
2b60100b
JO
1539 .hw_value = CONF_HW_BIT_RATE_48MBPS,
1540 .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
f5fc0f86 1541 { .bitrate = 540,
2b60100b
JO
1542 .hw_value = CONF_HW_BIT_RATE_54MBPS,
1543 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
f5fc0f86
LC
1544};
1545
1546/* can't be const, mac80211 writes to this */
1547static struct ieee80211_channel wl1271_channels[] = {
1548 { .hw_value = 1, .center_freq = 2412},
1549 { .hw_value = 2, .center_freq = 2417},
1550 { .hw_value = 3, .center_freq = 2422},
1551 { .hw_value = 4, .center_freq = 2427},
1552 { .hw_value = 5, .center_freq = 2432},
1553 { .hw_value = 6, .center_freq = 2437},
1554 { .hw_value = 7, .center_freq = 2442},
1555 { .hw_value = 8, .center_freq = 2447},
1556 { .hw_value = 9, .center_freq = 2452},
1557 { .hw_value = 10, .center_freq = 2457},
1558 { .hw_value = 11, .center_freq = 2462},
1559 { .hw_value = 12, .center_freq = 2467},
1560 { .hw_value = 13, .center_freq = 2472},
1561};
1562
1563/* can't be const, mac80211 writes to this */
1564static struct ieee80211_supported_band wl1271_band_2ghz = {
1565 .channels = wl1271_channels,
1566 .n_channels = ARRAY_SIZE(wl1271_channels),
1567 .bitrates = wl1271_rates,
1568 .n_bitrates = ARRAY_SIZE(wl1271_rates),
1569};
1570
1ebec3d7
TP
1571/* 5 GHz data rates for WL1273 */
1572static struct ieee80211_rate wl1271_rates_5ghz[] = {
1573 { .bitrate = 60,
1574 .hw_value = CONF_HW_BIT_RATE_6MBPS,
1575 .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
1576 { .bitrate = 90,
1577 .hw_value = CONF_HW_BIT_RATE_9MBPS,
1578 .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
1579 { .bitrate = 120,
1580 .hw_value = CONF_HW_BIT_RATE_12MBPS,
1581 .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
1582 { .bitrate = 180,
1583 .hw_value = CONF_HW_BIT_RATE_18MBPS,
1584 .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
1585 { .bitrate = 240,
1586 .hw_value = CONF_HW_BIT_RATE_24MBPS,
1587 .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
1588 { .bitrate = 360,
1589 .hw_value = CONF_HW_BIT_RATE_36MBPS,
1590 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
1591 { .bitrate = 480,
1592 .hw_value = CONF_HW_BIT_RATE_48MBPS,
1593 .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
1594 { .bitrate = 540,
1595 .hw_value = CONF_HW_BIT_RATE_54MBPS,
1596 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
1597};
1598
1599/* 5 GHz band channels for WL1273 */
1600static struct ieee80211_channel wl1271_channels_5ghz[] = {
1601 { .hw_value = 183, .center_freq = 4915},
1602 { .hw_value = 184, .center_freq = 4920},
1603 { .hw_value = 185, .center_freq = 4925},
1604 { .hw_value = 187, .center_freq = 4935},
1605 { .hw_value = 188, .center_freq = 4940},
1606 { .hw_value = 189, .center_freq = 4945},
1607 { .hw_value = 192, .center_freq = 4960},
1608 { .hw_value = 196, .center_freq = 4980},
1609 { .hw_value = 7, .center_freq = 5035},
1610 { .hw_value = 8, .center_freq = 5040},
1611 { .hw_value = 9, .center_freq = 5045},
1612 { .hw_value = 11, .center_freq = 5055},
1613 { .hw_value = 12, .center_freq = 5060},
1614 { .hw_value = 16, .center_freq = 5080},
1615 { .hw_value = 34, .center_freq = 5170},
1616 { .hw_value = 36, .center_freq = 5180},
1617 { .hw_value = 38, .center_freq = 5190},
1618 { .hw_value = 40, .center_freq = 5200},
1619 { .hw_value = 42, .center_freq = 5210},
1620 { .hw_value = 44, .center_freq = 5220},
1621 { .hw_value = 46, .center_freq = 5230},
1622 { .hw_value = 48, .center_freq = 5240},
1623 { .hw_value = 52, .center_freq = 5260},
1624 { .hw_value = 56, .center_freq = 5280},
1625 { .hw_value = 60, .center_freq = 5300},
1626 { .hw_value = 64, .center_freq = 5320},
1627 { .hw_value = 100, .center_freq = 5500},
1628 { .hw_value = 104, .center_freq = 5520},
1629 { .hw_value = 108, .center_freq = 5540},
1630 { .hw_value = 112, .center_freq = 5560},
1631 { .hw_value = 116, .center_freq = 5580},
1632 { .hw_value = 120, .center_freq = 5600},
1633 { .hw_value = 124, .center_freq = 5620},
1634 { .hw_value = 128, .center_freq = 5640},
1635 { .hw_value = 132, .center_freq = 5660},
1636 { .hw_value = 136, .center_freq = 5680},
1637 { .hw_value = 140, .center_freq = 5700},
1638 { .hw_value = 149, .center_freq = 5745},
1639 { .hw_value = 153, .center_freq = 5765},
1640 { .hw_value = 157, .center_freq = 5785},
1641 { .hw_value = 161, .center_freq = 5805},
1642 { .hw_value = 165, .center_freq = 5825},
1643};
1644
1645
1646static struct ieee80211_supported_band wl1271_band_5ghz = {
1647 .channels = wl1271_channels_5ghz,
1648 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
1649 .bitrates = wl1271_rates_5ghz,
1650 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
1651};
1652
f5fc0f86
LC
1653static const struct ieee80211_ops wl1271_ops = {
1654 .start = wl1271_op_start,
1655 .stop = wl1271_op_stop,
1656 .add_interface = wl1271_op_add_interface,
1657 .remove_interface = wl1271_op_remove_interface,
1658 .config = wl1271_op_config,
1659/* .config_interface = wl1271_op_config_interface, */
c87dec9f 1660 .prepare_multicast = wl1271_op_prepare_multicast,
f5fc0f86
LC
1661 .configure_filter = wl1271_op_configure_filter,
1662 .tx = wl1271_op_tx,
1663 .set_key = wl1271_op_set_key,
1664 .hw_scan = wl1271_op_hw_scan,
1665 .bss_info_changed = wl1271_op_bss_info_changed,
1666 .set_rts_threshold = wl1271_op_set_rts_threshold,
1667};
1668
1669static int wl1271_register_hw(struct wl1271 *wl)
1670{
1671 int ret;
1672
1673 if (wl->mac80211_registered)
1674 return 0;
1675
1676 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
1677
1678 ret = ieee80211_register_hw(wl->hw);
1679 if (ret < 0) {
1680 wl1271_error("unable to register mac80211 hw: %d", ret);
1681 return ret;
1682 }
1683
1684 wl->mac80211_registered = true;
1685
1686 wl1271_notice("loaded");
1687
1688 return 0;
1689}
1690
1691static int wl1271_init_ieee80211(struct wl1271 *wl)
1692{
1e2b7976
JO
1693 /* The tx descriptor buffer and the TKIP space. */
1694 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
1695 sizeof(struct wl1271_tx_hw_descr);
f5fc0f86
LC
1696
1697 /* unit us */
1698 /* FIXME: find a proper value */
1699 wl->hw->channel_change_time = 10000;
1700
1701 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1922167b
JO
1702 IEEE80211_HW_NOISE_DBM |
1703 IEEE80211_HW_BEACON_FILTER;
f5fc0f86
LC
1704
1705 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1706 wl->hw->wiphy->max_scan_ssids = 1;
1707 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
1708
1ebec3d7
TP
1709 if (wl1271_11a_enabled())
1710 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
1711
f5fc0f86
LC
1712 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
1713
1714 return 0;
1715}
1716
1717static void wl1271_device_release(struct device *dev)
1718{
1719
1720}
1721
1722static struct platform_device wl1271_device = {
1723 .name = "wl1271",
1724 .id = -1,
1725
1726 /* device model insists to have a release function */
1727 .dev = {
1728 .release = wl1271_device_release,
1729 },
1730};
1731
1732#define WL1271_DEFAULT_CHANNEL 0
1733static int __devinit wl1271_probe(struct spi_device *spi)
1734{
1735 struct wl12xx_platform_data *pdata;
1736 struct ieee80211_hw *hw;
1737 struct wl1271 *wl;
1738 int ret, i;
1739 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
1740
1741 pdata = spi->dev.platform_data;
1742 if (!pdata) {
1743 wl1271_error("no platform data");
1744 return -ENODEV;
1745 }
1746
1747 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
1748 if (!hw) {
1749 wl1271_error("could not alloc ieee80211_hw");
1750 return -ENOMEM;
1751 }
1752
1753 wl = hw->priv;
1754 memset(wl, 0, sizeof(*wl));
1755
1756 wl->hw = hw;
1757 dev_set_drvdata(&spi->dev, wl);
1758 wl->spi = spi;
1759
1760 skb_queue_head_init(&wl->tx_queue);
1761
1762 INIT_WORK(&wl->filter_work, wl1271_filter_work);
37b70a81 1763 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
f5fc0f86
LC
1764 wl->channel = WL1271_DEFAULT_CHANNEL;
1765 wl->scanning = false;
1766 wl->default_key = 0;
f5fc0f86
LC
1767 wl->rx_counter = 0;
1768 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1769 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1770 wl->elp = false;
1771 wl->psm = 0;
1772 wl->psm_requested = false;
1773 wl->tx_queue_stopped = false;
1774 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
d94cd297 1775 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
8a5a37a6 1776 wl->band = IEEE80211_BAND_2GHZ;
b771eee5 1777 wl->vif = NULL;
d6e19d13 1778 wl->joined = false;
f5fc0f86 1779
be7078c2 1780 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
f5fc0f86
LC
1781 wl->tx_frames[i] = NULL;
1782
1783 spin_lock_init(&wl->wl_lock);
1784
1785 /*
1786 * In case our MAC address is not correctly set,
1787 * we use a random but Nokia MAC.
1788 */
1789 memcpy(wl->mac_addr, nokia_oui, 3);
1790 get_random_bytes(wl->mac_addr + 3, 3);
1791
1792 wl->state = WL1271_STATE_OFF;
1793 mutex_init(&wl->mutex);
1794
1795 wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
1796 if (!wl->rx_descriptor) {
1797 wl1271_error("could not allocate memory for rx descriptor");
1798 ret = -ENOMEM;
1799 goto out_free;
1800 }
1801
1802 /* This is the only SPI value that we need to set here, the rest
1803 * comes from the board-peripherals file */
1804 spi->bits_per_word = 32;
1805
1806 ret = spi_setup(spi);
1807 if (ret < 0) {
1808 wl1271_error("spi_setup failed");
1809 goto out_free;
1810 }
1811
1812 wl->set_power = pdata->set_power;
1813 if (!wl->set_power) {
1814 wl1271_error("set power function missing in platform data");
1815 ret = -ENODEV;
1816 goto out_free;
1817 }
1818
1819 wl->irq = spi->irq;
1820 if (wl->irq < 0) {
1821 wl1271_error("irq missing in platform data");
1822 ret = -ENODEV;
1823 goto out_free;
1824 }
1825
1826 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
1827 if (ret < 0) {
1828 wl1271_error("request_irq() failed: %d", ret);
1829 goto out_free;
1830 }
1831
1832 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
1833
1834 disable_irq(wl->irq);
1835
1836 ret = platform_device_register(&wl1271_device);
1837 if (ret) {
1838 wl1271_error("couldn't register platform device");
1839 goto out_irq;
1840 }
1841 dev_set_drvdata(&wl1271_device.dev, wl);
1842
2b60100b
JO
1843 /* Apply default driver configuration. */
1844 wl1271_conf_init(wl);
1845
f5fc0f86
LC
1846 ret = wl1271_init_ieee80211(wl);
1847 if (ret)
1848 goto out_platform;
1849
1850 ret = wl1271_register_hw(wl);
1851 if (ret)
1852 goto out_platform;
1853
1854 wl1271_debugfs_init(wl);
1855
1856 wl1271_notice("initialized");
1857
1858 return 0;
1859
1860 out_platform:
1861 platform_device_unregister(&wl1271_device);
1862
1863 out_irq:
1864 free_irq(wl->irq, wl);
1865
1866 out_free:
1867 kfree(wl->rx_descriptor);
1868 wl->rx_descriptor = NULL;
1869
1870 ieee80211_free_hw(hw);
1871
1872 return ret;
1873}
1874
1875static int __devexit wl1271_remove(struct spi_device *spi)
1876{
1877 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
1878
1879 ieee80211_unregister_hw(wl->hw);
1880
1881 wl1271_debugfs_exit(wl);
1882 platform_device_unregister(&wl1271_device);
1883 free_irq(wl->irq, wl);
1884 kfree(wl->target_mem_map);
1fba4974 1885 vfree(wl->fw);
f5fc0f86
LC
1886 wl->fw = NULL;
1887 kfree(wl->nvs);
1888 wl->nvs = NULL;
1889
1890 kfree(wl->rx_descriptor);
1891 wl->rx_descriptor = NULL;
1892
1893 kfree(wl->fw_status);
1894 kfree(wl->tx_res_if);
1895
1896 ieee80211_free_hw(wl->hw);
1897
1898 return 0;
1899}
1900
1901
1902static struct spi_driver wl1271_spi_driver = {
1903 .driver = {
1904 .name = "wl1271",
1905 .bus = &spi_bus_type,
1906 .owner = THIS_MODULE,
1907 },
1908
1909 .probe = wl1271_probe,
1910 .remove = __devexit_p(wl1271_remove),
1911};
1912
1913static int __init wl1271_init(void)
1914{
1915 int ret;
1916
1917 ret = spi_register_driver(&wl1271_spi_driver);
1918 if (ret < 0) {
1919 wl1271_error("failed to register spi driver: %d", ret);
1920 goto out;
1921 }
1922
1923out:
1924 return ret;
1925}
1926
1927static void __exit wl1271_exit(void)
1928{
1929 spi_unregister_driver(&wl1271_spi_driver);
1930
1931 wl1271_notice("unloaded");
1932}
1933
1934module_init(wl1271_init);
1935module_exit(wl1271_exit);
1936
1937MODULE_LICENSE("GPL");
1938MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
2f018725 1939MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
This page took 0.18255 seconds and 5 git commands to generate.