GNU Linux-libre 4.9.318-gnu1
[releases.git] / drivers / net / wireless / st / cw1200 / main.c
1 /*
2  * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3  *
4  * Copyright (c) 2010, ST-Ericsson
5  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6  *
7  * Based on:
8  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9  * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
10  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11  *
12  * Based on:
13  * - the islsm (softmac prism54) driver, which is:
14  *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
15  * - stlc45xx driver
16  *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License version 2 as
20  * published by the Free Software Foundation.
21  */
22
23 #include <linux/module.h>
24 #include <linux/firmware.h>
25 #include <linux/etherdevice.h>
26 #include <linux/vmalloc.h>
27 #include <linux/random.h>
28 #include <linux/sched.h>
29 #include <net/mac80211.h>
30
31 #include "cw1200.h"
32 #include "txrx.h"
33 #include "hwbus.h"
34 #include "fwio.h"
35 #include "hwio.h"
36 #include "bh.h"
37 #include "sta.h"
38 #include "scan.h"
39 #include "debug.h"
40 #include "pm.h"
41
42 MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
43 MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
44 MODULE_LICENSE("GPL");
45 MODULE_ALIAS("cw1200_core");
46
47 /* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
48 static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
49 module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO);
50 MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
51
52 static char *cw1200_sdd_path;
53 module_param(cw1200_sdd_path, charp, 0644);
54 MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
55 static int cw1200_refclk;
56 module_param(cw1200_refclk, int, 0644);
57 MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
58
59 int cw1200_power_mode = wsm_power_mode_quiescent;
60 module_param(cw1200_power_mode, int, 0644);
61 MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode.  0 == active, 1 == doze, 2 == quiescent (default)");
62
63 #define RATETAB_ENT(_rate, _rateid, _flags)             \
64         {                                               \
65                 .bitrate        = (_rate),              \
66                 .hw_value       = (_rateid),            \
67                 .flags          = (_flags),             \
68         }
69
70 static struct ieee80211_rate cw1200_rates[] = {
71         RATETAB_ENT(10,  0,   0),
72         RATETAB_ENT(20,  1,   0),
73         RATETAB_ENT(55,  2,   0),
74         RATETAB_ENT(110, 3,   0),
75         RATETAB_ENT(60,  6,  0),
76         RATETAB_ENT(90,  7,  0),
77         RATETAB_ENT(120, 8,  0),
78         RATETAB_ENT(180, 9,  0),
79         RATETAB_ENT(240, 10, 0),
80         RATETAB_ENT(360, 11, 0),
81         RATETAB_ENT(480, 12, 0),
82         RATETAB_ENT(540, 13, 0),
83 };
84
85 static struct ieee80211_rate cw1200_mcs_rates[] = {
86         RATETAB_ENT(65,  14, IEEE80211_TX_RC_MCS),
87         RATETAB_ENT(130, 15, IEEE80211_TX_RC_MCS),
88         RATETAB_ENT(195, 16, IEEE80211_TX_RC_MCS),
89         RATETAB_ENT(260, 17, IEEE80211_TX_RC_MCS),
90         RATETAB_ENT(390, 18, IEEE80211_TX_RC_MCS),
91         RATETAB_ENT(520, 19, IEEE80211_TX_RC_MCS),
92         RATETAB_ENT(585, 20, IEEE80211_TX_RC_MCS),
93         RATETAB_ENT(650, 21, IEEE80211_TX_RC_MCS),
94 };
95
96 #define cw1200_a_rates          (cw1200_rates + 4)
97 #define cw1200_a_rates_size     (ARRAY_SIZE(cw1200_rates) - 4)
98 #define cw1200_g_rates          (cw1200_rates + 0)
99 #define cw1200_g_rates_size     (ARRAY_SIZE(cw1200_rates))
100 #define cw1200_n_rates          (cw1200_mcs_rates)
101 #define cw1200_n_rates_size     (ARRAY_SIZE(cw1200_mcs_rates))
102
103
104 #define CHAN2G(_channel, _freq, _flags) {                       \
105         .band                   = NL80211_BAND_2GHZ,            \
106         .center_freq            = (_freq),                      \
107         .hw_value               = (_channel),                   \
108         .flags                  = (_flags),                     \
109         .max_antenna_gain       = 0,                            \
110         .max_power              = 30,                           \
111 }
112
113 #define CHAN5G(_channel, _flags) {                              \
114         .band                   = NL80211_BAND_5GHZ,            \
115         .center_freq    = 5000 + (5 * (_channel)),              \
116         .hw_value               = (_channel),                   \
117         .flags                  = (_flags),                     \
118         .max_antenna_gain       = 0,                            \
119         .max_power              = 30,                           \
120 }
121
122 static struct ieee80211_channel cw1200_2ghz_chantable[] = {
123         CHAN2G(1, 2412, 0),
124         CHAN2G(2, 2417, 0),
125         CHAN2G(3, 2422, 0),
126         CHAN2G(4, 2427, 0),
127         CHAN2G(5, 2432, 0),
128         CHAN2G(6, 2437, 0),
129         CHAN2G(7, 2442, 0),
130         CHAN2G(8, 2447, 0),
131         CHAN2G(9, 2452, 0),
132         CHAN2G(10, 2457, 0),
133         CHAN2G(11, 2462, 0),
134         CHAN2G(12, 2467, 0),
135         CHAN2G(13, 2472, 0),
136         CHAN2G(14, 2484, 0),
137 };
138
139 static struct ieee80211_channel cw1200_5ghz_chantable[] = {
140         CHAN5G(34, 0),          CHAN5G(36, 0),
141         CHAN5G(38, 0),          CHAN5G(40, 0),
142         CHAN5G(42, 0),          CHAN5G(44, 0),
143         CHAN5G(46, 0),          CHAN5G(48, 0),
144         CHAN5G(52, 0),          CHAN5G(56, 0),
145         CHAN5G(60, 0),          CHAN5G(64, 0),
146         CHAN5G(100, 0),         CHAN5G(104, 0),
147         CHAN5G(108, 0),         CHAN5G(112, 0),
148         CHAN5G(116, 0),         CHAN5G(120, 0),
149         CHAN5G(124, 0),         CHAN5G(128, 0),
150         CHAN5G(132, 0),         CHAN5G(136, 0),
151         CHAN5G(140, 0),         CHAN5G(149, 0),
152         CHAN5G(153, 0),         CHAN5G(157, 0),
153         CHAN5G(161, 0),         CHAN5G(165, 0),
154         CHAN5G(184, 0),         CHAN5G(188, 0),
155         CHAN5G(192, 0),         CHAN5G(196, 0),
156         CHAN5G(200, 0),         CHAN5G(204, 0),
157         CHAN5G(208, 0),         CHAN5G(212, 0),
158         CHAN5G(216, 0),
159 };
160
161 static struct ieee80211_supported_band cw1200_band_2ghz = {
162         .channels = cw1200_2ghz_chantable,
163         .n_channels = ARRAY_SIZE(cw1200_2ghz_chantable),
164         .bitrates = cw1200_g_rates,
165         .n_bitrates = cw1200_g_rates_size,
166         .ht_cap = {
167                 .cap = IEEE80211_HT_CAP_GRN_FLD |
168                         (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
169                         IEEE80211_HT_CAP_MAX_AMSDU,
170                 .ht_supported = 1,
171                 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
172                 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
173                 .mcs = {
174                         .rx_mask[0] = 0xFF,
175                         .rx_highest = __cpu_to_le16(0x41),
176                         .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
177                 },
178         },
179 };
180
181 static struct ieee80211_supported_band cw1200_band_5ghz = {
182         .channels = cw1200_5ghz_chantable,
183         .n_channels = ARRAY_SIZE(cw1200_5ghz_chantable),
184         .bitrates = cw1200_a_rates,
185         .n_bitrates = cw1200_a_rates_size,
186         .ht_cap = {
187                 .cap = IEEE80211_HT_CAP_GRN_FLD |
188                         (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
189                         IEEE80211_HT_CAP_MAX_AMSDU,
190                 .ht_supported = 1,
191                 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
192                 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
193                 .mcs = {
194                         .rx_mask[0] = 0xFF,
195                         .rx_highest = __cpu_to_le16(0x41),
196                         .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
197                 },
198         },
199 };
200
201 static const unsigned long cw1200_ttl[] = {
202         1 * HZ, /* VO */
203         2 * HZ, /* VI */
204         5 * HZ, /* BE */
205         10 * HZ /* BK */
206 };
207
208 static const struct ieee80211_ops cw1200_ops = {
209         .start                  = cw1200_start,
210         .stop                   = cw1200_stop,
211         .add_interface          = cw1200_add_interface,
212         .remove_interface       = cw1200_remove_interface,
213         .change_interface       = cw1200_change_interface,
214         .tx                     = cw1200_tx,
215         .hw_scan                = cw1200_hw_scan,
216         .set_tim                = cw1200_set_tim,
217         .sta_notify             = cw1200_sta_notify,
218         .sta_add                = cw1200_sta_add,
219         .sta_remove             = cw1200_sta_remove,
220         .set_key                = cw1200_set_key,
221         .set_rts_threshold      = cw1200_set_rts_threshold,
222         .config                 = cw1200_config,
223         .bss_info_changed       = cw1200_bss_info_changed,
224         .prepare_multicast      = cw1200_prepare_multicast,
225         .configure_filter       = cw1200_configure_filter,
226         .conf_tx                = cw1200_conf_tx,
227         .get_stats              = cw1200_get_stats,
228         .ampdu_action           = cw1200_ampdu_action,
229         .flush                  = cw1200_flush,
230 #ifdef CONFIG_PM
231         .suspend                = cw1200_wow_suspend,
232         .resume                 = cw1200_wow_resume,
233 #endif
234         /* Intentionally not offloaded:                                 */
235         /*.channel_switch       = cw1200_channel_switch,                */
236         /*.remain_on_channel    = cw1200_remain_on_channel,             */
237         /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel,  */
238 };
239
240 static int cw1200_ba_rx_tids = -1;
241 static int cw1200_ba_tx_tids = -1;
242 module_param(cw1200_ba_rx_tids, int, 0644);
243 module_param(cw1200_ba_tx_tids, int, 0644);
244 MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
245 MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
246
247 #ifdef CONFIG_PM
248 static const struct wiphy_wowlan_support cw1200_wowlan_support = {
249         /* Support only for limited wowlan functionalities */
250         .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
251 };
252 #endif
253
254
255 static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
256                                                 const bool have_5ghz)
257 {
258         int i, band;
259         struct ieee80211_hw *hw;
260         struct cw1200_common *priv;
261
262         hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
263         if (!hw)
264                 return NULL;
265
266         priv = hw->priv;
267         priv->hw = hw;
268         priv->hw_type = -1;
269         priv->mode = NL80211_IFTYPE_UNSPECIFIED;
270         priv->rates = cw1200_rates; /* TODO: fetch from FW */
271         priv->mcs_rates = cw1200_n_rates;
272         if (cw1200_ba_rx_tids != -1)
273                 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
274         else
275                 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
276         if (cw1200_ba_tx_tids != -1)
277                 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
278         else
279                 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
280
281         ieee80211_hw_set(hw, NEED_DTIM_BEFORE_ASSOC);
282         ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
283         ieee80211_hw_set(hw, AMPDU_AGGREGATION);
284         ieee80211_hw_set(hw, CONNECTION_MONITOR);
285         ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
286         ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
287         ieee80211_hw_set(hw, SIGNAL_DBM);
288         ieee80211_hw_set(hw, SUPPORTS_PS);
289
290         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
291                                           BIT(NL80211_IFTYPE_ADHOC) |
292                                           BIT(NL80211_IFTYPE_AP) |
293                                           BIT(NL80211_IFTYPE_MESH_POINT) |
294                                           BIT(NL80211_IFTYPE_P2P_CLIENT) |
295                                           BIT(NL80211_IFTYPE_P2P_GO);
296
297 #ifdef CONFIG_PM
298         hw->wiphy->wowlan = &cw1200_wowlan_support;
299 #endif
300
301         hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
302
303         hw->queues = 4;
304
305         priv->rts_threshold = -1;
306
307         hw->max_rates = 8;
308         hw->max_rate_tries = 15;
309         hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
310                 8;  /* TKIP IV */
311
312         hw->sta_data_size = sizeof(struct cw1200_sta_priv);
313
314         hw->wiphy->bands[NL80211_BAND_2GHZ] = &cw1200_band_2ghz;
315         if (have_5ghz)
316                 hw->wiphy->bands[NL80211_BAND_5GHZ] = &cw1200_band_5ghz;
317
318         /* Channel params have to be cleared before registering wiphy again */
319         for (band = 0; band < NUM_NL80211_BANDS; band++) {
320                 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
321                 if (!sband)
322                         continue;
323                 for (i = 0; i < sband->n_channels; i++) {
324                         sband->channels[i].flags = 0;
325                         sband->channels[i].max_antenna_gain = 0;
326                         sband->channels[i].max_power = 30;
327                 }
328         }
329
330         hw->wiphy->max_scan_ssids = 2;
331         hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
332
333         if (macaddr)
334                 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
335         else
336                 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
337
338         /* Fix up mac address if necessary */
339         if (hw->wiphy->perm_addr[3] == 0 &&
340             hw->wiphy->perm_addr[4] == 0 &&
341             hw->wiphy->perm_addr[5] == 0) {
342                 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
343         }
344
345         mutex_init(&priv->wsm_cmd_mux);
346         mutex_init(&priv->conf_mutex);
347         priv->workqueue = create_singlethread_workqueue("cw1200_wq");
348         if (!priv->workqueue) {
349                 ieee80211_free_hw(hw);
350                 return NULL;
351         }
352
353         sema_init(&priv->scan.lock, 1);
354         INIT_WORK(&priv->scan.work, cw1200_scan_work);
355         INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
356         INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
357         INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
358                           cw1200_clear_recent_scan_work);
359         INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
360         INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
361         INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
362         INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
363         INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
364         spin_lock_init(&priv->event_queue_lock);
365         INIT_LIST_HEAD(&priv->event_queue);
366         INIT_WORK(&priv->event_handler, cw1200_event_handler);
367         INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
368         INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
369         spin_lock_init(&priv->bss_loss_lock);
370         spin_lock_init(&priv->ps_state_lock);
371         INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
372         INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
373         INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
374         INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
375         INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
376         INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
377         INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
378         INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
379         INIT_WORK(&priv->set_beacon_wakeup_period_work,
380                   cw1200_set_beacon_wakeup_period_work);
381         setup_timer(&priv->mcast_timeout, cw1200_mcast_timeout,
382                     (unsigned long)priv);
383
384         if (cw1200_queue_stats_init(&priv->tx_queue_stats,
385                                     CW1200_LINK_ID_MAX,
386                                     cw1200_skb_dtor,
387                                     priv)) {
388                 destroy_workqueue(priv->workqueue);
389                 ieee80211_free_hw(hw);
390                 return NULL;
391         }
392
393         for (i = 0; i < 4; ++i) {
394                 if (cw1200_queue_init(&priv->tx_queue[i],
395                                       &priv->tx_queue_stats, i, 16,
396                                       cw1200_ttl[i])) {
397                         for (; i > 0; i--)
398                                 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
399                         cw1200_queue_stats_deinit(&priv->tx_queue_stats);
400                         destroy_workqueue(priv->workqueue);
401                         ieee80211_free_hw(hw);
402                         return NULL;
403                 }
404         }
405
406         init_waitqueue_head(&priv->channel_switch_done);
407         init_waitqueue_head(&priv->wsm_cmd_wq);
408         init_waitqueue_head(&priv->wsm_startup_done);
409         init_waitqueue_head(&priv->ps_mode_switch_done);
410         wsm_buf_init(&priv->wsm_cmd_buf);
411         spin_lock_init(&priv->wsm_cmd.lock);
412         priv->wsm_cmd.done = 1;
413         tx_policy_init(priv);
414
415         return hw;
416 }
417
418 static int cw1200_register_common(struct ieee80211_hw *dev)
419 {
420         struct cw1200_common *priv = dev->priv;
421         int err;
422
423 #ifdef CONFIG_PM
424         err = cw1200_pm_init(&priv->pm_state, priv);
425         if (err) {
426                 pr_err("Cannot init PM. (%d).\n",
427                        err);
428                 return err;
429         }
430 #endif
431
432         err = ieee80211_register_hw(dev);
433         if (err) {
434                 pr_err("Cannot register device (%d).\n",
435                        err);
436 #ifdef CONFIG_PM
437                 cw1200_pm_deinit(&priv->pm_state);
438 #endif
439                 return err;
440         }
441
442         cw1200_debug_init(priv);
443
444         pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
445         return 0;
446 }
447
448 static void cw1200_free_common(struct ieee80211_hw *dev)
449 {
450         ieee80211_free_hw(dev);
451 }
452
453 static void cw1200_unregister_common(struct ieee80211_hw *dev)
454 {
455         struct cw1200_common *priv = dev->priv;
456         int i;
457
458         ieee80211_unregister_hw(dev);
459
460         del_timer_sync(&priv->mcast_timeout);
461         cw1200_unregister_bh(priv);
462
463         cw1200_debug_release(priv);
464
465         mutex_destroy(&priv->conf_mutex);
466
467         wsm_buf_deinit(&priv->wsm_cmd_buf);
468
469         destroy_workqueue(priv->workqueue);
470         priv->workqueue = NULL;
471
472         if (priv->sdd) {
473                 release_firmware(priv->sdd);
474                 priv->sdd = NULL;
475         }
476
477         for (i = 0; i < 4; ++i)
478                 cw1200_queue_deinit(&priv->tx_queue[i]);
479
480         cw1200_queue_stats_deinit(&priv->tx_queue_stats);
481 #ifdef CONFIG_PM
482         cw1200_pm_deinit(&priv->pm_state);
483 #endif
484 }
485
486 /* Clock is in KHz */
487 u32 cw1200_dpll_from_clk(u16 clk_khz)
488 {
489         switch (clk_khz) {
490         case 0x32C8: /* 13000 KHz */
491                 return 0x1D89D241;
492         case 0x3E80: /* 16000 KHz */
493                 return 0x000001E1;
494         case 0x41A0: /* 16800 KHz */
495                 return 0x124931C1;
496         case 0x4B00: /* 19200 KHz */
497                 return 0x00000191;
498         case 0x5DC0: /* 24000 KHz */
499                 return 0x00000141;
500         case 0x6590: /* 26000 KHz */
501                 return 0x0EC4F121;
502         case 0x8340: /* 33600 KHz */
503                 return 0x092490E1;
504         case 0x9600: /* 38400 KHz */
505                 return 0x100010C1;
506         case 0x9C40: /* 40000 KHz */
507                 return 0x000000C1;
508         case 0xBB80: /* 48000 KHz */
509                 return 0x000000A1;
510         case 0xCB20: /* 52000 KHz */
511                 return 0x07627091;
512         default:
513                 pr_err("Unknown Refclk freq (0x%04x), using 26000KHz\n",
514                        clk_khz);
515                 return 0x0EC4F121;
516         }
517 }
518
519 int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
520                       struct hwbus_priv *hwbus,
521                       struct device *pdev,
522                       struct cw1200_common **core,
523                       int ref_clk, const u8 *macaddr,
524                       const char *sdd_path, bool have_5ghz)
525 {
526         int err = -EINVAL;
527         struct ieee80211_hw *dev;
528         struct cw1200_common *priv;
529         struct wsm_operational_mode mode = {
530                 .power_mode = cw1200_power_mode,
531                 .disable_more_flag_usage = true,
532         };
533
534         dev = cw1200_init_common(macaddr, have_5ghz);
535         if (!dev)
536                 goto err;
537
538         priv = dev->priv;
539         priv->hw_refclk = ref_clk;
540         if (cw1200_refclk)
541                 priv->hw_refclk = cw1200_refclk;
542
543         priv->sdd_path = (char *)sdd_path;
544         if (cw1200_sdd_path)
545                 priv->sdd_path = cw1200_sdd_path;
546
547         priv->hwbus_ops = hwbus_ops;
548         priv->hwbus_priv = hwbus;
549         priv->pdev = pdev;
550         SET_IEEE80211_DEV(priv->hw, pdev);
551
552         /* Pass struct cw1200_common back up */
553         *core = priv;
554
555         err = cw1200_register_bh(priv);
556         if (err)
557                 goto err1;
558
559         err = cw1200_load_firmware(priv);
560         if (err)
561                 goto err2;
562
563         if (wait_event_interruptible_timeout(priv->wsm_startup_done,
564                                              priv->firmware_ready,
565                                              3*HZ) <= 0) {
566                 /* TODO: Need to find how to reset device
567                    in QUEUE mode properly.
568                 */
569                 pr_err("Timeout waiting on device startup\n");
570                 err = -ETIMEDOUT;
571                 goto err2;
572         }
573
574         /* Set low-power mode. */
575         wsm_set_operational_mode(priv, &mode);
576
577         /* Enable multi-TX confirmation */
578         wsm_use_multi_tx_conf(priv, true);
579
580         err = cw1200_register_common(dev);
581         if (err)
582                 goto err2;
583
584         return err;
585
586 err2:
587         cw1200_unregister_bh(priv);
588 err1:
589         cw1200_free_common(dev);
590 err:
591         *core = NULL;
592         return err;
593 }
594 EXPORT_SYMBOL_GPL(cw1200_core_probe);
595
596 void cw1200_core_release(struct cw1200_common *self)
597 {
598         /* Disable device interrupts */
599         self->hwbus_ops->lock(self->hwbus_priv);
600         __cw1200_irq_enable(self, 0);
601         self->hwbus_ops->unlock(self->hwbus_priv);
602
603         /* And then clean up */
604         cw1200_unregister_common(self->hw);
605         cw1200_free_common(self->hw);
606         return;
607 }
608 EXPORT_SYMBOL_GPL(cw1200_core_release);