コード例 #1
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
static void qca_wq_awake_device(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_awake_device);
	struct hci_uart *hu = qca->hu;
	unsigned long retrans_delay;

	BT_DBG("hu %p wq awake device", hu);

	/* Vote for serial clock */
	serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);

	spin_lock(&qca->hci_ibs_lock);

	/* Send wake indication to device */
	if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
		BT_ERR("Failed to send WAKE to device");

	qca->ibs_sent_wakes++;

	/* Start retransmit timer */
	retrans_delay = msecs_to_jiffies(qca->wake_retrans);
	mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);

	spin_unlock(&qca->hci_ibs_lock);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #2
0
ファイル: hci_ibs.c プロジェクト: 404992361/mi1_kernel
static void ibs_wq_awake_rx(struct work_struct *work)
{
	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
					ws_awake_rx);
	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;
	unsigned long flags;

	BT_DBG(" %p ", hu);

	ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);

	spin_lock_irqsave(&ibs->hci_ibs_lock, flags);

	ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
	/* Always acknowledge device wake up,
	 * sending IBS message doesn't count as TX ON
	 */
	if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
		BT_ERR("cannot acknowledge device wake up");

	ibs->ibs_sent_wacks++; /* debug */

	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);

	/* actually send the packets */
	hci_uart_tx_wakeup(hu);

}
コード例 #3
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	struct qca_data *qca = hu->priv;
	struct sk_buff *skb;
	u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };

	if (baudrate > QCA_BAUDRATE_3000000)
		return -EINVAL;

	cmd[4] = baudrate;

	skb = bt_skb_alloc(sizeof(cmd), GFP_ATOMIC);
	if (!skb) {
		BT_ERR("Failed to allocate memory for baudrate packet");
		return -ENOMEM;
	}

	/* Assign commands to change baudrate and packet type. */
	memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;

	skb_queue_tail(&qca->txq, skb);
	hci_uart_tx_wakeup(hu);

	/* wait 300ms to change new baudrate on controller side
	 * controller will come back after they receive this HCI command
	 * then host can communicate with new baudrate to controller
	 */
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
	set_current_state(TASK_INTERRUPTIBLE);

	return 0;
}
コード例 #4
0
ファイル: hci_ibs.c プロジェクト: 404992361/mi1_kernel
static void hci_ibs_wake_retrans_timeout(unsigned long arg)
{
	struct hci_uart *hu = (struct hci_uart *) arg;
	struct ibs_struct *ibs = hu->priv;
	unsigned long flags;
	unsigned long retransmit = 0;

	BT_DBG("hu %p wake retransmit timeout in %lu state",
		hu, ibs->tx_ibs_state);

	spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
					flags, SINGLE_DEPTH_NESTING);

	switch (ibs->tx_ibs_state) {
	default:
	case HCI_IBS_TX_ASLEEP:
	case HCI_IBS_TX_AWAKE:
		BT_ERR("spurrious timeout tx state %ld", ibs->tx_ibs_state);
		goto out;
	case HCI_IBS_TX_WAKING: /* No WAKE_ACK, retransmit WAKE */
		retransmit = 1;
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
			BT_ERR("cannot acknowledge device wake up");
			goto out;
		}
		ibs->ibs_sent_wakes++; /* debug */
		mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
		break;
	}
out:
	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
	if (retransmit)
		hci_uart_tx_wakeup(hu);
}
コード例 #5
0
static void ll_device_want_to_sleep(struct hci_uart *hu)
{
	unsigned long flags;
	struct ll_struct *ll = hu->priv;

	BT_DBG("hu %p", hu);

	
	spin_lock_irqsave(&ll->hcill_lock, flags);

	
	if (ll->hcill_state != HCILL_AWAKE)
		BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);

	
	if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
		BT_ERR("cannot acknowledge device sleep");
		goto out;
	}

	
	ll->hcill_state = HCILL_ASLEEP;

