OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [bluetooth/] [hci_ll.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  Texas Instruments' Bluetooth HCILL UART protocol
3
 *
4
 *  HCILL (HCI Low Level) is a Texas Instruments' power management
5
 *  protocol extension to H4.
6
 *
7
 *  Copyright (C) 2007 Texas Instruments, Inc.
8
 *
9
 *  Written by Ohad Ben-Cohen <ohad@bencohen.org>
10
 *
11
 *  Acknowledgements:
12
 *  This file is based on hci_h4.c, which was written
13
 *  by Maxim Krasnyansky and Marcel Holtmann.
14
 *
15
 *  This program is free software; you can redistribute it and/or modify
16
 *  it under the terms of the GNU General Public License version 2
17
 *  as published by the Free Software Foundation
18
 *
19
 *  This program is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  You should have received a copy of the GNU General Public License
25
 *  along with this program; if not, write to the Free Software
26
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 *
28
 */
29
 
30
#include <linux/module.h>
31
#include <linux/kernel.h>
32
 
33
#include <linux/init.h>
34
#include <linux/sched.h>
35
#include <linux/types.h>
36
#include <linux/fcntl.h>
37
#include <linux/interrupt.h>
38
#include <linux/ptrace.h>
39
#include <linux/poll.h>
40
 
41
#include <linux/slab.h>
42
#include <linux/tty.h>
43
#include <linux/errno.h>
44
#include <linux/string.h>
45
#include <linux/signal.h>
46
#include <linux/ioctl.h>
47
#include <linux/skbuff.h>
48
 
49
#include <net/bluetooth/bluetooth.h>
50
#include <net/bluetooth/hci_core.h>
51
 
52
#include "hci_uart.h"
53
 
54
/* HCILL commands */
55
#define HCILL_GO_TO_SLEEP_IND   0x30
56
#define HCILL_GO_TO_SLEEP_ACK   0x31
57
#define HCILL_WAKE_UP_IND       0x32
58
#define HCILL_WAKE_UP_ACK       0x33
59
 
60
/* HCILL receiver States */
61
#define HCILL_W4_PACKET_TYPE    0
62
#define HCILL_W4_EVENT_HDR      1
63
#define HCILL_W4_ACL_HDR        2
64
#define HCILL_W4_SCO_HDR        3
65
#define HCILL_W4_DATA           4
66
 
67
/* HCILL states */
68
enum hcill_states_e {
69
        HCILL_ASLEEP,
70
        HCILL_ASLEEP_TO_AWAKE,
71
        HCILL_AWAKE,
72
        HCILL_AWAKE_TO_ASLEEP
73
};
74
 
75
struct hcill_cmd {
76
        u8 cmd;
77
} __attribute__((packed));
78
 
79
struct ll_struct {
80
        unsigned long rx_state;
81
        unsigned long rx_count;
82
        struct sk_buff *rx_skb;
83
        struct sk_buff_head txq;
84
        spinlock_t hcill_lock;          /* HCILL state lock     */
85
        unsigned long hcill_state;      /* HCILL power state    */
86
        struct sk_buff_head tx_wait_q;  /* HCILL wait queue     */
87
};
88
 
89
/*
90
 * Builds and sends an HCILL command packet.
91
 * These are very simple packets with only 1 cmd byte
92
 */
93
static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
94
{
95
        int err = 0;
96
        struct sk_buff *skb = NULL;
97
        struct ll_struct *ll = hu->priv;
98
        struct hcill_cmd *hcill_packet;
99
 
100
        BT_DBG("hu %p cmd 0x%x", hu, cmd);
101
 
102
        /* allocate packet */
103
        skb = bt_skb_alloc(1, GFP_ATOMIC);
104
        if (!skb) {
105
                BT_ERR("cannot allocate memory for HCILL packet");
106
                err = -ENOMEM;
107
                goto out;
108
        }
109
 
110
        /* prepare packet */
111
        hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
112
        hcill_packet->cmd = cmd;
113
        skb->dev = (void *) hu->hdev;
114
 
115
        /* send packet */
116
        skb_queue_tail(&ll->txq, skb);
117
out:
118
        return err;
119
}
120
 
121
/* Initialize protocol */
122
static int ll_open(struct hci_uart *hu)
123
{
124
        struct ll_struct *ll;
125
 
126
        BT_DBG("hu %p", hu);
127
 
128
        ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
129
        if (!ll)
130
                return -ENOMEM;
131
 
132
        skb_queue_head_init(&ll->txq);
133
        skb_queue_head_init(&ll->tx_wait_q);
134
        spin_lock_init(&ll->hcill_lock);
135
 
136
        ll->hcill_state = HCILL_AWAKE;
137
 
138
        hu->priv = ll;
139
 
140
        return 0;
141
}
142
 
143
/* Flush protocol data */
144
static int ll_flush(struct hci_uart *hu)
145
{
146
        struct ll_struct *ll = hu->priv;
147
 
148
        BT_DBG("hu %p", hu);
149
 
150
        skb_queue_purge(&ll->tx_wait_q);
151
        skb_queue_purge(&ll->txq);
152
 
153
        return 0;
154
}
155
 
156
/* Close protocol */
157
static int ll_close(struct hci_uart *hu)
158
{
159
        struct ll_struct *ll = hu->priv;
160
 
161
        BT_DBG("hu %p", hu);
162
 
163
        skb_queue_purge(&ll->tx_wait_q);
164
        skb_queue_purge(&ll->txq);
165
 
166
        if (ll->rx_skb)
167
                kfree_skb(ll->rx_skb);
168
 
169
        hu->priv = NULL;
170
 
171
        kfree(ll);
172
 
173
        return 0;
174
}
175
 
176
/*
177
 * internal function, which does common work of the device wake up process:
178
 * 1. places all pending packets (waiting in tx_wait_q list) in txq list.
179
 * 2. changes internal state to HCILL_AWAKE.
180
 * Note: assumes that hcill_lock spinlock is taken,
181
 * shouldn't be called otherwise!
182
 */
183
static void __ll_do_awake(struct ll_struct *ll)
184
{
185
        struct sk_buff *skb = NULL;
186
 
187
        while ((skb = skb_dequeue(&ll->tx_wait_q)))
188
                skb_queue_tail(&ll->txq, skb);
189
 
190
        ll->hcill_state = HCILL_AWAKE;
191
}
192
 
193
/*
194
 * Called upon a wake-up-indication from the device
195
 */
196
static void ll_device_want_to_wakeup(struct hci_uart *hu)
197
{
198
        unsigned long flags;
199
        struct ll_struct *ll = hu->priv;
200
 
201
        BT_DBG("hu %p", hu);
202
 
203
        /* lock hcill state */
204
        spin_lock_irqsave(&ll->hcill_lock, flags);
205
 
206
        switch (ll->hcill_state) {
207
        case HCILL_ASLEEP_TO_AWAKE:
208
                /*
209
                 * This state means that both the host and the BRF chip
210
                 * have simultaneously sent a wake-up-indication packet.
211
                 * Traditionaly, in this case, receiving a wake-up-indication
212
                 * was enough and an additional wake-up-ack wasn't needed.
213
                 * This has changed with the BRF6350, which does require an
214
                 * explicit wake-up-ack. Other BRF versions, which do not
215
                 * require an explicit ack here, do accept it, thus it is
216
                 * perfectly safe to always send one.
217
                 */
218
                BT_DBG("dual wake-up-indication");
219
                /* deliberate fall-through - do not add break */
220
        case HCILL_ASLEEP:
221
                /* acknowledge device wake up */
222
                if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
223
                        BT_ERR("cannot acknowledge device wake up");
224
                        goto out;
225
                }
226
                break;
227
        default:
228
                /* any other state is illegal */
229
                BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
230
                break;
231
        }
232
 
233
        /* send pending packets and change state to HCILL_AWAKE */
234
        __ll_do_awake(ll);
235
 
236
out:
237
        spin_unlock_irqrestore(&ll->hcill_lock, flags);
238
 
239
        /* actually send the packets */
240
        hci_uart_tx_wakeup(hu);
241
}
242
 
