Loading...
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
39MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
40MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
41MODULE_LICENSE("GPL");
42MODULE_ALIAS("cw1200_core");
43
44/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
45static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
46module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, 0444);
47MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
48
49static char *cw1200_sdd_path;
50module_param(cw1200_sdd_path, charp, 0644);
51MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
52static int cw1200_refclk;
53module_param(cw1200_refclk, int, 0644);
54MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
55
56int cw1200_power_mode = wsm_power_mode_quiescent;
57module_param(cw1200_power_mode, int, 0644);
58MODULE_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
67static 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
82static 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
119static 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
136static 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
158static 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
178static 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
198static const unsigned long cw1200_ttl[] = {
199 1 * HZ, /* VO */
200 2 * HZ, /* VI */
201 5 * HZ, /* BE */
202 10 * HZ /* BK */
203};
204
205static const struct ieee80211_ops cw1200_ops = {
206 .start = cw1200_start,
207 .stop = cw1200_stop,
208 .add_interface = cw1200_add_interface,
209 .remove_interface = cw1200_remove_interface,
210 .change_interface = cw1200_change_interface,
211 .tx = cw1200_tx,
212 .wake_tx_queue = ieee80211_handle_wake_tx_queue,
213 .hw_scan = cw1200_hw_scan,
214 .set_tim = cw1200_set_tim,
215 .sta_notify = cw1200_sta_notify,
216 .sta_add = cw1200_sta_add,
217 .sta_remove = cw1200_sta_remove,
218 .set_key = cw1200_set_key,
219 .set_rts_threshold = cw1200_set_rts_threshold,
220 .config = cw1200_config,
221 .bss_info_changed = cw1200_bss_info_changed,
222 .prepare_multicast = cw1200_prepare_multicast,
223 .configure_filter = cw1200_configure_filter,
224 .conf_tx = cw1200_conf_tx,
225 .get_stats = cw1200_get_stats,
226 .ampdu_action = cw1200_ampdu_action,
227 .flush = cw1200_flush,
228#ifdef CONFIG_PM
229 .suspend = cw1200_wow_suspend,
230 .resume = cw1200_wow_resume,
231#endif
232 /* Intentionally not offloaded: */
233 /*.channel_switch = cw1200_channel_switch, */
234 /*.remain_on_channel = cw1200_remain_on_channel, */
235 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
236};
237
238static int cw1200_ba_rx_tids = -1;
239static int cw1200_ba_tx_tids = -1;
240module_param(cw1200_ba_rx_tids, int, 0644);
241module_param(cw1200_ba_tx_tids, int, 0644);
242MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
243MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
244
245#ifdef CONFIG_PM
246static const struct wiphy_wowlan_support cw1200_wowlan_support = {
247 /* Support only for limited wowlan functionalities */
248 .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
249};
250#endif
251
252
253static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
254 const bool have_5ghz)
255{
256 int i, band;
257 struct ieee80211_hw *hw;
258 struct cw1200_common *priv;
259
260 hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
261 if (!hw)
262 return NULL;
263
264 priv = hw->priv;
265 priv->hw = hw;
266 priv->hw_type = -1;
267 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
268 priv->rates = cw1200_rates; /* TODO: fetch from FW */
269 priv->mcs_rates = cw1200_n_rates;
270 if (cw1200_ba_rx_tids != -1)
271 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
272 else
273 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
274 if (cw1200_ba_tx_tids != -1)
275 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
276 else
277 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
278
279 ieee80211_hw_set(hw, NEED_DTIM_BEFORE_ASSOC);
280 ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
281 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
282 ieee80211_hw_set(hw, CONNECTION_MONITOR);
283 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
284 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
285 ieee80211_hw_set(hw, SIGNAL_DBM);
286 ieee80211_hw_set(hw, SUPPORTS_PS);
287
288 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
289 BIT(NL80211_IFTYPE_ADHOC) |
290 BIT(NL80211_IFTYPE_AP) |
291 BIT(NL80211_IFTYPE_MESH_POINT) |
292 BIT(NL80211_IFTYPE_P2P_CLIENT) |
293 BIT(NL80211_IFTYPE_P2P_GO);
294
295#ifdef CONFIG_PM
296 hw->wiphy->wowlan = &cw1200_wowlan_support;
297#endif
298
299 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
300
301 hw->queues = 4;
302
303 priv->rts_threshold = -1;
304
305 hw->max_rates = 8;
306 hw->max_rate_tries = 15;
307 hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
308 8; /* TKIP IV */
309
310 hw->sta_data_size = sizeof(struct cw1200_sta_priv);
311
312 hw->wiphy->bands[NL80211_BAND_2GHZ] = &cw1200_band_2ghz;
313 if (have_5ghz)
314 hw->wiphy->bands[NL80211_BAND_5GHZ] = &cw1200_band_5ghz;
315
316 /* Channel params have to be cleared before registering wiphy again */
317 for (band = 0; band < NUM_NL80211_BANDS; band++) {
318 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
319 if (!sband)
320 continue;
321 for (i = 0; i < sband->n_channels; i++) {
322 sband->channels[i].flags = 0;
323 sband->channels[i].max_antenna_gain = 0;
324 sband->channels[i].max_power = 30;
325 }
326 }
327
328 hw->wiphy->max_scan_ssids = 2;
329 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
330
331 if (macaddr)
332 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
333 else
334 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
335
336 /* Fix up mac address if necessary */
337 if (hw->wiphy->perm_addr[3] == 0 &&
338 hw->wiphy->perm_addr[4] == 0 &&
339 hw->wiphy->perm_addr[5] == 0) {
340 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
341 }
342
343 mutex_init(&priv->wsm_cmd_mux);
344 mutex_init(&priv->conf_mutex);
345 priv->workqueue = create_singlethread_workqueue("cw1200_wq");
346 if (!priv->workqueue) {
347 ieee80211_free_hw(hw);
348 return NULL;
349 }
350
351 sema_init(&priv->scan.lock, 1);
352 INIT_WORK(&priv->scan.work, cw1200_scan_work);
353 INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
354 INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
355 INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
356 cw1200_clear_recent_scan_work);
357 INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
358 INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
359 INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
360 INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
361 INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
362 spin_lock_init(&priv->event_queue_lock);
363 INIT_LIST_HEAD(&priv->event_queue);
364 INIT_WORK(&priv->event_handler, cw1200_event_handler);
365 INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
366 INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
367 spin_lock_init(&priv->bss_loss_lock);
368 spin_lock_init(&priv->ps_state_lock);
369 INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
370 INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
371 INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
372 INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
373 INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
374 INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
375 INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
376 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
377 INIT_WORK(&priv->set_beacon_wakeup_period_work,
378 cw1200_set_beacon_wakeup_period_work);
379 timer_setup(&priv->mcast_timeout, cw1200_mcast_timeout, 0);
380
381 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
382 CW1200_LINK_ID_MAX,
383 cw1200_skb_dtor,
384 priv)) {
385 destroy_workqueue(priv->workqueue);
386 ieee80211_free_hw(hw);
387 return NULL;
388 }
389
390 for (i = 0; i < 4; ++i) {
391 if (cw1200_queue_init(&priv->tx_queue[i],
392 &priv->tx_queue_stats, i, 16,
393 cw1200_ttl[i])) {
394 for (; i > 0; i--)
395 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
396 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
397 destroy_workqueue(priv->workqueue);
398 ieee80211_free_hw(hw);
399 return NULL;
400 }
401 }
402
403 init_waitqueue_head(&priv->channel_switch_done);
404 init_waitqueue_head(&priv->wsm_cmd_wq);
405 init_waitqueue_head(&priv->wsm_startup_done);
406 init_waitqueue_head(&priv->ps_mode_switch_done);
407 wsm_buf_init(&priv->wsm_cmd_buf);
408 spin_lock_init(&priv->wsm_cmd.lock);
409 priv->wsm_cmd.done = 1;
410 tx_policy_init(priv);
411
412 return hw;
413}
414
415static int cw1200_register_common(struct ieee80211_hw *dev)
416{
417 struct cw1200_common *priv = dev->priv;
418 int err;
419
420#ifdef CONFIG_PM
421 err = cw1200_pm_init(&priv->pm_state, priv);
422 if (err) {
423 pr_err("Cannot init PM. (%d).\n",
424 err);
425 return err;
426 }
427#endif
428
429 err = ieee80211_register_hw(dev);
430 if (err) {
431 pr_err("Cannot register device (%d).\n",
432 err);
433#ifdef CONFIG_PM
434 cw1200_pm_deinit(&priv->pm_state);
435#endif
436 return err;
437 }
438
439 cw1200_debug_init(priv);
440
441 pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
442 return 0;
443}
444
445static void cw1200_free_common(struct ieee80211_hw *dev)
446{
447 ieee80211_free_hw(dev);
448}
449
450static void cw1200_unregister_common(struct ieee80211_hw *dev)
451{
452 struct cw1200_common *priv = dev->priv;
453 int i;
454
455 ieee80211_unregister_hw(dev);
456
457 del_timer_sync(&priv->mcast_timeout);
458 cw1200_unregister_bh(priv);
459
460 cw1200_debug_release(priv);
461
462 mutex_destroy(&priv->conf_mutex);
463
464 wsm_buf_deinit(&priv->wsm_cmd_buf);
465
466 destroy_workqueue(priv->workqueue);
467 priv->workqueue = NULL;
468
469 if (priv->sdd) {
470 release_firmware(priv->sdd);
471 priv->sdd = NULL;
472 }
473
474 for (i = 0; i < 4; ++i)
475 cw1200_queue_deinit(&priv->tx_queue[i]);
476
477 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
478#ifdef CONFIG_PM
479 cw1200_pm_deinit(&priv->pm_state);
480#endif
481}
482
483/* Clock is in KHz */
484u32 cw1200_dpll_from_clk(u16 clk_khz)
485{
486 switch (clk_khz) {
487 case 0x32C8: /* 13000 KHz */
488 return 0x1D89D241;
489 case 0x3E80: /* 16000 KHz */
490 return 0x000001E1;
491 case 0x41A0: /* 16800 KHz */
492 return 0x124931C1;
493 case 0x4B00: /* 19200 KHz */
494 return 0x00000191;
495 case 0x5DC0: /* 24000 KHz */
496 return 0x00000141;
497 case 0x6590: /* 26000 KHz */
498 return 0x0EC4F121;
499 case 0x8340: /* 33600 KHz */
500 return 0x092490E1;
501 case 0x9600: /* 38400 KHz */
502 return 0x100010C1;
503 case 0x9C40: /* 40000 KHz */
504 return 0x000000C1;
505 case 0xBB80: /* 48000 KHz */
506 return 0x000000A1;
507 case 0xCB20: /* 52000 KHz */
508 return 0x07627091;
509 default:
510 pr_err("Unknown Refclk freq (0x%04x), using 26000KHz\n",
511 clk_khz);
512 return 0x0EC4F121;
513 }
514}
515
516int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
517 struct hwbus_priv *hwbus,
518 struct device *pdev,
519 struct cw1200_common **core,
520 int ref_clk, const u8 *macaddr,
521 const char *sdd_path, bool have_5ghz)
522{
523 int err = -EINVAL;
524 struct ieee80211_hw *dev;
525 struct cw1200_common *priv;
526 struct wsm_operational_mode mode = {
527 .power_mode = cw1200_power_mode,
528 .disable_more_flag_usage = true,
529 };
530
531 dev = cw1200_init_common(macaddr, have_5ghz);
532 if (!dev)
533 goto err;
534
535 priv = dev->priv;
536 priv->hw_refclk = ref_clk;
537 if (cw1200_refclk)
538 priv->hw_refclk = cw1200_refclk;
539
540 priv->sdd_path = (char *)sdd_path;
541 if (cw1200_sdd_path)
542 priv->sdd_path = cw1200_sdd_path;
543
544 priv->hwbus_ops = hwbus_ops;
545 priv->hwbus_priv = hwbus;
546 priv->pdev = pdev;
547 SET_IEEE80211_DEV(priv->hw, pdev);
548
549 /* Pass struct cw1200_common back up */
550 *core = priv;
551
552 err = cw1200_register_bh(priv);
553 if (err)
554 goto err1;
555
556 err = cw1200_load_firmware(priv);
557 if (err)
558 goto err2;
559
560 if (wait_event_interruptible_timeout(priv->wsm_startup_done,
561 priv->firmware_ready,
562 3*HZ) <= 0) {
563 /* TODO: Need to find how to reset device
564 in QUEUE mode properly.
565 */
566 pr_err("Timeout waiting on device startup\n");
567 err = -ETIMEDOUT;
568 goto err2;
569 }
570
571 /* Set low-power mode. */
572 wsm_set_operational_mode(priv, &mode);
573
574 /* Enable multi-TX confirmation */
575 wsm_use_multi_tx_conf(priv, true);
576
577 err = cw1200_register_common(dev);
578 if (err)
579 goto err2;
580
581 return err;
582
583err2:
584 cw1200_unregister_bh(priv);
585err1:
586 cw1200_free_common(dev);
587err:
588 *core = NULL;
589 return err;
590}
591EXPORT_SYMBOL_GPL(cw1200_core_probe);
592
593void cw1200_core_release(struct cw1200_common *self)
594{
595 /* Disable device interrupts */
596 self->hwbus_ops->lock(self->hwbus_priv);
597 __cw1200_irq_enable(self, 0);
598 self->hwbus_ops->unlock(self->hwbus_priv);
599
600 /* And then clean up */
601 cw1200_unregister_common(self->hw);
602 cw1200_free_common(self->hw);
603 return;
604}
605EXPORT_SYMBOL_GPL(cw1200_core_release);
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
39MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
40MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
41MODULE_LICENSE("GPL");
42MODULE_ALIAS("cw1200_core");
43
44/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
45static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
46module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, 0444);
47MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
48
49static char *cw1200_sdd_path;
50module_param(cw1200_sdd_path, charp, 0644);
51MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
52static int cw1200_refclk;
53module_param(cw1200_refclk, int, 0644);
54MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
55
56int cw1200_power_mode = wsm_power_mode_quiescent;
57module_param(cw1200_power_mode, int, 0644);
58MODULE_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
67static 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
82static 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
119static 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
136static 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
158static 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
178static 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
198static const unsigned long cw1200_ttl[] = {
199 1 * HZ, /* VO */
200 2 * HZ, /* VI */
201 5 * HZ, /* BE */
202 10 * HZ /* BK */
203};
204
205static const struct ieee80211_ops cw1200_ops = {
206 .start = cw1200_start,
207 .stop = cw1200_stop,
208 .add_interface = cw1200_add_interface,
209 .remove_interface = cw1200_remove_interface,
210 .change_interface = cw1200_change_interface,
211 .tx = cw1200_tx,
212 .hw_scan = cw1200_hw_scan,
213 .set_tim = cw1200_set_tim,
214 .sta_notify = cw1200_sta_notify,
215 .sta_add = cw1200_sta_add,
216 .sta_remove = cw1200_sta_remove,
217 .set_key = cw1200_set_key,
218 .set_rts_threshold = cw1200_set_rts_threshold,
219 .config = cw1200_config,
220 .bss_info_changed = cw1200_bss_info_changed,
221 .prepare_multicast = cw1200_prepare_multicast,
222 .configure_filter = cw1200_configure_filter,
223 .conf_tx = cw1200_conf_tx,
224 .get_stats = cw1200_get_stats,
225 .ampdu_action = cw1200_ampdu_action,
226 .flush = cw1200_flush,
227#ifdef CONFIG_PM
228 .suspend = cw1200_wow_suspend,
229 .resume = cw1200_wow_resume,
230#endif
231 /* Intentionally not offloaded: */
232 /*.channel_switch = cw1200_channel_switch, */
233 /*.remain_on_channel = cw1200_remain_on_channel, */
234 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
235};
236
237static int cw1200_ba_rx_tids = -1;
238static int cw1200_ba_tx_tids = -1;
239module_param(cw1200_ba_rx_tids, int, 0644);
240module_param(cw1200_ba_tx_tids, int, 0644);
241MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
242MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
243
244#ifdef CONFIG_PM
245static const struct wiphy_wowlan_support cw1200_wowlan_support = {
246 /* Support only for limited wowlan functionalities */
247 .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
248};
249#endif
250
251
252static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
253 const bool have_5ghz)
254{
255 int i, band;
256 struct ieee80211_hw *hw;
257 struct cw1200_common *priv;
258
259 hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
260 if (!hw)
261 return NULL;
262
263 priv = hw->priv;
264 priv->hw = hw;
265 priv->hw_type = -1;
266 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
267 priv->rates = cw1200_rates; /* TODO: fetch from FW */
268 priv->mcs_rates = cw1200_n_rates;
269 if (cw1200_ba_rx_tids != -1)
270 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
271 else
272 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
273 if (cw1200_ba_tx_tids != -1)
274 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
275 else
276 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
277
278 ieee80211_hw_set(hw, NEED_DTIM_BEFORE_ASSOC);
279 ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
280 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
281 ieee80211_hw_set(hw, CONNECTION_MONITOR);
282 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
283 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
284 ieee80211_hw_set(hw, SIGNAL_DBM);
285 ieee80211_hw_set(hw, SUPPORTS_PS);
286
287 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
288 BIT(NL80211_IFTYPE_ADHOC) |
289 BIT(NL80211_IFTYPE_AP) |
290 BIT(NL80211_IFTYPE_MESH_POINT) |
291 BIT(NL80211_IFTYPE_P2P_CLIENT) |
292 BIT(NL80211_IFTYPE_P2P_GO);
293
294#ifdef CONFIG_PM
295 hw->wiphy->wowlan = &cw1200_wowlan_support;
296#endif
297
298 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
299
300 hw->queues = 4;
301
302 priv->rts_threshold = -1;
303
304 hw->max_rates = 8;
305 hw->max_rate_tries = 15;
306 hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
307 8; /* TKIP IV */
308
309 hw->sta_data_size = sizeof(struct cw1200_sta_priv);
310
311 hw->wiphy->bands[NL80211_BAND_2GHZ] = &cw1200_band_2ghz;
312 if (have_5ghz)
313 hw->wiphy->bands[NL80211_BAND_5GHZ] = &cw1200_band_5ghz;
314
315 /* Channel params have to be cleared before registering wiphy again */
316 for (band = 0; band < NUM_NL80211_BANDS; band++) {
317 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
318 if (!sband)
319 continue;
320 for (i = 0; i < sband->n_channels; i++) {
321 sband->channels[i].flags = 0;
322 sband->channels[i].max_antenna_gain = 0;
323 sband->channels[i].max_power = 30;
324 }
325 }
326
327 hw->wiphy->max_scan_ssids = 2;
328 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
329
330 if (macaddr)
331 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
332 else
333 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
334
335 /* Fix up mac address if necessary */
336 if (hw->wiphy->perm_addr[3] == 0 &&
337 hw->wiphy->perm_addr[4] == 0 &&
338 hw->wiphy->perm_addr[5] == 0) {
339 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
340 }
341
342 mutex_init(&priv->wsm_cmd_mux);
343 mutex_init(&priv->conf_mutex);
344 priv->workqueue = create_singlethread_workqueue("cw1200_wq");
345 if (!priv->workqueue) {
346 ieee80211_free_hw(hw);
347 return NULL;
348 }
349
350 sema_init(&priv->scan.lock, 1);
351 INIT_WORK(&priv->scan.work, cw1200_scan_work);
352 INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
353 INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
354 INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
355 cw1200_clear_recent_scan_work);
356 INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
357 INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
358 INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
359 INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
360 INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
361 spin_lock_init(&priv->event_queue_lock);
362 INIT_LIST_HEAD(&priv->event_queue);
363 INIT_WORK(&priv->event_handler, cw1200_event_handler);
364 INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
365 INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
366 spin_lock_init(&priv->bss_loss_lock);
367 spin_lock_init(&priv->ps_state_lock);
368 INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
369 INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
370 INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
371 INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
372 INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
373 INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
374 INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
375 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
376 INIT_WORK(&priv->set_beacon_wakeup_period_work,
377 cw1200_set_beacon_wakeup_period_work);
378 timer_setup(&priv->mcast_timeout, cw1200_mcast_timeout, 0);
379
380 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
381 CW1200_LINK_ID_MAX,
382 cw1200_skb_dtor,
383 priv)) {
384 destroy_workqueue(priv->workqueue);
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 destroy_workqueue(priv->workqueue);
397 ieee80211_free_hw(hw);
398 return NULL;
399 }
400 }
401
402 init_waitqueue_head(&priv->channel_switch_done);
403 init_waitqueue_head(&priv->wsm_cmd_wq);
404 init_waitqueue_head(&priv->wsm_startup_done);
405 init_waitqueue_head(&priv->ps_mode_switch_done);
406 wsm_buf_init(&priv->wsm_cmd_buf);
407 spin_lock_init(&priv->wsm_cmd.lock);
408 priv->wsm_cmd.done = 1;
409 tx_policy_init(priv);
410
411 return hw;
412}
413
414static int cw1200_register_common(struct ieee80211_hw *dev)
415{
416 struct cw1200_common *priv = dev->priv;
417 int err;
418
419#ifdef CONFIG_PM
420 err = cw1200_pm_init(&priv->pm_state, priv);
421 if (err) {
422 pr_err("Cannot init PM. (%d).\n",
423 err);
424 return err;
425 }
426#endif
427
428 err = ieee80211_register_hw(dev);
429 if (err) {
430 pr_err("Cannot register device (%d).\n",
431 err);
432#ifdef CONFIG_PM
433 cw1200_pm_deinit(&priv->pm_state);
434#endif
435 return err;
436 }
437
438 cw1200_debug_init(priv);
439
440 pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
441 return 0;
442}
443
444static void cw1200_free_common(struct ieee80211_hw *dev)
445{
446 ieee80211_free_hw(dev);
447}
448
449static void cw1200_unregister_common(struct ieee80211_hw *dev)
450{
451 struct cw1200_common *priv = dev->priv;
452 int i;
453
454 ieee80211_unregister_hw(dev);
455
456 del_timer_sync(&priv->mcast_timeout);
457 cw1200_unregister_bh(priv);
458
459 cw1200_debug_release(priv);
460
461 mutex_destroy(&priv->conf_mutex);
462
463 wsm_buf_deinit(&priv->wsm_cmd_buf);
464
465 destroy_workqueue(priv->workqueue);
466 priv->workqueue = NULL;
467
468 if (priv->sdd) {
469 release_firmware(priv->sdd);
470 priv->sdd = NULL;
471 }
472
473 for (i = 0; i < 4; ++i)
474 cw1200_queue_deinit(&priv->tx_queue[i]);
475
476 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
477#ifdef CONFIG_PM
478 cw1200_pm_deinit(&priv->pm_state);
479#endif
480}
481
482/* Clock is in KHz */
483u32 cw1200_dpll_from_clk(u16 clk_khz)
484{
485 switch (clk_khz) {
486 case 0x32C8: /* 13000 KHz */
487 return 0x1D89D241;
488 case 0x3E80: /* 16000 KHz */
489 return 0x000001E1;
490 case 0x41A0: /* 16800 KHz */
491 return 0x124931C1;
492 case 0x4B00: /* 19200 KHz */
493 return 0x00000191;
494 case 0x5DC0: /* 24000 KHz */
495 return 0x00000141;
496 case 0x6590: /* 26000 KHz */
497 return 0x0EC4F121;
498 case 0x8340: /* 33600 KHz */
499 return 0x092490E1;
500 case 0x9600: /* 38400 KHz */
501 return 0x100010C1;
502 case 0x9C40: /* 40000 KHz */
503 return 0x000000C1;
504 case 0xBB80: /* 48000 KHz */
505 return 0x000000A1;
506 case 0xCB20: /* 52000 KHz */
507 return 0x07627091;
508 default:
509 pr_err("Unknown Refclk freq (0x%04x), using 26000KHz\n",
510 clk_khz);
511 return 0x0EC4F121;
512 }
513}
514
515int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
516 struct hwbus_priv *hwbus,
517 struct device *pdev,
518 struct cw1200_common **core,
519 int ref_clk, const u8 *macaddr,
520 const char *sdd_path, bool have_5ghz)
521{
522 int err = -EINVAL;
523 struct ieee80211_hw *dev;
524 struct cw1200_common *priv;
525 struct wsm_operational_mode mode = {
526 .power_mode = cw1200_power_mode,
527 .disable_more_flag_usage = true,
528 };
529
530 dev = cw1200_init_common(macaddr, have_5ghz);
531 if (!dev)
532 goto err;
533
534 priv = dev->priv;
535 priv->hw_refclk = ref_clk;
536 if (cw1200_refclk)
537 priv->hw_refclk = cw1200_refclk;
538
539 priv->sdd_path = (char *)sdd_path;
540 if (cw1200_sdd_path)
541 priv->sdd_path = cw1200_sdd_path;
542
543 priv->hwbus_ops = hwbus_ops;
544 priv->hwbus_priv = hwbus;
545 priv->pdev = pdev;
546 SET_IEEE80211_DEV(priv->hw, pdev);
547
548 /* Pass struct cw1200_common back up */
549 *core = priv;
550
551 err = cw1200_register_bh(priv);
552 if (err)
553 goto err1;
554
555 err = cw1200_load_firmware(priv);
556 if (err)
557 goto err2;
558
559 if (wait_event_interruptible_timeout(priv->wsm_startup_done,
560 priv->firmware_ready,
561 3*HZ) <= 0) {
562 /* TODO: Need to find how to reset device
563 in QUEUE mode properly.
564 */
565 pr_err("Timeout waiting on device startup\n");
566 err = -ETIMEDOUT;
567 goto err2;
568 }
569
570 /* Set low-power mode. */
571 wsm_set_operational_mode(priv, &mode);
572
573 /* Enable multi-TX confirmation */
574 wsm_use_multi_tx_conf(priv, true);
575
576 err = cw1200_register_common(dev);
577 if (err)
578 goto err2;
579
580 return err;
581
582err2:
583 cw1200_unregister_bh(priv);
584err1:
585 cw1200_free_common(dev);
586err:
587 *core = NULL;
588 return err;
589}
590EXPORT_SYMBOL_GPL(cw1200_core_probe);
591
592void cw1200_core_release(struct cw1200_common *self)
593{
594 /* Disable device interrupts */
595 self->hwbus_ops->lock(self->hwbus_priv);
596 __cw1200_irq_enable(self, 0);
597 self->hwbus_ops->unlock(self->hwbus_priv);
598
599 /* And then clean up */
600 cw1200_unregister_common(self->hw);
601 cw1200_free_common(self->hw);
602 return;
603}
604EXPORT_SYMBOL_GPL(cw1200_core_release);