out:
	spin_unlock_irqrestore(&ll->hcill_lock, flags);

	
	hci_uart_tx_wakeup(hu);

	spin_lock_irqsave(&ll->hcill_lock, flags);
	if (ll->hcill_state == HCILL_ASLEEP)
		__ll_msm_serial_clock_request_off(hu->tty);
	spin_unlock_irqrestore(&ll->hcill_lock, flags);
}
コード例 #6
0
ファイル: hci_ll.c プロジェクト: 020gzh/linux
/*
 * Called upon a sleep-indication from the device
 */
static void ll_device_want_to_sleep(struct hci_uart *hu)
{
	unsigned long flags;
	struct ll_struct *ll = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hcill state */
	spin_lock_irqsave(&ll->hcill_lock, flags);

	/* sanity check */
	if (ll->hcill_state != HCILL_AWAKE)
		BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);

	/* acknowledge device sleep */
	if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
		BT_ERR("cannot acknowledge device sleep");
		goto out;
	}

	/* update state */
	ll->hcill_state = HCILL_ASLEEP;

out:
	spin_unlock_irqrestore(&ll->hcill_lock, flags);

	/* actually send the sleep ack packet */
	hci_uart_tx_wakeup(hu);
}
コード例 #7
0
/*
 * Cabrcmed upon a sleep-indication from the device
 */
static void brcm_device_want_to_sleep(struct hci_uart *hu)
{
	unsigned long flags;
	struct brcm_struct *brcm = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hcibrcm state */
	spin_lock_irqsave(&brcm->hcibrcm_lock, flags);

	/* sanity check */
	if (brcm->hcibrcm_state != HCIBRCM_AWAKE)
		BT_ERR("ERR: HCIBRCM_GO_TO_SLEEP_IND in state %ld", brcm->hcibrcm_state);

	/* acknowledge device sleep */
	if (send_hcibrcm_cmd(HCIBRCM_GO_TO_SLEEP_ACK, hu) < 0) {
		BT_ERR("cannot acknowledge device sleep");
		goto out;
	}

	/* update state */
	brcm->hcibrcm_state = HCIBRCM_ASLEEP;

out:
	spin_unlock_irqrestore(&brcm->hcibrcm_lock, flags);

	/* actuabrcmy send the sleep ack packet */
	hci_uart_tx_wakeup(hu);

	spin_lock_irqsave(&brcm->hcibrcm_lock, flags);
	if (brcm->hcibrcm_state == HCIBRCM_ASLEEP)
		__brcm_msm_serial_clock_request_off(hu->tty);
	spin_unlock_irqrestore(&brcm->hcibrcm_lock, flags);
}
コード例 #8
0
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct sk_buff *skb)
{
	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
	struct tty_struct *tty;
	struct hci_uart *hu;

	if (!hdev) {
		BT_ERR("Frame for uknown device (hdev=NULL)");
		return -ENODEV;
	}

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	hu = (struct hci_uart *) hdev->driver_data;
	tty = hu->tty;

	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);

	return 0;
}
コード例 #9
0
int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
#endif
	struct hci_uart *hu;

	if (!hdev) {
		BT_ERR("Frame for unknown device (hdev=NULL)");
		return -ENODEV;
	}

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	hu = GET_DRV_DATA(hdev);	//(struct hci_uart *) hdev->driver_data;

	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
	       skb->len);

#ifdef BTCOEX
	if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT)
		rtk_btcoex_parse_cmd(skb->data, skb->len);
	if (bt_cb(skb)->pkt_type == HCI_ACLDATA_PKT)
		rtk_btcoex_parse_l2cap_data_tx(skb->data, skb->len);
