Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/bluetooth/btmrvl_main.c
15109 views
1
/**
2
* Marvell Bluetooth driver
3
*
4
* Copyright (C) 2009, Marvell International Ltd.
5
*
6
* This software file (the "File") is distributed by Marvell International
7
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
8
* (the "License"). You may use, redistribute and/or modify this File in
9
* accordance with the terms and conditions of the License, a copy of which
10
* is available by writing to the Free Software Foundation, Inc.,
11
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13
*
14
*
15
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18
* this warranty disclaimer.
19
**/
20
21
#include <net/bluetooth/bluetooth.h>
22
#include <net/bluetooth/hci_core.h>
23
24
#include "btmrvl_drv.h"
25
26
#define VERSION "1.0"
27
28
/*
29
* This function is called by interface specific interrupt handler.
30
* It updates Power Save & Host Sleep states, and wakes up the main
31
* thread.
32
*/
33
void btmrvl_interrupt(struct btmrvl_private *priv)
34
{
35
priv->adapter->ps_state = PS_AWAKE;
36
37
priv->adapter->wakeup_tries = 0;
38
39
priv->adapter->int_count++;
40
41
wake_up_interruptible(&priv->main_thread.wait_q);
42
}
43
EXPORT_SYMBOL_GPL(btmrvl_interrupt);
44
45
void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
46
{
47
struct hci_event_hdr *hdr = (void *) skb->data;
48
struct hci_ev_cmd_complete *ec;
49
u16 opcode, ocf;
50
51
if (hdr->evt == HCI_EV_CMD_COMPLETE) {
52
ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
53
opcode = __le16_to_cpu(ec->opcode);
54
ocf = hci_opcode_ocf(opcode);
55
if (ocf == BT_CMD_MODULE_CFG_REQ &&
56
priv->btmrvl_dev.sendcmdflag) {
57
priv->btmrvl_dev.sendcmdflag = false;
58
priv->adapter->cmd_complete = true;
59
wake_up_interruptible(&priv->adapter->cmd_wait_q);
60
}
61
}
62
}
63
EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt);
64
65
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
66
{
67
struct btmrvl_adapter *adapter = priv->adapter;
68
struct btmrvl_event *event;
69
int ret = 0;
70
71
event = (struct btmrvl_event *) skb->data;
72
if (event->ec != 0xff) {
73
BT_DBG("Not Marvell Event=%x", event->ec);
74
ret = -EINVAL;
75
goto exit;
76
}
77
78
switch (event->data[0]) {
79
case BT_CMD_AUTO_SLEEP_MODE:
80
if (!event->data[2]) {
81
if (event->data[1] == BT_PS_ENABLE)
82
adapter->psmode = 1;
83
else
84
adapter->psmode = 0;
85
BT_DBG("PS Mode:%s",
86
(adapter->psmode) ? "Enable" : "Disable");
87
} else {
88
BT_DBG("PS Mode command failed");
89
}
90
break;
91
92
case BT_CMD_HOST_SLEEP_CONFIG:
93
if (!event->data[3])
94
BT_DBG("gpio=%x, gap=%x", event->data[1],
95
event->data[2]);
96
else
97
BT_DBG("HSCFG command failed");
98
break;
99
100
case BT_CMD_HOST_SLEEP_ENABLE:
101
if (!event->data[1]) {
102
adapter->hs_state = HS_ACTIVATED;
103
if (adapter->psmode)
104
adapter->ps_state = PS_SLEEP;
105
wake_up_interruptible(&adapter->cmd_wait_q);
106
BT_DBG("HS ACTIVATED!");
107
} else {
108
BT_DBG("HS Enable failed");
109
}
110
break;
111
112
case BT_CMD_MODULE_CFG_REQ:
113
if (priv->btmrvl_dev.sendcmdflag &&
114
event->data[1] == MODULE_BRINGUP_REQ) {
115
BT_DBG("EVENT:%s",
116
((event->data[2] == MODULE_BROUGHT_UP) ||
117
(event->data[2] == MODULE_ALREADY_UP)) ?
118
"Bring-up succeed" : "Bring-up failed");
119
120
if (event->length > 3 && event->data[3])
121
priv->btmrvl_dev.dev_type = HCI_AMP;
122
else
123
priv->btmrvl_dev.dev_type = HCI_BREDR;
124
125
BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
126
} else if (priv->btmrvl_dev.sendcmdflag &&
127
event->data[1] == MODULE_SHUTDOWN_REQ) {
128
BT_DBG("EVENT:%s", (event->data[2]) ?
129
"Shutdown failed" : "Shutdown succeed");
130
} else {
131
BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP");
132
ret = -EINVAL;
133
}
134
break;
135
136
case BT_EVENT_POWER_STATE:
137
if (event->data[1] == BT_PS_SLEEP)
138
adapter->ps_state = PS_SLEEP;
139
BT_DBG("EVENT:%s",
140
(adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE");
141
break;
142
143
default:
144
BT_DBG("Unknown Event=%d", event->data[0]);
145
ret = -EINVAL;
146
break;
147
}
148
149
exit:
150
if (!ret)
151
kfree_skb(skb);
152
153
return ret;
154
}
155
EXPORT_SYMBOL_GPL(btmrvl_process_event);
156
157
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
158
{
159
struct sk_buff *skb;
160
struct btmrvl_cmd *cmd;
161
int ret = 0;
162
163
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
164
if (skb == NULL) {
165
BT_ERR("No free skb");
166
return -ENOMEM;
167
}
168
169
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
170
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ));
171
cmd->length = 1;
172
cmd->data[0] = subcmd;
173
174
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
175
176
skb->dev = (void *) priv->btmrvl_dev.hcidev;
177
skb_queue_head(&priv->adapter->tx_queue, skb);
178
179
priv->btmrvl_dev.sendcmdflag = true;
180
181
priv->adapter->cmd_complete = false;
182
183
BT_DBG("Queue module cfg Command");
184
185
wake_up_interruptible(&priv->main_thread.wait_q);
186
187
if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
188
priv->adapter->cmd_complete,
189
msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) {
190
ret = -ETIMEDOUT;
191
BT_ERR("module_cfg_cmd(%x): timeout: %d",
192
subcmd, priv->btmrvl_dev.sendcmdflag);
193
}
194
195
BT_DBG("module cfg Command done");
196
197
return ret;
198
}
199
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
200
201
int btmrvl_enable_ps(struct btmrvl_private *priv)
202
{
203
struct sk_buff *skb;
204
struct btmrvl_cmd *cmd;
205
206
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
207
if (skb == NULL) {
208
BT_ERR("No free skb");
209
return -ENOMEM;
210
}
211
212
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
213
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
214
BT_CMD_AUTO_SLEEP_MODE));
215
cmd->length = 1;
216
217
if (priv->btmrvl_dev.psmode)
218
cmd->data[0] = BT_PS_ENABLE;
219
else
220
cmd->data[0] = BT_PS_DISABLE;
221
222
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
223
224
skb->dev = (void *) priv->btmrvl_dev.hcidev;
225
skb_queue_head(&priv->adapter->tx_queue, skb);
226
227
BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
228
229
return 0;
230
}
231
EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
232
233
static int btmrvl_enable_hs(struct btmrvl_private *priv)
234
{
235
struct sk_buff *skb;
236
struct btmrvl_cmd *cmd;
237
int ret = 0;
238
239
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
240
if (skb == NULL) {
241
BT_ERR("No free skb");
242
return -ENOMEM;
243
}
244
245
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
246
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE));
247
cmd->length = 0;
248
249
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
250
251
skb->dev = (void *) priv->btmrvl_dev.hcidev;
252
skb_queue_head(&priv->adapter->tx_queue, skb);
253
254
BT_DBG("Queue hs enable Command");
255
256
wake_up_interruptible(&priv->main_thread.wait_q);
257
258
if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
259
priv->adapter->hs_state,
260
msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) {
261
ret = -ETIMEDOUT;
262
BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state,
263
priv->adapter->ps_state,
264
priv->adapter->wakeup_tries);
265
}
266
267
return ret;
268
}
269
270
int btmrvl_prepare_command(struct btmrvl_private *priv)
271
{
272
struct sk_buff *skb = NULL;
273
struct btmrvl_cmd *cmd;
274
int ret = 0;
275
276
if (priv->btmrvl_dev.hscfgcmd) {
277
priv->btmrvl_dev.hscfgcmd = 0;
278
279
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
280
if (skb == NULL) {
281
BT_ERR("No free skb");
282
return -ENOMEM;
283
}
284
285
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
286
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG));
287
cmd->length = 2;
288
cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
289
cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
290
291
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
292
293
skb->dev = (void *) priv->btmrvl_dev.hcidev;
294
skb_queue_head(&priv->adapter->tx_queue, skb);
295
296
BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x",
297
cmd->data[0], cmd->data[1]);
298
}
299
300
if (priv->btmrvl_dev.pscmd) {
301
priv->btmrvl_dev.pscmd = 0;
302
btmrvl_enable_ps(priv);
303
}
304
305
if (priv->btmrvl_dev.hscmd) {
306
priv->btmrvl_dev.hscmd = 0;
307
308
if (priv->btmrvl_dev.hsmode) {
309
ret = btmrvl_enable_hs(priv);
310
} else {
311
ret = priv->hw_wakeup_firmware(priv);
312
priv->adapter->hs_state = HS_DEACTIVATED;
313
}
314
}
315
316
return ret;
317
}
318
319
static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
320
{
321
int ret = 0;
322
323
if (!skb || !skb->data)
324
return -EINVAL;
325
326
if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) {
327
BT_ERR("Tx Error: Bad skb length %d : %d",
328
skb->len, BTM_UPLD_SIZE);
329
return -EINVAL;
330
}
331
332
if (skb_headroom(skb) < BTM_HEADER_LEN) {
333
struct sk_buff *tmp = skb;
334
335
skb = skb_realloc_headroom(skb, BTM_HEADER_LEN);
336
if (!skb) {
337
BT_ERR("Tx Error: realloc_headroom failed %d",
338
BTM_HEADER_LEN);
339
skb = tmp;
340
return -EINVAL;
341
}
342
343
kfree_skb(tmp);
344
}
345
346
skb_push(skb, BTM_HEADER_LEN);
347
348
/* header type: byte[3]
349
* HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor
350
* header length: byte[2][1][0]
351
*/
352
353
skb->data[0] = (skb->len & 0x0000ff);
354
skb->data[1] = (skb->len & 0x00ff00) >> 8;
355
skb->data[2] = (skb->len & 0xff0000) >> 16;
356
skb->data[3] = bt_cb(skb)->pkt_type;
357
358
if (priv->hw_host_to_card)
359
ret = priv->hw_host_to_card(priv, skb->data, skb->len);
360
361
return ret;
362
}
363
364
static void btmrvl_init_adapter(struct btmrvl_private *priv)
365
{
366
skb_queue_head_init(&priv->adapter->tx_queue);
367
368
priv->adapter->ps_state = PS_AWAKE;
369
370
init_waitqueue_head(&priv->adapter->cmd_wait_q);
371
}
372
373
static void btmrvl_free_adapter(struct btmrvl_private *priv)
374
{
375
skb_queue_purge(&priv->adapter->tx_queue);
376
377
kfree(priv->adapter);
378
379
priv->adapter = NULL;
380
}
381
382
static int btmrvl_ioctl(struct hci_dev *hdev,
383
unsigned int cmd, unsigned long arg)
384
{
385
return -ENOIOCTLCMD;
386
}
387
388
static void btmrvl_destruct(struct hci_dev *hdev)
389
{
390
}
391
392
static int btmrvl_send_frame(struct sk_buff *skb)
393
{
394
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
395
struct btmrvl_private *priv = NULL;
396
397
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
398
399
if (!hdev || !hdev->driver_data) {
400
BT_ERR("Frame for unknown HCI device");
401
return -ENODEV;
402
}
403
404
priv = (struct btmrvl_private *) hdev->driver_data;
405
if (!test_bit(HCI_RUNNING, &hdev->flags)) {
406
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
407
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
408
skb->data, skb->len);
409
return -EBUSY;
410
}
411
412
switch (bt_cb(skb)->pkt_type) {
413
case HCI_COMMAND_PKT:
414
hdev->stat.cmd_tx++;
415
break;
416
417
case HCI_ACLDATA_PKT:
418
hdev->stat.acl_tx++;
419
break;
420
421
case HCI_SCODATA_PKT:
422
hdev->stat.sco_tx++;
423
break;
424
}
425
426
skb_queue_tail(&priv->adapter->tx_queue, skb);
427
428
wake_up_interruptible(&priv->main_thread.wait_q);
429
430
return 0;
431
}
432
433
static int btmrvl_flush(struct hci_dev *hdev)
434
{
435
struct btmrvl_private *priv = hdev->driver_data;
436
437
skb_queue_purge(&priv->adapter->tx_queue);
438
439
return 0;
440
}
441
442
static int btmrvl_close(struct hci_dev *hdev)
443
{
444
struct btmrvl_private *priv = hdev->driver_data;
445
446
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
447
return 0;
448
449
skb_queue_purge(&priv->adapter->tx_queue);
450
451
return 0;
452
}
453
454
static int btmrvl_open(struct hci_dev *hdev)
455
{
456
set_bit(HCI_RUNNING, &hdev->flags);
457
458
return 0;
459
}
460
461
/*
462
* This function handles the event generated by firmware, rx data
463
* received from firmware, and tx data sent from kernel.
464
*/
465
static int btmrvl_service_main_thread(void *data)
466
{
467
struct btmrvl_thread *thread = data;
468
struct btmrvl_private *priv = thread->priv;
469
struct btmrvl_adapter *adapter = priv->adapter;
470
wait_queue_t wait;
471
struct sk_buff *skb;
472
ulong flags;
473
474
init_waitqueue_entry(&wait, current);
475
476
current->flags |= PF_NOFREEZE;
477
478
for (;;) {
479
add_wait_queue(&thread->wait_q, &wait);
480
481
set_current_state(TASK_INTERRUPTIBLE);
482
483
if (adapter->wakeup_tries ||
484
((!adapter->int_count) &&
485
(!priv->btmrvl_dev.tx_dnld_rdy ||
486
skb_queue_empty(&adapter->tx_queue)))) {
487
BT_DBG("main_thread is sleeping...");
488
schedule();
489
}
490
491
set_current_state(TASK_RUNNING);
492
493
remove_wait_queue(&thread->wait_q, &wait);
494
495
BT_DBG("main_thread woke up");
496
497
if (kthread_should_stop()) {
498
BT_DBG("main_thread: break from main thread");
499
break;
500
}
501
502
spin_lock_irqsave(&priv->driver_lock, flags);
503
if (adapter->int_count) {
504
adapter->int_count = 0;
505
spin_unlock_irqrestore(&priv->driver_lock, flags);
506
priv->hw_process_int_status(priv);
507
} else if (adapter->ps_state == PS_SLEEP &&
508
!skb_queue_empty(&adapter->tx_queue)) {
509
spin_unlock_irqrestore(&priv->driver_lock, flags);
510
adapter->wakeup_tries++;
511
priv->hw_wakeup_firmware(priv);
512
continue;
513
} else {
514
spin_unlock_irqrestore(&priv->driver_lock, flags);
515
}
516
517
if (adapter->ps_state == PS_SLEEP)
518
continue;
519
520
if (!priv->btmrvl_dev.tx_dnld_rdy)
521
continue;
522
523
skb = skb_dequeue(&adapter->tx_queue);
524
if (skb) {
525
if (btmrvl_tx_pkt(priv, skb))
526
priv->btmrvl_dev.hcidev->stat.err_tx++;
527
else
528
priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len;
529
530
kfree_skb(skb);
531
}
532
}
533
534
return 0;
535
}
536
537
int btmrvl_register_hdev(struct btmrvl_private *priv)
538
{
539
struct hci_dev *hdev = NULL;
540
int ret;
541
542
hdev = hci_alloc_dev();
543
if (!hdev) {
544
BT_ERR("Can not allocate HCI device");
545
goto err_hdev;
546
}
547
548
priv->btmrvl_dev.hcidev = hdev;
549
hdev->driver_data = priv;
550
551
hdev->bus = HCI_SDIO;
552
hdev->open = btmrvl_open;
553
hdev->close = btmrvl_close;
554
hdev->flush = btmrvl_flush;
555
hdev->send = btmrvl_send_frame;
556
hdev->destruct = btmrvl_destruct;
557
hdev->ioctl = btmrvl_ioctl;
558
hdev->owner = THIS_MODULE;
559
560
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
561
562
hdev->dev_type = priv->btmrvl_dev.dev_type;
563
564
ret = hci_register_dev(hdev);
565
if (ret < 0) {
566
BT_ERR("Can not register HCI device");
567
goto err_hci_register_dev;
568
}
569
570
#ifdef CONFIG_DEBUG_FS
571
btmrvl_debugfs_init(hdev);
572
#endif
573
574
return 0;
575
576
err_hci_register_dev:
577
hci_free_dev(hdev);
578
579
err_hdev:
580
/* Stop the thread servicing the interrupts */
581
kthread_stop(priv->main_thread.task);
582
583
btmrvl_free_adapter(priv);
584
kfree(priv);
585
586
return -ENOMEM;
587
}
588
EXPORT_SYMBOL_GPL(btmrvl_register_hdev);
589
590
struct btmrvl_private *btmrvl_add_card(void *card)
591
{
592
struct btmrvl_private *priv;
593
594
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
595
if (!priv) {
596
BT_ERR("Can not allocate priv");
597
goto err_priv;
598
}
599
600
priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
601
if (!priv->adapter) {
602
BT_ERR("Allocate buffer for btmrvl_adapter failed!");
603
goto err_adapter;
604
}
605
606
btmrvl_init_adapter(priv);
607
608
BT_DBG("Starting kthread...");
609
priv->main_thread.priv = priv;
610
spin_lock_init(&priv->driver_lock);
611
612
init_waitqueue_head(&priv->main_thread.wait_q);
613
priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
614
&priv->main_thread, "btmrvl_main_service");
615
616
priv->btmrvl_dev.card = card;
617
priv->btmrvl_dev.tx_dnld_rdy = true;
618
619
return priv;
620
621
err_adapter:
622
kfree(priv);
623
624
err_priv:
625
return NULL;
626
}
627
EXPORT_SYMBOL_GPL(btmrvl_add_card);
628
629
int btmrvl_remove_card(struct btmrvl_private *priv)
630
{
631
struct hci_dev *hdev;
632
633
hdev = priv->btmrvl_dev.hcidev;
634
635
wake_up_interruptible(&priv->adapter->cmd_wait_q);
636
637
kthread_stop(priv->main_thread.task);
638
639
#ifdef CONFIG_DEBUG_FS
640
btmrvl_debugfs_remove(hdev);
641
#endif
642
643
hci_unregister_dev(hdev);
644
645
hci_free_dev(hdev);
646
647
priv->btmrvl_dev.hcidev = NULL;
648
649
btmrvl_free_adapter(priv);
650
651
kfree(priv);
652
653
return 0;
654
}
655
EXPORT_SYMBOL_GPL(btmrvl_remove_card);
656
657
MODULE_AUTHOR("Marvell International Ltd.");
658
MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION);
659
MODULE_VERSION(VERSION);
660
MODULE_LICENSE("GPL v2");
661
662