Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac802...
[linux-drm-fsl-dcu.git] / drivers / net / wireless / 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                   = IEEE80211_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                   = IEEE80211_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         hw->flags = IEEE80211_HW_SIGNAL_DBM |
282                     IEEE80211_HW_SUPPORTS_PS |
283                     IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
284                     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
285                     IEEE80211_HW_SUPPORTS_UAPSD |
286                     IEEE80211_HW_CONNECTION_MONITOR |
287                     IEEE80211_HW_AMPDU_AGGREGATION |
288                     IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
289                     IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC;
290
291         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
292                                           BIT(NL80211_IFTYPE_ADHOC) |
293                                           BIT(NL80211_IFTYPE_AP) |
294                                           BIT(NL80211_IFTYPE_MESH_POINT) |
295                                           BIT(NL80211_IFTYPE_P2P_CLIENT) |
296                                           BIT(NL80211_IFTYPE_P2P_GO);
297
298 #ifdef CONFIG_PM
299         hw->wiphy->wowlan = &cw1200_wowlan_support;
300 #endif
301
302         hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
303
304         hw->queues = 4;
305
306         priv->rts_threshold = -1;
307
308         hw->max_rates = 8;
309         hw->max_rate_tries = 15;
310         hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
311                 8;  /* TKIP IV */
312
313         hw->sta_data_size = sizeof(struct cw1200_sta_priv);
314
315         hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &cw1200_band_2ghz;
316         if (have_5ghz)
317                 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &cw1200_band_5ghz;
318
319         /* Channel params have to be cleared before registering wiphy again */
320         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
321                 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
322                 if (!sband)
323                         continue;
324                 for (i = 0; i < sband->n_channels; i++) {
325                         sband->channels[i].flags = 0;
326                         sband->channels[i].max_antenna_gain = 0;
327                         sband->channels[i].max_power = 30;
328                 }
329         }
330
331         hw->wiphy->max_scan_ssids = 2;
332         hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
333
334         if (macaddr)
335                 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
336         else
337                 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
338
339         /* Fix up mac address if necessary */
340         if (hw->wiphy->perm_addr[3] == 0 &&
341             hw->wiphy->perm_addr[4] == 0 &&
342             hw->wiphy->perm_addr[5] == 0) {
343                 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
344         }
345
346         mutex_init(&priv->wsm_cmd_mux);
347         mutex_init(&priv->conf_mutex);
348         priv->workqueue = create_singlethread_workqueue("cw1200_wq");
349         sema_init(&priv->scan.lock, 1);
350         INIT_WORK(&priv->scan.work, cw1200_scan_work);
351         INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
352         INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
353         INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
354                           cw1200_clear_recent_scan_work);
355         INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
356         INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
357         INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
358         INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
359         INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
360         spin_lock_init(&priv->event_queue_lock);
361         INIT_LIST_HEAD(&priv->event_queue);
362         INIT_WORK(&priv->event_handler, cw1200_event_handler);
363         INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
364         INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
365         spin_lock_init(&priv->bss_loss_lock);
366         spin_lock_init(&priv->ps_state_lock);
367         INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
368         INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
369         INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
370         INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
371         INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
372         INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
373         INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
374         INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
375         INIT_WORK(&priv->set_beacon_wakeup_period_work,
376                   cw1200_set_beacon_wakeup_period_work);
377         init_timer(&priv->mcast_timeout);
378         priv->mcast_timeout.data = (unsigned long)priv;
379         priv->mcast_timeout.function = cw1200_mcast_timeout;
380
381         if (cw1200_queue_stats_init(&priv->tx_queue_stats,
382                                     CW1200_LINK_ID_MAX,
383                                     cw1200_skb_dtor,
384                                     priv)) {
385                 ieee80211_free_hw(hw);
386                 return NULL;
387         }
388
389         for (i = 0; i < 4; ++i) {
390                 if (cw1200_queue_init(&priv->tx_queue[i],
391                                       &priv->tx_queue_stats, i, 16,
392                                       cw1200_ttl[i])) {
393                         for (; i > 0; i--)
394                                 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
395                         cw1200_queue_stats_deinit(&priv->tx_queue_stats);
396                         ieee80211_free_hw(hw);
397                         return NULL;
398                 }
399         }
400
401         init_waitqueue_head(&priv->channel_switch_done);
402         init_waitqueue_head(&priv->wsm_cmd_wq);
403         init_waitqueue_head(&priv->wsm_startup_done);
404         init_waitqueue_head(&priv->ps_mode_switch_done);
405         wsm_buf_init(&priv->wsm_cmd_buf);
406         spin_lock_init(&priv->wsm_cmd.lock);
407         priv->wsm_cmd.done = 1;
408         tx_policy_init(priv);
409
410         return hw;
411 }
412
413 static int cw1200_register_common(struct ieee80211_hw *dev)
414 {
415         struct cw1200_common *priv = dev->priv;
416         int err;
417
418 #ifdef CONFIG_PM
419         err = cw1200_pm_init(&priv->pm_state, priv);
420         if (err) {
421                 pr_err("Cannot init PM. (%d).\n",
422                        err);
423                 return err;
424         }
425 #endif
426
427         err = ieee80211_register_hw(dev);
428         if (err) {
429                 pr_err("Cannot register device (%d).\n",
430                        err);
431 #ifdef CONFIG_PM
432                 cw1200_pm_deinit(&priv->pm_state);
433 #endif
434                 return err;
435         }
436
437         cw1200_debug_init(priv);
438
439         pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
440         return 0;
441 }
442
443 static void cw1200_free_common(struct ieee80211_hw *dev)
444 {
445         ieee80211_free_hw(dev);
446 }
447
448 static void cw1200_unregister_common(struct ieee80211_hw *dev)
449 {
450         struct cw1200_common *priv = dev->priv;
451         int i;
452
453         ieee80211_unregister_hw(dev);
454
455         del_timer_sync(&priv->mcast_timeout);
456         cw1200_unregister_bh(priv);
457
458         cw1200_debug_release(priv);
459
460         mutex_destroy(&priv->conf_mutex);
461
462         wsm_buf_deinit(&priv->wsm_cmd_buf);
463
464         destroy_workqueue(priv->workqueue);
465         priv->workqueue = NULL;
466
467         if (priv->sdd) {
468                 release_firmware(priv->sdd);
469                 priv->sdd = NULL;
470         }
471
472         for (i = 0; i < 4; ++i)
473                 cw1200_queue_deinit(&priv->tx_queue[i]);
474
475         cw1200_queue_stats_deinit(&priv->tx_queue_stats);
476 #ifdef CONFIG_PM
477         cw1200_pm_deinit(&priv->pm_state);
478 #endif
479 }
480
481 /* Clock is in KHz */
482 u32 cw1200_dpll_from_clk(u16 clk_khz)
483 {
484         switch (clk_khz) {
485         case 0x32C8: /* 13000 KHz */
486                 return 0x1D89D241;
487         case 0x3E80: /* 16000 KHz */
488                 return 0x000001E1;
489         case 0x41A0: /* 16800 KHz */
490                 return 0x124931C1;
491         case 0x4B00: /* 19200 KHz */
492                 return 0x00000191;
493         case 0x5DC0: /* 24000 KHz */
494                 return 0x00000141;
495         case 0x6590: /* 26000 KHz */
496                 return 0x0EC4F121;
497         case 0x8340: /* 33600 KHz */
498                 return 0x092490E1;
499         case 0x9600: /* 38400 KHz */
500                 return 0x100010C1;
501         case 0x9C40: /* 40000 KHz */
502                 return 0x000000C1;
503         case 0xBB80: /* 48000 KHz */
504                 return 0x000000A1;
505         case 0xCB20: /* 52000 KHz */
506                 return 0x07627091;
507         default:
508                 pr_err("Unknown Refclk freq (0x%04x), using 26000KHz\n",
509                        clk_khz);
510                 return 0x0EC4F121;
511         }
512 }
513
514 int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
515                       struct hwbus_priv *hwbus,
516                       struct device *pdev,
517                       struct cw1200_common **core,
518                       int ref_clk, const u8 *macaddr,
519                       const char *sdd_path, bool have_5ghz)
520 {
521         int err = -EINVAL;
522         struct ieee80211_hw *dev;
523         struct cw1200_common *priv;
524         struct wsm_operational_mode mode = {
525                 .power_mode = cw1200_power_mode,
526                 .disable_more_flag_usage = true,
527         };
528
529         dev = cw1200_init_common(macaddr, have_5ghz);
530         if (!dev)
531                 goto err;
532
533         priv = dev->priv;
534         priv->hw_refclk = ref_clk;
535         if (cw1200_refclk)
536                 priv->hw_refclk = cw1200_refclk;
537
538         priv->sdd_path = (char *)sdd_path;
539         if (cw1200_sdd_path)
540                 priv->sdd_path = cw1200_sdd_path;
541
542         priv->hwbus_ops = hwbus_ops;
543         priv->hwbus_priv = hwbus;
544         priv->pdev = pdev;
545         SET_IEEE80211_DEV(priv->hw, pdev);
546
547         /* Pass struct cw1200_common back up */
548         *core = priv;
549
550         err = cw1200_register_bh(priv);
551         if (err)
552                 goto err1;
553
554         err = cw1200_load_firmware(priv);
555         if (err)
556                 goto err2;
557
558         if (wait_event_interruptible_timeout(priv->wsm_startup_done,
559                                              priv->firmware_ready,
560                                              3*HZ) <= 0) {
561                 /* TODO: Need to find how to reset device
562                    in QUEUE mode properly.
563                 */
564                 pr_err("Timeout waiting on device startup\n");
565                 err = -ETIMEDOUT;
566                 goto err2;
567         }
568
569         /* Set low-power mode. */
570         wsm_set_operational_mode(priv, &mode);
571
572         /* Enable multi-TX confirmation */
573         wsm_use_multi_tx_conf(priv, true);
574
575         err = cw1200_register_common(dev);
576         if (err)
577                 goto err2;
578
579         return err;
580
581 err2:
582         cw1200_unregister_bh(priv);
583 err1:
584         cw1200_free_common(dev);
585 err:
586         *core = NULL;
587         return err;
588 }
589 EXPORT_SYMBOL_GPL(cw1200_core_probe);
590
591 void cw1200_core_release(struct cw1200_common *self)
592 {
593         /* Disable device interrupts */
594         self->hwbus_ops->lock(self->hwbus_priv);
595         __cw1200_irq_enable(self, 0);
596         self->hwbus_ops->unlock(self->hwbus_priv);
597
598         /* And then clean up */
599         cw1200_unregister_common(self->hw);
600         cw1200_free_common(self->hw);
601         return;
602 }
603 EXPORT_SYMBOL_GPL(cw1200_core_release);