#endif

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);

	return 0;
}
コード例 #10
0
ファイル: hci_ldisc.c プロジェクト: LucidOne/Rovio
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct sk_buff *skb)
{
	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
	cyg_io_handle_t serial;
	struct hci_uart *hu;

	if (!hdev) {
		//BT_ERR
		printf("Frame for uknown device (hdev=NULL)\n");
		return -ENODEV;
	}

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	hu = (struct hci_uart *) hdev->driver_data;
	serial = hu->tty;

	//BT_DBG
	printf("%s: type %d len %d\n", hdev->name, skb->pkt_type, skb->len);

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);
	return 0;
}
コード例 #11
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
static void qca_wq_awake_rx(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_awake_rx);
	struct hci_uart *hu = qca->hu;

	BT_DBG("hu %p wq awake rx", hu);

	serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);

	spin_lock(&qca->hci_ibs_lock);
	qca->rx_ibs_state = HCI_IBS_RX_AWAKE;

	/* Always acknowledge device wake up,
	 * sending IBS message doesn't count as TX ON.
	 */
	if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
		BT_ERR("Failed to acknowledge device wake up");

	qca->ibs_sent_wacks++;

	spin_unlock(&qca->hci_ibs_lock);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #12
0
ファイル: hci_ldisc.c プロジェクト: 020gzh/linux
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb),
	       skb->len);

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);

	return 0;
}
コード例 #13
0
/*
 * Cabrcmed upon a wake-up-indication from the device
 */
static void brcm_device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long flags;
	struct brcm_struct *brcm = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hcibrcm state */
	spin_lock_irqsave(&brcm->hcibrcm_lock, flags);

	switch (brcm->hcibrcm_state) {
	case HCIBRCM_ASLEEP_TO_AWAKE:
		/*
		 * This state means that both the host and the BRF chip
		 * have simultaneously sent a wake-up-indication packet.
		 * Traditionaly, in this case, receiving a wake-up-indication
		 * was enough and an additional wake-up-ack wasn't needed.
		 * This has changed with the BRF6350, which does require an
		 * explicit wake-up-ack. Other BRF versions, which do not
		 * require an explicit ack here, do accept it, thus it is
		 * perfectly safe to always send one.
		 */
		BT_DBG("dual wake-up-indication");
		/* deliberate fabrcm-through - do not add break */
	case HCIBRCM_ASLEEP:
		/* Make sure clock is on - we may have turned clock off since
		 * receiving the wake up indicator
		 */
		__brcm_bcm_serial_clock_on(hu);
		/* acknowledge device wake up */
		if (send_hcibrcm_cmd(HCIBRCM_WAKE_UP_ACK, hu) < 0) {
			BT_ERR("cannot acknowledge device wake up");
			goto out;
		}
		break;
	default:
		/* any other state is ibrcmegal */
		BT_ERR("received HCIBRCM_WAKE_UP_IND in state %ld",
		       brcm->hcibrcm_state);
		break;
	}

	/* send pending packets and change state to HCIBRCM_AWAKE */
	__brcm_do_awake(brcm);

out:
	spin_unlock_irqrestore(&brcm->hcibrcm_lock, flags);

	/* actuabrcmy send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #14
0
ファイル: hci_serdev.c プロジェクト: EMFPGA/linux_media
/** hci_uart_write_wakeup - transmit buffer wakeup
 * @serdev: serial device
 *
 * This function is called by the serdev framework when it accepts
 * more data being sent.
 */
