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