243
/*
244
 * Called upon a sleep-indication from the device
245
 */
246
static void ll_device_want_to_sleep(struct hci_uart *hu)
247
{
248
        unsigned long flags;
249
        struct ll_struct *ll = hu->priv;
250
 
251
        BT_DBG("hu %p", hu);
252
 
253
        /* lock hcill state */
254
        spin_lock_irqsave(&ll->hcill_lock, flags);
255
 
256
        /* sanity check */
257
        if (ll->hcill_state != HCILL_AWAKE)
258
                BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);
259
 
260
        /* acknowledge device sleep */
261
        if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
262
                BT_ERR("cannot acknowledge device sleep");
263
                goto out;
264
        }
265
 
266
        /* update state */
267
        ll->hcill_state = HCILL_ASLEEP;
268
 
269
out:
270
        spin_unlock_irqrestore(&ll->hcill_lock, flags);
271
 
272
        /* actually send the sleep ack packet */
273
        hci_uart_tx_wakeup(hu);
274
}
275
 
276
/*
277
 * Called upon wake-up-acknowledgement from the device
278
 */
279
static void ll_device_woke_up(struct hci_uart *hu)
280
{
281
        unsigned long flags;
282
        struct ll_struct *ll = hu->priv;
283
 
284
        BT_DBG("hu %p", hu);
285
 
286
        /* lock hcill state */
287
        spin_lock_irqsave(&ll->hcill_lock, flags);
288
 
289
        /* sanity check */
290
        if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE)