static void hci_uart_write_wakeup(struct serdev_device *serdev)
{
	struct hci_uart *hu = serdev_device_get_drvdata(serdev);

	BT_DBG("");

	if (!hu || serdev != hu->serdev) {
		WARN_ON(1);
		return;
	}

	if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
		hci_uart_tx_wakeup(hu);
}
コード例 #15
0
/* QualComm baseLine update 1030 to 1040 begin */
static void ibs_wq(struct work_struct *work)
{
	unsigned long flags = 0;
	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
						ws_ibs);
	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;

	BT_DBG("hu %p, ibs_wq state: %lu\n", hu, ibs->ibs_wq_state);

	/* lock hci_ibs state */
	spin_lock_irqsave(&ibs->hci_ibs_lock, flags);

	switch (ibs->ibs_wq_state) {
	case HCI_IBS_WQ_AWAKE_DEVICE:
		/* Vote for serial clock */
		ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);

		/* send wake indication to device */
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
			BT_ERR("cannot send WAKE to device");

		ibs->ibs_sent_wakes++; /* debug */

		/* start retransmit timer */
		mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
		break;
	case HCI_IBS_WQ_AWAKE_RX:
		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
		ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;

		if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
			BT_ERR("cannot acknowledge device wake up");

		ibs->ibs_sent_wacks++; /* debug */
		/* actually send the packets */
		hci_uart_tx_wakeup(hu);
		break;
	case HCI_IBS_WQ_RX_VOTE_OFF:
		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu);
		break;
	case HCI_IBS_WQ_TX_VOTE_OFF:
		ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
		break;
	default:
		BT_DBG("Invalid state in ibs workqueue");
		break;
	}
	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
}
コード例 #16
0
/*
 * Called upon wake-up-acknowledgement from the device
 */
static void ibs_device_woke_up(struct hci_uart *hu)
{
	unsigned long flags;
	struct ibs_struct *ibs = hu->priv;
	struct sk_buff *skb = NULL;

	BT_DBG("hu %p", hu);

	/* lock hci_ibs state */
	spin_lock_irqsave(&ibs->hci_ibs_lock, flags);

	/* debug */
	ibs->ibs_recv_wacks++;

	//Add check for rx_ibs_state when receive HCI_IBS_WAKE_ACK just after HCI_IBS_SLEEP_IND. 
	if(ibs->rx_ibs_state == HCI_IBS_RX_ASLEEP) {
		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
		ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
	}

	switch (ibs->tx_ibs_state) {
	case HCI_IBS_TX_ASLEEP:
		/* This could be spurrious rx wake on the BT chip.
		 * Send it another SLEEP othwise it will stay awake. */
	default:
		BT_ERR("received HCI_IBS_WAKE_ACK in tx state %ld",
			ibs->tx_ibs_state);
		break;
	case HCI_IBS_TX_AWAKE:
		/* expect one if we send 2 WAKEs */
		BT_DBG("received HCI_IBS_WAKE_ACK in tx state %ld",
			ibs->tx_ibs_state);
		break;
	case HCI_IBS_TX_WAKING:
		/* send pending packets */
		while ((skb = skb_dequeue(&ibs->tx_wait_q)))
			skb_queue_tail(&ibs->txq, skb);
		/* switch timers and change state to HCI_IBS_TX_AWAKE */
		del_timer(&ibs->wake_retrans_timer);
		mod_timer(&ibs->tx_idle_timer, jiffies + tx_idle_delay);
		ibs->tx_ibs_state = HCI_IBS_TX_AWAKE;
	}


	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);

	/* actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #17
0
ファイル: hci_ldisc.c プロジェクト: 24hours/linux
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);

	return 0;
}
コード例 #18
0
ファイル: hci_ibs.c プロジェクト: 404992361/mi1_kernel
static void ibs_wq_serial_tx_clock_vote_off(struct work_struct *work)
{
	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
					ws_tx_vote_off);
	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;

	BT_DBG(" %p ", hu);

	hci_uart_tx_wakeup(hu);  /* run HCI tx handling unlocked */

	/* now that message queued to tty driver, vote for tty clocks off */
	/* It is up to the tty driver to pend the clocks off until tx done. */
	ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);

}
コード例 #19
0
/*
 * Called upon a wake-up-indication from the device
 */
