blob: 2a6f3f84b9353f700794a072fb490b6bd173e4ca [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * Qualcomm's Bluetooth Software In-Band Sleep UART protocol
3 *
4 * HCI_IBS (HCI In-Band Sleep) is Qualcomm's power management
5 * protocol extension to H4.
6 *
7 * Copyright (C) 2007 Texas Instruments, Inc.
8 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
9 *
10 * Acknowledgements:
11 * This file is based on hci_ll.c, which was...
12 * Written by Ohad Ben-Cohen <ohad@bencohen.org>
13 * which was in turn based on hci_h4.c, which was written
14 * by Maxim Krasnyansky and Marcel Holtmann.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33
34#include <linux/init.h>
35#include <linux/sched.h>
36#include <linux/types.h>
37#include <linux/fcntl.h>
38#include <linux/interrupt.h>
39#include <linux/ptrace.h>
40#include <linux/poll.h>
41
42#include <linux/slab.h>
43#include <linux/tty.h>
44#include <linux/errno.h>
45#include <linux/string.h>
46#include <linux/signal.h>
47#include <linux/ioctl.h>
48#include <linux/timer.h>
49#include <linux/skbuff.h>
50#include <linux/serial_core.h>
51
52#ifdef CONFIG_SERIAL_MSM_HS
53#include <mach/msm_serial_hs.h>
54#endif
55
56#include <net/bluetooth/bluetooth.h>
57#include <net/bluetooth/hci_core.h>
58
59#include "hci_uart.h"
60
61/* HCI_IBS protocol messages */
62#define HCI_IBS_SLEEP_IND 0xFE
63#define HCI_IBS_WAKE_IND 0xFD
64#define HCI_IBS_WAKE_ACK 0xFC
65
66/* HCI_IBS receiver States */
67#define HCI_IBS_W4_PACKET_TYPE 0
68#define HCI_IBS_W4_EVENT_HDR 1
69#define HCI_IBS_W4_ACL_HDR 2
70#define HCI_IBS_W4_SCO_HDR 3
71#define HCI_IBS_W4_DATA 4
72
73/* HCI_IBS transmit side sleep protocol states */
74enum tx_ibs_states_e {
75 HCI_IBS_TX_ASLEEP,
76 HCI_IBS_TX_WAKING,
77 HCI_IBS_TX_AWAKE,
78};
79
80/* HCI_IBS receive side sleep protocol states */
81enum rx_states_e {
82 HCI_IBS_RX_ASLEEP,
83 HCI_IBS_RX_AWAKE,
84};
85
86/* HCI_IBS transmit and receive side clock state vote */
87enum hci_ibs_clock_state_vote_e {
88 HCI_IBS_VOTE_STATS_UPDATE,
89 HCI_IBS_TX_VOTE_CLOCK_ON,
90 HCI_IBS_TX_VOTE_CLOCK_OFF,
91 HCI_IBS_RX_VOTE_CLOCK_ON,
92 HCI_IBS_RX_VOTE_CLOCK_OFF,
93};
94
95static unsigned long wake_retrans = 1;
96static unsigned long tx_idle_delay = (HZ * 2);
97
98struct hci_ibs_cmd {
99 u8 cmd;
100} __attribute__((packed));
101
102struct ibs_struct {
103 unsigned long rx_state;
104 unsigned long rx_count;
105 struct sk_buff *rx_skb;
106 struct sk_buff_head txq;
107 struct sk_buff_head tx_wait_q; /* HCI_IBS wait queue */
108 spinlock_t hci_ibs_lock; /* HCI_IBS state lock */
109 unsigned long tx_ibs_state; /* HCI_IBS transmit side power state */
110 unsigned long rx_ibs_state; /* HCI_IBS receive side power state */
111 unsigned long tx_vote; /* clock must be on for TX */
112 unsigned long rx_vote; /* clock must be on for RX */
113 struct timer_list tx_idle_timer;
114 struct timer_list wake_retrans_timer;
115 /* debug */
116 unsigned long ibs_sent_wacks;
117 unsigned long ibs_sent_slps;
118 unsigned long ibs_sent_wakes;
119 unsigned long ibs_recv_wacks;
120 unsigned long ibs_recv_slps;
121 unsigned long ibs_recv_wakes;
122 unsigned long vote_last_jif;
123 unsigned long vote_on_ticks;
124 unsigned long vote_off_ticks;
125 unsigned long tx_votes_on;
126 unsigned long rx_votes_on;
127 unsigned long tx_votes_off;
128 unsigned long rx_votes_off;
129 unsigned long votes_on;
130 unsigned long votes_off;
131};
132
133#ifdef CONFIG_SERIAL_MSM_HS
134static void __ibs_msm_serial_clock_on(struct tty_struct *tty)
135{
136 struct uart_state *state = tty->driver_data;
137 struct uart_port *port = state->uart_port;
138
139 msm_hs_request_clock_on(port);
140}
141
142static void __ibs_msm_serial_clock_request_off(struct tty_struct *tty)
143{
144 struct uart_state *state = tty->driver_data;
145 struct uart_port *port = state->uart_port;
146
147 msm_hs_request_clock_off(port);
148}
149#else
150static inline void __ibs_msm_serial_clock_on(struct tty_struct *tty) {}
151static inline void __ibs_msm_serial_clock_request_off(struct tty_struct *tty) {}
152#endif
153
154/* clock_vote needs to be called with the ibs lock held */
155static void ibs_msm_serial_clock_vote(unsigned long vote, struct hci_uart *hu)
156{
157 struct ibs_struct *ibs = hu->priv;
158
159 unsigned long old_vote = (ibs->tx_vote | ibs->rx_vote);
160 unsigned long new_vote;
161
162 switch (vote) {
163 default: /* error */
164 BT_ERR("voting irregularity");
165 return;
166 case HCI_IBS_VOTE_STATS_UPDATE:
167 if (old_vote)
168 ibs->vote_off_ticks += (jiffies - ibs->vote_last_jif);
169 else
170 ibs->vote_on_ticks += (jiffies - ibs->vote_last_jif);
171 return;
172 case HCI_IBS_TX_VOTE_CLOCK_ON:
173 ibs->tx_vote = 1;
174 ibs->tx_votes_on++;
175 new_vote = 1;
176 break;
177 case HCI_IBS_RX_VOTE_CLOCK_ON:
178 ibs->rx_vote = 1;
179 ibs->rx_votes_on++;
180 new_vote = 1;
181 break;
182 case HCI_IBS_TX_VOTE_CLOCK_OFF:
183 ibs->tx_vote = 0;
184 ibs->tx_votes_off++;
185 new_vote = ibs->rx_vote | ibs->tx_vote;
186 break;
187 case HCI_IBS_RX_VOTE_CLOCK_OFF:
188 ibs->rx_vote = 0;
189 ibs->rx_votes_off++;
190 new_vote = ibs->rx_vote | ibs->tx_vote;
191 break;
192 }
193 if (new_vote != old_vote) {
194 if (new_vote)
195 __ibs_msm_serial_clock_on(hu->tty);
196 else
197 __ibs_msm_serial_clock_request_off(hu->tty);
198
199 BT_DBG("HCIUART_IBS: vote msm_serial_hs clock %lu(%lu)",
200 new_vote, vote);
201 /* debug */
202 if (new_vote) {
203 ibs->votes_on++;
204 ibs->vote_off_ticks += (jiffies - ibs->vote_last_jif);
205 } else {
206 ibs->votes_off++;
207 ibs->vote_on_ticks += (jiffies - ibs->vote_last_jif);
208 }
209 ibs->vote_last_jif = jiffies;
210 }
211}
212
213/*
214 * Builds and sends an HCI_IBS command packet.
215 * These are very simple packets with only 1 cmd byte
216 */
217static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu)
218{
219 int err = 0;
220 struct sk_buff *skb = NULL;
221 struct ibs_struct *ibs = hu->priv;
222 struct hci_ibs_cmd *hci_ibs_packet;
223
224 BT_DBG("hu %p cmd 0x%x", hu, cmd);
225
226 /* allocate packet */
227 skb = bt_skb_alloc(1, GFP_ATOMIC);
228 if (!skb) {
229 BT_ERR("cannot allocate memory for HCI_IBS packet");
230 err = -ENOMEM;
231 goto out;
232 }
233
234 /* prepare packet */
235 hci_ibs_packet = (struct hci_ibs_cmd *) skb_put(skb, 1);
236 hci_ibs_packet->cmd = cmd;
237 skb->dev = (void *) hu->hdev;
238
239 /* send packet */
240 skb_queue_tail(&ibs->txq, skb);
241out:
242 return err;
243}
244
245static void hci_ibs_tx_idle_timeout(unsigned long arg)
246{
247 struct hci_uart *hu = (struct hci_uart *) arg;
248 struct ibs_struct *ibs = hu->priv;
249 unsigned long flags;
250 unsigned long vote_tx_sleep = 0;
251
252 BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state);
253
254 spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
255 flags, SINGLE_DEPTH_NESTING);
256
257 switch (ibs->tx_ibs_state) {
258 default:
259 case HCI_IBS_TX_ASLEEP:
260 case HCI_IBS_TX_WAKING:
261 BT_ERR("spurrious timeout in tx state %ld", ibs->tx_ibs_state);
262 goto out;
263 case HCI_IBS_TX_AWAKE: /* TX_IDLE, go to SLEEP */
264 if (send_hci_ibs_cmd(HCI_IBS_SLEEP_IND, hu) < 0) {
265 BT_ERR("cannot send SLEEP to device");
266 goto out;
267 }
268 ibs->tx_ibs_state = HCI_IBS_TX_ASLEEP;
269 ibs->ibs_sent_slps++; /* debug */
270 vote_tx_sleep = 1;
271 break;
272 }
273
274 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
275
276 hci_uart_tx_wakeup(hu); /* run HCI tx handling unlocked */
277
278 if (!vote_tx_sleep)
279 return;
280 /* now that message queued to tty driver, vote for tty clocks off */
281 /* It is up to the tty driver to pend the clocks off until tx done. */
282
283 spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
284 flags, SINGLE_DEPTH_NESTING);
285 ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
286out:
287 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
288}
289
290static void hci_ibs_wake_retrans_timeout(unsigned long arg)
291{
292 struct hci_uart *hu = (struct hci_uart *) arg;
293 struct ibs_struct *ibs = hu->priv;
294 unsigned long flags;
295 unsigned long retransmit = 0;
296
297 BT_DBG("hu %p wake retransmit timeout in %lu state",
298 hu, ibs->tx_ibs_state);
299
300 spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
301 flags, SINGLE_DEPTH_NESTING);
302
303 switch (ibs->tx_ibs_state) {
304 default:
305 case HCI_IBS_TX_ASLEEP:
306 case HCI_IBS_TX_AWAKE:
307 BT_ERR("spurrious timeout tx state %ld", ibs->tx_ibs_state);
308 goto out;
309 case HCI_IBS_TX_WAKING: /* No WAKE_ACK, retransmit WAKE */
310 retransmit = 1;
311 if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
312 BT_ERR("cannot acknowledge device wake up");
313 goto out;
314 }
315 ibs->ibs_sent_wakes++; /* debug */
316 mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
317 break;
318 }
319out:
320 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
321 if (retransmit)
322 hci_uart_tx_wakeup(hu);
323}
324
325/* Initialize protocol */
326static int ibs_open(struct hci_uart *hu)
327{
328 struct ibs_struct *ibs;
329
330 BT_DBG("hu %p", hu);
331
332 ibs = kzalloc(sizeof(*ibs), GFP_ATOMIC);
333 if (!ibs)
334 return -ENOMEM;
335
336 skb_queue_head_init(&ibs->txq);
337 skb_queue_head_init(&ibs->tx_wait_q);
338 spin_lock_init(&ibs->hci_ibs_lock);
339
340 /* Assume we start with both sides asleep -- extra wakes OK */
341 ibs->tx_ibs_state = HCI_IBS_TX_ASLEEP;
342 ibs->rx_ibs_state = HCI_IBS_RX_ASLEEP;
343 /* clocks actually on, but we start votes off */
344 ibs->tx_vote = 0;
345 ibs->rx_vote = 0;
346
347 /* debug */
348 ibs->ibs_sent_wacks = 0;
349 ibs->ibs_sent_slps = 0;
350 ibs->ibs_sent_wakes = 0;
351 ibs->ibs_recv_wacks = 0;
352 ibs->ibs_recv_slps = 0;
353 ibs->ibs_recv_wakes = 0;
354 ibs->vote_last_jif = jiffies;
355 ibs->vote_on_ticks = 0;
356 ibs->vote_off_ticks = 0;
357 ibs->votes_on = 0;
358 ibs->votes_off = 0;
359 ibs->tx_votes_on = 0;
360 ibs->tx_votes_off = 0;
361 ibs->rx_votes_on = 0;
362 ibs->rx_votes_off = 0;
363
364 hu->priv = ibs;
365
366 init_timer(&ibs->wake_retrans_timer);
367 ibs->wake_retrans_timer.function = hci_ibs_wake_retrans_timeout;
368 ibs->wake_retrans_timer.data = (u_long) hu;
369
370 init_timer(&ibs->tx_idle_timer);
371 ibs->tx_idle_timer.function = hci_ibs_tx_idle_timeout;
372 ibs->tx_idle_timer.data = (u_long) hu;
373
374 BT_INFO("HCI_IBS open, tx_idle_delay=%lu, wake_retrans=%lu",
375 tx_idle_delay, wake_retrans);
376
377 return 0;
378}
379
380void ibs_log_local_stats(struct ibs_struct *ibs)
381{
382 BT_INFO("HCI_IBS stats: tx_idle_delay=%lu, wake_retrans=%lu",
383 tx_idle_delay, wake_retrans);
384
385 BT_INFO("HCI_IBS stats: tx_ibs_state=%lu, rx_ibs_state=%lu",
386 ibs->tx_ibs_state, ibs->rx_ibs_state);
387 BT_INFO("HCI_IBS stats: sent: sleep=%lu, wake=%lu, wake_ack=%lu",
388 ibs->ibs_sent_slps, ibs->ibs_sent_wakes, ibs->ibs_sent_wacks);
389 BT_INFO("HCI_IBS stats: recv: sleep=%lu, wake=%lu, wake_ack=%lu",
390 ibs->ibs_recv_slps, ibs->ibs_recv_wakes, ibs->ibs_recv_wacks);
391
392 BT_INFO("HCI_IBS stats: queues: txq=%s, txwaitq=%s",
393 skb_queue_empty(&(ibs->txq)) ? "empty" : "full",
394 skb_queue_empty(&(ibs->tx_wait_q)) ? "empty" : "full");
395
396 BT_INFO("HCI_IBS stats: vote state: tx=%lu, rx=%lu",
397 ibs->tx_vote, ibs->rx_vote);
398 BT_INFO("HCI_IBS stats: tx votes cast: on=%lu, off=%lu",
399 ibs->tx_votes_on, ibs->tx_votes_off);
400 BT_INFO("HCI_IBS stats: rx votes cast: on=%lu, off=%lu",
401 ibs->rx_votes_on, ibs->rx_votes_off);
402 BT_INFO("HCI_IBS stats: msm_clock votes cast: on=%lu, off=%lu",
403 ibs->votes_on, ibs->votes_off);
404 BT_INFO("HCI_IBS stats: vote ticks: on=%lu, off=%lu",
405 ibs->vote_on_ticks, ibs->vote_off_ticks);
406}
407
408/* Flush protocol data */
409static int ibs_flush(struct hci_uart *hu)
410{
411 struct ibs_struct *ibs = hu->priv;
412
413 BT_DBG("hu %p", hu);
414
415 skb_queue_purge(&ibs->tx_wait_q);
416 skb_queue_purge(&ibs->txq);
417
418 return 0;
419}
420
421/* Close protocol */
422static int ibs_close(struct hci_uart *hu)
423{
424 struct ibs_struct *ibs = hu->priv;
425
426 BT_DBG("hu %p", hu);
427
428 ibs_msm_serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu);
429 ibs_log_local_stats(ibs);
430
431 skb_queue_purge(&ibs->tx_wait_q);
432 skb_queue_purge(&ibs->txq);
433 del_timer(&ibs->tx_idle_timer);
434 del_timer(&ibs->wake_retrans_timer);
435
436 kfree_skb(ibs->rx_skb);
437
438 hu->priv = NULL;
439
440 kfree(ibs);
441
442 return 0;
443}
444
445/*
446 * Called upon a wake-up-indication from the device
447 */
448static void ibs_device_want_to_wakeup(struct hci_uart *hu)
449{
450 unsigned long flags;
451 struct ibs_struct *ibs = hu->priv;
452
453 BT_DBG("hu %p", hu);
454
455 /* lock hci_ibs state */
456 spin_lock_irqsave(&ibs->hci_ibs_lock, flags);
457
458 /* debug */
459 ibs->ibs_recv_wakes++;
460
461 switch (ibs->rx_ibs_state) {
462 case HCI_IBS_RX_ASLEEP:
463 /* Make sure clock is on - we may have turned clock off since
464 * receiving the wake up indicator
465 */
466 ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
467 ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
468 /* deliberate fall-through */
469 case HCI_IBS_RX_AWAKE:
470 /* Always acknowledge device wake up,
471 * sending IBS message doesn't count as TX ON.
472 */
473 if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0) {
474 BT_ERR("cannot acknowledge device wake up");
475 goto out;
476 }
477 ibs->ibs_sent_wacks++; /* debug */
478 break;
479 default:
480 /* any other state is illegal */
481 BT_ERR("received HCI_IBS_WAKE_IND in rx state %ld",
482 ibs->rx_ibs_state);
483 break;
484 }
485
486out:
487 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
488
489 /* actually send the packets */
490 hci_uart_tx_wakeup(hu);
491}
492
493/*
494 * Called upon a sleep-indication from the device
495 */
496static void ibs_device_want_to_sleep(struct hci_uart *hu)
497{
498 unsigned long flags;
499 struct ibs_struct *ibs = hu->priv;
500
501 BT_DBG("hu %p", hu);
502
503 /* lock hci_ibs state */
504 spin_lock_irqsave(&ibs->hci_ibs_lock, flags);
505
506 /* debug */
507 ibs->ibs_recv_slps++;
508
509 switch (ibs->rx_ibs_state) {
510 case HCI_IBS_RX_AWAKE:
511 /* update state */
512 ibs->rx_ibs_state = HCI_IBS_RX_ASLEEP;
513 ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu);
514 break;
515 case HCI_IBS_RX_ASLEEP:
516 /* deliberate fall-through */
517 default:
518 /* any other state is illegal */
519 BT_ERR("received HCI_IBS_SLEEP_IND in rx state %ld",
520 ibs->rx_ibs_state);
521 break;
522 }
523
524 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
525}
526
527/*
528 * Called upon wake-up-acknowledgement from the device
529 */
530static void ibs_device_woke_up(struct hci_uart *hu)
531{
532 unsigned long flags;
533 struct ibs_struct *ibs = hu->priv;
534 struct sk_buff *skb = NULL;
535
536 BT_DBG("hu %p", hu);
537
538 /* lock hci_ibs state */
539 spin_lock_irqsave(&ibs->hci_ibs_lock, flags);
540
541 /* debug */
542 ibs->ibs_recv_wacks++;
543
544 switch (ibs->tx_ibs_state) {
545 case HCI_IBS_TX_ASLEEP:
546 /* This could be spurrious rx wake on the BT chip.
547 * Send it another SLEEP othwise it will stay awake. */
548 default:
549 BT_ERR("received HCI_IBS_WAKE_ACK in tx state %ld",
550 ibs->tx_ibs_state);
551 break;
552 case HCI_IBS_TX_AWAKE:
553 /* expect one if we send 2 WAKEs */
554 BT_DBG("received HCI_IBS_WAKE_ACK in tx state %ld",
555 ibs->tx_ibs_state);
556 break;
557 case HCI_IBS_TX_WAKING:
558 /* send pending packets */
559 while ((skb = skb_dequeue(&ibs->tx_wait_q)))
560 skb_queue_tail(&ibs->txq, skb);
561 /* switch timers and change state to HCI_IBS_TX_AWAKE */
562 del_timer(&ibs->wake_retrans_timer);
563 mod_timer(&ibs->tx_idle_timer, jiffies + tx_idle_delay);
564 ibs->tx_ibs_state = HCI_IBS_TX_AWAKE;
565 }
566
567 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
568
569 /* actually send the packets */
570 hci_uart_tx_wakeup(hu);
571}
572
573/* Enqueue frame for transmittion (padding, crc, etc) */
574/* may be called from two simultaneous tasklets */
575static int ibs_enqueue(struct hci_uart *hu, struct sk_buff *skb)
576{
577 unsigned long flags = 0;
578 struct ibs_struct *ibs = hu->priv;
579
580 BT_DBG("hu %p skb %p", hu, skb);
581
582 /* Prepend skb with frame type */
583 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
584
585 /* lock hci_ibs state */
586 spin_lock_irqsave(&ibs->hci_ibs_lock, flags);
587
588 /* act according to current state */
589 switch (ibs->tx_ibs_state) {
590 case HCI_IBS_TX_AWAKE:
591 BT_DBG("device awake, sending normally");
592 skb_queue_tail(&ibs->txq, skb);
593 mod_timer(&ibs->tx_idle_timer, jiffies + tx_idle_delay);
594 break;
595
596 case HCI_IBS_TX_ASLEEP:
597 BT_DBG("device asleep, waking up and queueing packet");
598 ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
599 /* save packet for later */
600 skb_queue_tail(&ibs->tx_wait_q, skb);
601 /* awake device */
602 if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
603 BT_ERR("cannot send WAKE to device");
604 break;
605 }
606 ibs->ibs_sent_wakes++; /* debug */
607
608 /* start retransmit timer */
609 mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
610
611 ibs->tx_ibs_state = HCI_IBS_TX_WAKING;
612 break;
613
614 case HCI_IBS_TX_WAKING:
615 BT_DBG("device waking up, queueing packet");
616 /* transient state; just keep packet for later */
617 skb_queue_tail(&ibs->tx_wait_q, skb);
618 break;
619
620 default:
621 BT_ERR("illegal tx state: %ld (losing packet)",
622 ibs->tx_ibs_state);
623 kfree_skb(skb);
624 break;
625 }
626
627 spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
628
629 return 0;
630}
631
632static inline int ibs_check_data_len(struct ibs_struct *ibs, int len)
633{
634 register int room = skb_tailroom(ibs->rx_skb);
635
636 BT_DBG("len %d room %d", len, room);
637
638 if (!len) {
639 hci_recv_frame(ibs->rx_skb);
640 } else if (len > room) {
641 BT_ERR("Data length is too large");
642 kfree_skb(ibs->rx_skb);
643 } else {
644 ibs->rx_state = HCI_IBS_W4_DATA;
645 ibs->rx_count = len;
646 return len;
647 }
648
649 ibs->rx_state = HCI_IBS_W4_PACKET_TYPE;
650 ibs->rx_skb = NULL;
651 ibs->rx_count = 0;
652
653 return 0;
654}
655
656/* Recv data */
657static int ibs_recv(struct hci_uart *hu, void *data, int count)
658{
659 struct ibs_struct *ibs = hu->priv;
660 register char *ptr;
661 struct hci_event_hdr *eh;
662 struct hci_acl_hdr *ah;
663 struct hci_sco_hdr *sh;
664 register int len, type, dlen;
665
666 BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
667 hu, count, ibs->rx_state, ibs->rx_count);
668
669 ptr = data;
670 while (count) {
671 if (ibs->rx_count) {
672 len = min_t(unsigned int, ibs->rx_count, count);
673 memcpy(skb_put(ibs->rx_skb, len), ptr, len);
674 ibs->rx_count -= len; count -= len; ptr += len;
675
676 if (ibs->rx_count)
677 continue;
678
679 switch (ibs->rx_state) {
680 case HCI_IBS_W4_DATA:
681 BT_DBG("Complete data");
682 hci_recv_frame(ibs->rx_skb);
683
684 ibs->rx_state = HCI_IBS_W4_PACKET_TYPE;
685 ibs->rx_skb = NULL;
686 continue;
687
688 case HCI_IBS_W4_EVENT_HDR:
689 eh = (struct hci_event_hdr *) ibs->rx_skb->data;
690
691 BT_DBG("Event header: evt 0x%2.2x plen %d",
692 eh->evt, eh->plen);
693
694 ibs_check_data_len(ibs, eh->plen);
695 continue;
696
697 case HCI_IBS_W4_ACL_HDR:
698 ah = (struct hci_acl_hdr *) ibs->rx_skb->data;
699 dlen = __le16_to_cpu(ah->dlen);
700
701 BT_DBG("ACL header: dlen %d", dlen);
702
703 ibs_check_data_len(ibs, dlen);
704 continue;
705
706 case HCI_IBS_W4_SCO_HDR:
707 sh = (struct hci_sco_hdr *) ibs->rx_skb->data;
708
709 BT_DBG("SCO header: dlen %d", sh->dlen);
710
711 ibs_check_data_len(ibs, sh->dlen);
712 continue;
713 }
714 }
715
716 /* HCI_IBS_W4_PACKET_TYPE */
717 switch (*ptr) {
718 case HCI_EVENT_PKT:
719 BT_DBG("Event packet");
720 ibs->rx_state = HCI_IBS_W4_EVENT_HDR;
721 ibs->rx_count = HCI_EVENT_HDR_SIZE;
722 type = HCI_EVENT_PKT;
723 break;
724
725 case HCI_ACLDATA_PKT:
726 BT_DBG("ACL packet");
727 ibs->rx_state = HCI_IBS_W4_ACL_HDR;
728 ibs->rx_count = HCI_ACL_HDR_SIZE;
729 type = HCI_ACLDATA_PKT;
730 break;
731
732 case HCI_SCODATA_PKT:
733 BT_DBG("SCO packet");
734 ibs->rx_state = HCI_IBS_W4_SCO_HDR;
735 ibs->rx_count = HCI_SCO_HDR_SIZE;
736 type = HCI_SCODATA_PKT;
737 break;
738
739 /* HCI_IBS signals */
740 case HCI_IBS_SLEEP_IND:
741 BT_DBG("HCI_IBS_SLEEP_IND packet");
742 ibs_device_want_to_sleep(hu);
743 ptr++; count--;
744 continue;
745
746 case HCI_IBS_WAKE_IND:
747 BT_DBG("HCI_IBS_WAKE_IND packet");
748 ibs_device_want_to_wakeup(hu);
749 ptr++; count--;
750 continue;
751
752 case HCI_IBS_WAKE_ACK:
753 BT_DBG("HCI_IBS_WAKE_ACK packet");
754 ibs_device_woke_up(hu);
755 ptr++; count--;
756 continue;
757
758 default:
759 BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
760 hu->hdev->stat.err_rx++;
761 ptr++; count--;
762 continue;
763 };
764
765 ptr++; count--;
766
767 /* Allocate packet */
768 ibs->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
769 if (!ibs->rx_skb) {
770 BT_ERR("Can't allocate mem for new packet");
771 ibs->rx_state = HCI_IBS_W4_PACKET_TYPE;
772 ibs->rx_count = 0;
773 return 0;
774 }
775
776 ibs->rx_skb->dev = (void *) hu->hdev;
777 bt_cb(ibs->rx_skb)->pkt_type = type;
778 }
779
780 return count;
781}
782
783static struct sk_buff *ibs_dequeue(struct hci_uart *hu)
784{
785 struct ibs_struct *ibs = hu->priv;
786 return skb_dequeue(&ibs->txq);
787}
788
789static struct hci_uart_proto ibs_p = {
790 .id = HCI_UART_IBS,
791 .open = ibs_open,
792 .close = ibs_close,
793 .recv = ibs_recv,
794 .enqueue = ibs_enqueue,
795 .dequeue = ibs_dequeue,
796 .flush = ibs_flush,
797};
798
799int ibs_init(void)
800{
801 int err = hci_uart_register_proto(&ibs_p);
802
803 if (!err)
804 BT_INFO("HCI_IBS protocol initialized");
805 else
806 BT_ERR("HCI_IBS protocol registration failed");
807
808 return err;
809}
810
811int ibs_deinit(void)
812{
813 return hci_uart_unregister_proto(&ibs_p);
814}
815
816module_param(wake_retrans, ulong, 0644);
817MODULE_PARM_DESC(wake_retrans, "Delay (1/HZ) to retransmit WAKE_IND");
818
819module_param(tx_idle_delay, ulong, 0644);
820MODULE_PARM_DESC(tx_idle_delay, "Delay (1/HZ) since last tx for SLEEP_IND");