291
                BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state);
292
 
293
        /* send pending packets and change state to HCILL_AWAKE */
294
        __ll_do_awake(ll);
295
 
296
        spin_unlock_irqrestore(&ll->hcill_lock, flags);
297
 
298
        /* actually send the packets */
299
        hci_uart_tx_wakeup(hu);
300
}
301
 
302
/* Enqueue frame for transmittion (padding, crc, etc) */
303
/* may be called from two simultaneous tasklets */
304
static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
305
{
306
        unsigned long flags = 0;
307
        struct ll_struct *ll = hu->priv;
308
 
309
        BT_DBG("hu %p skb %p", hu, skb);
310
 
311
        /* Prepend skb with frame type */
312
        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
313
 
314
        /* lock hcill state */
315
        spin_lock_irqsave(&ll->hcill_lock, flags);
316
 
317
        /* act according to current state */
318
        switch (ll->hcill_state) {
319
        case HCILL_AWAKE:
320
                BT_DBG("device awake, sending normally");
321
                skb_queue_tail(&ll->txq, skb);
322
                break;
323
        case HCILL_ASLEEP:
324
                BT_DBG("device asleep, waking up and queueing packet");
325
                /* save packet for later */
326
                skb_queue_tail(&ll->tx_wait_q, skb);
327
                /* awake device */
328
                if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) {
329
                        BT_ERR("cannot wake up device");
330
                        break;
331
                }
332
                ll->hcill_state = HCILL_ASLEEP_TO_AWAKE;
333
                break;
334
        case HCILL_ASLEEP_TO_AWAKE:
335
                BT_DBG("device waking up, queueing packet");
336
                /* transient state; just keep packet for later */
337
                skb_queue_tail(&ll->tx_wait_q, skb);
338
                break;
339
        default:
340
                BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state);
341
                kfree_skb(skb);
342
                break;
343
        }
344
 
345
        spin_unlock_irqrestore(&ll->hcill_lock, flags);
346
 
347
        return 0;
348
}
349
 
350
static inline int ll_check_data_len(struct ll_struct *ll, int len)
351
{
352
        register int room = skb_tailroom(ll->rx_skb);
353
 
354
        BT_DBG("len %d room %d", len, room);
355
 
356
        if (!len) {
357
                hci_recv_frame(ll->rx_skb);
358
        } else if (len > room) {
359
                BT_ERR("Data length is too large");
360
                kfree_skb(ll->rx_skb);
361
        } else {
362
                ll->rx_state = HCILL_W4_DATA;
363
                ll->rx_count = len;
364
                return len;
365
        }
366
 
367
        ll->rx_state = HCILL_W4_PACKET_TYPE;
368
        ll->rx_skb   = NULL;
369
        ll->rx_count = 0;
370
 
371
        return 0;
372
}
373
 