static void ibs_device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long flags;
	struct ibs_struct *ibs = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hci_ibs state */
	spin_lock_irqsave(&ibs->hci_ibs_lock, flags);

	/* debug */
	ibs->ibs_recv_wakes++;

	switch (ibs->rx_ibs_state) {
	case HCI_IBS_RX_ASLEEP:
		/* Make sure clock is on - we may have turned clock off since
		 * receiving the wake up indicator
		 */
		/* QualComm baseLine update 1030 to 1040 begin */
		/* awake rx clock */
		ibs->ibs_wq_state = HCI_IBS_WQ_AWAKE_RX;
		queue_work(ibs->workqueue, &ibs->ws_ibs);
		spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
		return;
		/* QualComm baseLine update 1030 to 1040 end */
	case HCI_IBS_RX_AWAKE:
		/* Always acknowledge device wake up,
		 * sending IBS message doesn't count as TX ON.
		 */
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0) {
			BT_ERR("cannot acknowledge device wake up");
			goto out;
		}
		ibs->ibs_sent_wacks++; /* debug */
		break;
	default:
		/* any other state is illegal */
		BT_ERR("received HCI_IBS_WAKE_IND in rx state %ld",
			ibs->rx_ibs_state);
		break;
	}

out:
	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);

	/* actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #20
0
static void hci_ibs_tx_idle_timeout(unsigned long arg)
{
	struct hci_uart *hu = (struct hci_uart *) arg;
	struct ibs_struct *ibs = hu->priv;
	unsigned long flags;
	unsigned long vote_tx_sleep = 0;

	BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state);

	spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
					flags, SINGLE_DEPTH_NESTING);

	switch (ibs->tx_ibs_state) {
	default:
	case HCI_IBS_TX_ASLEEP:
	case HCI_IBS_TX_WAKING:
		BT_ERR("spurrious timeout in tx state %ld", ibs->tx_ibs_state);
		goto out;
	case HCI_IBS_TX_AWAKE: /* TX_IDLE, go to SLEEP */
		if (send_hci_ibs_cmd(HCI_IBS_SLEEP_IND, hu) < 0) {
			BT_ERR("cannot send SLEEP to device");
			goto out;
		}
		ibs->tx_ibs_state = HCI_IBS_TX_ASLEEP;
		ibs->ibs_sent_slps++; /* debug */
		vote_tx_sleep = 1;
		break;
	}

	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);

	hci_uart_tx_wakeup(hu);  /* run HCI tx handling unlocked */

	if (!vote_tx_sleep)
		return;
	/* now that message queued to tty driver, vote for tty clocks off */
	/* It is up to the tty driver to pend the clocks off until tx done. */

	spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
					flags, SINGLE_DEPTH_NESTING);
	/* QualComm baseLine update 1030 to 1040 begin */
	/* vote off tx clock */
	ibs->ibs_wq_state = HCI_IBS_WQ_TX_VOTE_OFF;
	queue_work(ibs->workqueue, &ibs->ws_ibs);
	/* QualComm baseLine update 1030 to 1040 end */
out:
	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
}
コード例 #21
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
static void qca_wq_serial_tx_clock_vote_off(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_tx_vote_off);
	struct hci_uart *hu = qca->hu;

	BT_DBG("hu %p tx clock vote off", hu);

	/* Run HCI tx handling unlocked */
	hci_uart_tx_wakeup(hu);

	/* Now that message queued to tty driver, vote for tty clocks off.
	 * It is up to the tty driver to pend the clocks off until tx done.
	 */
	serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
}
コード例 #22
0
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb),
	       skb->len);

	if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
		return -EUNATCH;

	hu->proto->enqueue(hu, skb);

	hci_uart_tx_wakeup(hu);

	return 0;
}
コード例 #23
0
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct sk_buff *skb)
{
    struct hci_dev* hdev = (struct hci_dev *) skb->dev;
    struct hci_uart *hu;
#ifdef CONFIG_TROUT_UART_TRANSPORT_DEBUG
    struct h4_struct *h4;
    int is_queue_empty = 0;
#endif

    if (!hdev) {
        BT_ERR("Frame for unknown device (hdev=NULL)");
        return -ENODEV;
    }

    if (!test_bit(HCI_RUNNING, &hdev->flags))
        return -EBUSY;

    hu = (struct hci_uart *) hdev->driver_data;
#ifdef CONFIG_TROUT_UART_TRANSPORT_DEBUG
    h4 = hu->priv;
#endif
    BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);

