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