374
/* Recv data */
375
static int ll_recv(struct hci_uart *hu, void *data, int count)
376
{
377
        struct ll_struct *ll = hu->priv;
378
        register char *ptr;
379
        struct hci_event_hdr *eh;
380
        struct hci_acl_hdr   *ah;
381
        struct hci_sco_hdr   *sh;
382
        register int len, type, dlen;
383
 
384
        BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
385
 
386
        ptr = data;
387
        while (count) {
388
                if (ll->rx_count) {
389
                        len = min_t(unsigned int, ll->rx_count, count);
390
                        memcpy(skb_put(ll->rx_skb, len), ptr, len);
391
                        ll->rx_count -= len; count -= len; ptr += len;
392
 
393
                        if (ll->rx_count)
394
                                continue;
395
 
396
                        switch (ll->rx_state) {
397
                        case HCILL_W4_DATA:
398
                                BT_DBG("Complete data");
399
                                hci_recv_frame(ll->rx_skb);
400
 
401
                                ll->rx_state = HCILL_W4_PACKET_TYPE;
402
                                ll->rx_skb = NULL;
403
                                continue;
404
 
405
                        case HCILL_W4_EVENT_HDR:
406
                                eh = (struct hci_event_hdr *) ll->rx_skb->data;
407
 
408
                                BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
409
 
410
                                ll_check_data_len(ll, eh->plen);
411
                                continue;
412
 
413
                        case HCILL_W4_ACL_HDR:
414
                                ah = (struct hci_acl_hdr *) ll->rx_skb->data;
415
                                dlen = __le16_to_cpu(ah->dlen);
416
 
417
                                BT_DBG("ACL header: dlen %d", dlen);
418
 
419
                                ll_check_data_len(ll, dlen);
420
                                continue;
421
 
422
                        case HCILL_W4_SCO_HDR:
423
                                sh = (struct hci_sco_hdr *) ll->rx_skb->data;
424
 
425
                                BT_DBG("SCO header: dlen %d", sh->dlen);
426
 
427
                                ll_check_data_len(ll, sh->dlen);
428
                                continue;
429
                        }
430
                }
431
 
432
                /* HCILL_W4_PACKET_TYPE */
433
                switch (*ptr) {
434
                case HCI_EVENT_PKT:
435
                        BT_DBG("Event packet");
436
                        ll->rx_state = HCILL_W4_EVENT_HDR;
437
                        ll->rx_count = HCI_EVENT_HDR_SIZE;
438
                        type = HCI_EVENT_PKT;
439
                        break;
440
 
441
                case HCI_ACLDATA_PKT:
442
                        BT_DBG("ACL packet");
443
                        ll->rx_state = HCILL_W4_ACL_HDR;
444
                        ll->rx_count = HCI_ACL_HDR_SIZE;
445
                        type = HCI_ACLDATA_PKT;
446
                        break;
447
 
448
                case HCI_SCODATA_PKT:
449
                        BT_DBG("SCO packet");
450
                        ll->rx_state = HCILL_W4_SCO_HDR;
451
                        ll->rx_count = HCI_SCO_HDR_SIZE;
452
                        type = HCI_SCODATA_PKT;
453
                        break;
454
 
455
                /* HCILL signals */
456
                case HCILL_GO_TO_SLEEP_IND:
457
                        BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
458
                        ll_device_want_to_sleep(hu);
459
                        ptr++; count--;
460
                        continue;
461
 
462
                case HCILL_GO_TO_SLEEP_ACK:
463
                        /* shouldn't happen */
464
                        BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state);
465
                        ptr++; count--;
466
                        continue;
467
 
468
                case HCILL_WAKE_UP_IND:
469
                        BT_DBG("HCILL_WAKE_UP_IND packet");
470
                        ll_device_want_to_wakeup(hu);
471
                        ptr++; count--;
472
                        continue;
473
 
474
                case HCILL_WAKE_UP_ACK:
475
                        BT_DBG("HCILL_WAKE_UP_ACK packet");
476
                        ll_device_woke_up(hu);
477
                        ptr++; count--;
478
                        continue;
479
 
480
                default:
481
                        BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
482
                        hu->hdev->stat.err_rx++;
483
                        ptr++; count--;
484
                        continue;
485
                };
486
 
487
                ptr++; count--;
488
 
489
                /* Allocate packet */
490
                ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
491
                if (!ll->rx_skb) {
492
                        BT_ERR("Can't allocate mem for new packet");
493
                        ll->rx_state = HCILL_W4_PACKET_TYPE;
494
                        ll->rx_count = 0;
495
                        return 0;
496
                }
497
 
498
                ll->rx_skb->dev = (void *) hu->hdev;
499
                bt_cb(ll->rx_skb)->pkt_type = type;
500
        }
501
 
502
        return count;
503
}
504
 
505
static struct sk_buff *ll_dequeue(struct hci_uart *hu)
506
{
507
        struct ll_struct *ll = hu->priv;
508
        return skb_dequeue(&ll->txq);
509
}
510
 
511
static struct hci_uart_proto llp = {
512
        .id             = HCI_UART_LL,
513
        .open           = ll_open,
514
        .close          = ll_close,
515
        .recv           = ll_recv,
516
        .enqueue        = ll_enqueue,
517
        .dequeue        = ll_dequeue,
518
        .flush          = ll_flush,
519
};
520
 
521
int ll_init(void)
522
{
523
        int err = hci_uart_register_proto(&llp);
524
 
525
        if (!err)
526
                BT_INFO("HCILL protocol initialized");
527
        else
528
                BT_ERR("HCILL protocol registration failed");
529
 
530
        return err;
531
}
532
 
533
int ll_deinit(void)
534
{
535
        return hci_uart_unregister_proto(&llp);
536
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.