#ifdef CONFIG_TROUT_UART_TRANSPORT_DEBUG
    BT_UART_DBG("sk_data1:type 0x%x len =%d            data:0x%x 0x%x 0x%x",bt_cb(skb)->pkt_type, skb->len,skb->data[0], skb->data[1], skb->data[2]);
    hu->proto->enqueue(hu, skb);
    if(!hci_is_ctl_act())
    {
        is_queue_empty = is_skb_queue_empty(&h4->txq);
        hci_uart_tx_wakeup_sprd(hu, is_queue_empty, false, false);
    }
    else
    {
        if(NULL != &timer_retransmit)
        {
            del_timer(&timer_retransmit);
        }
        hci_uart_tx_wakeup_sprd(hu, 0, true, false);
    }
#else
    hu->proto->enqueue(hu, skb);
#endif
#ifndef CONFIG_TROUT_UART_TRANSPORT_DEBUG
    hci_uart_tx_wakeup(hu);
#endif
    return 0;
}
コード例 #24
0
/*
 * Called upon a wake-up-indication from the device
 */
static void ibs_device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long flags;
	struct ibs_struct *ibs = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hci_ibs state */
	spin_lock_irqsave(&ibs->hci_ibs_lock, flags);

	/* debug */
	ibs->ibs_recv_wakes++;

	switch (ibs->rx_ibs_state) {
	case HCI_IBS_RX_ASLEEP:
		/* Make sure clock is on - we may have turned clock off since
		 * receiving the wake up indicator
		 */
		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
		ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
		/* deliberate fall-through */

		

	case HCI_IBS_RX_AWAKE:
		/* Always acknowledge device wake up,
		 * sending IBS message doesn't count as TX ON.
		 */
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0) {
			BT_ERR("cannot acknowledge device wake up");
			goto out;
		}
		ibs->ibs_sent_wacks++; /* debug */
		break;
	default:
		/* any other state is illegal */
		BT_ERR("received HCI_IBS_WAKE_IND in rx state %ld",
			ibs->rx_ibs_state);
		break;
	}

out:
	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);

	/* actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #25
0
/* hci_uart_tty_wakeup()
 *
 * Callback for transmit wakeup. Called when low level
 * device driver can accept more send data.
 *
 * Arguments:        tty    pointer to associated tty instance data
 * Return Value:    None
 */
static void hci_uart_tty_wakeup(struct tty_struct *tty)
{
	struct hci_uart *hu = (void *)tty->disc_data;

	BT_DBG("");

	if (!hu)
		return;

	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	if (tty != hu->tty)
		return;

	if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
		hci_uart_tx_wakeup(hu);
}
コード例 #26
0
ファイル: hci_ldisc.c プロジェクト: LucidOne/Rovio
/* hci_uart_tty_wakeup()
 *
 *    Callback for transmit wakeup. Called when low level
 *    device driver can accept more send data.
 *
 * Arguments:        tty    pointer to associated tty instance data
 * Return Value:    None
 */
static void hci_uart_tty_wakeup(cyg_io_handle_t tty)
{
	struct hci_uart *hu = (struct hci_uart *)serial_getdisc(tty);//(void *)tty->disc_data;

//	BT_DBG("");

	if (!hu)
		return;

//	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	if (tty != hu->tty)
		return;

	if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
		hci_uart_tx_wakeup(hu);
}
コード例 #27
0
static void ath_hci_uart_work(struct work_struct *work)
{
    int status;
    struct ath_struct *ath;
    struct hci_uart *hu;

    ath = container_of(work, struct ath_struct, ctxtsw);

    hu = ath->hu;

    /* verify and wake up controller */
    if (test_bit(BT_SLEEPENABLE, &flags))
        status = ath_wakeup_ar3k();
    /* Ready to send Data */
    clear_bit(HCI_UART_SENDING, &hu->tx_state);
    hci_uart_tx_wakeup(hu);
}
コード例 #28
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
/* Called upon wake-up-acknowledgement from the device
 */
static void device_woke_up(struct hci_uart *hu)
{
	unsigned long flags, idle_delay;
	struct qca_data *qca = hu->priv;
	struct sk_buff *skb = NULL;

	BT_DBG("hu %p woke up", hu);

	spin_lock_irqsave(&qca->hci_ibs_lock, flags);

	qca->ibs_recv_wacks++;

	switch (qca->tx_ibs_state) {
	case HCI_IBS_TX_AWAKE:
		/* Expect one if we send 2 WAKEs */
		BT_DBG("Received HCI_IBS_WAKE_ACK in tx state %d",
		       qca->tx_ibs_state);
		break;

	case HCI_IBS_TX_WAKING:
		/* Send pending packets */
		while ((skb = skb_dequeue(&qca->tx_wait_q)))
			skb_queue_tail(&qca->txq, skb);

		/* Switch timers and change state to HCI_IBS_TX_AWAKE */
		del_timer(&qca->wake_retrans_timer);
		idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
		mod_timer(&qca->tx_idle_timer, jiffies + idle_delay);
		qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
		break;

	case HCI_IBS_TX_ASLEEP:
		/* Fall through */

	default:
		BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
		       qca->tx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}
コード例 #29
0
ファイル: hci_qca.c プロジェクト: Anjali05/linux
static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	struct qca_data *qca = hu->priv;
	struct qca_serdev *qcadev;
	struct sk_buff *skb;
	u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };

	if (baudrate > QCA_BAUDRATE_3200000)
		return -EINVAL;

	cmd[4] = baudrate;

	skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
	if (!skb) {
		bt_dev_err(hdev, "Failed to allocate baudrate packet");
		return -ENOMEM;
	}

	/* Assign commands to change baudrate and packet type. */
	skb_put_data(skb, cmd, sizeof(cmd));
	hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;

	skb_queue_tail(&qca->txq, skb);
	hci_uart_tx_wakeup(hu);

	qcadev = serdev_device_get_drvdata(hu->serdev);

	/* Wait for the baudrate change request to be sent */

	while (!skb_queue_empty(&qca->txq))
		usleep_range(100, 200);

	serdev_device_wait_until_sent(hu->serdev,
		      msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));

	/* Give the controller time to process the request */
	if (qcadev->btsoc_type == QCA_WCN3990)
		msleep(10);
	else
		msleep(300);

	return 0;
}
コード例 #30
0
ファイル: hci_qca.c プロジェクト: hellocccat/ath
/* Called upon a wake-up-indication from the device.
 */
static void device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long flags;
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p want to wake up", hu);

	spin_lock_irqsave(&qca->hci_ibs_lock, flags);

	qca->ibs_recv_wakes++;

	switch (qca->rx_ibs_state) {
	case HCI_IBS_RX_ASLEEP:
		/* Make sure clock is on - we may have turned clock off since
		 * receiving the wake up indicator awake rx clock.
		 */
		queue_work(qca->workqueue, &qca->ws_awake_rx);
		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
		return;

	case HCI_IBS_RX_AWAKE:
		/* Always acknowledge device wake up,
		 * sending IBS message doesn't count as TX ON.
		 */
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0) {
			BT_ERR("Failed to acknowledge device wake up");
			break;
		}
		qca->ibs_sent_wacks++;
		break;

	default:
		/* Any other state is illegal */
		BT_ERR("Received HCI_IBS_WAKE_IND in rx state %d",
		       qca->rx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}