Lines Matching +full:three +full:- +full:state

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Bluetooth HCI Three-wire UART driver
37 * Maximum Three-wire packet:
38 * 4 byte header + max value for 12-bit length + 2 bytes for CRC
42 /* Convenience macros for reading Three-wire header values */
55 /* H5 state flags */
90 } state; member
128 struct h5 *h5 = hu->priv; in h5_link_control()
139 skb_queue_tail(&h5->unrel, nskb); in h5_link_control()
145 return h5->tx_win & 0x07; in h5_cfg_field()
153 struct hci_uart *hu = h5->hu; in h5_timed_event()
157 BT_DBG("%s", hu->hdev->name); in h5_timed_event()
159 if (h5->state == H5_UNINITIALIZED) in h5_timed_event()
162 if (h5->state == H5_INITIALIZED) { in h5_timed_event()
167 if (h5->state != H5_ACTIVE) { in h5_timed_event()
168 mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); in h5_timed_event()
172 if (h5->sleep != H5_AWAKE) { in h5_timed_event()
173 h5->sleep = H5_SLEEPING; in h5_timed_event()
177 BT_DBG("hu %p retransmitting %u pkts", hu, h5->unack.qlen); in h5_timed_event()
179 spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING); in h5_timed_event()
181 while ((skb = __skb_dequeue_tail(&h5->unack)) != NULL) { in h5_timed_event()
182 h5->tx_seq = (h5->tx_seq - 1) & 0x07; in h5_timed_event()
183 skb_queue_head(&h5->rel, skb); in h5_timed_event()
186 spin_unlock_irqrestore(&h5->unack.lock, flags); in h5_timed_event()
194 struct h5 *h5 = hu->priv; in h5_peer_reset()
196 bt_dev_err(hu->hdev, "Peer device has reset"); in h5_peer_reset()
198 h5->state = H5_UNINITIALIZED; in h5_peer_reset()
200 del_timer(&h5->timer); in h5_peer_reset()
202 skb_queue_purge(&h5->rel); in h5_peer_reset()
203 skb_queue_purge(&h5->unrel); in h5_peer_reset()
204 skb_queue_purge(&h5->unack); in h5_peer_reset()
206 h5->tx_seq = 0; in h5_peer_reset()
207 h5->tx_ack = 0; in h5_peer_reset()
210 hci_reset_dev(hu->hdev); in h5_peer_reset()
220 if (hu->serdev) { in h5_open()
221 h5 = serdev_device_get_drvdata(hu->serdev); in h5_open()
225 return -ENOMEM; in h5_open()
228 hu->priv = h5; in h5_open()
229 h5->hu = hu; in h5_open()
231 skb_queue_head_init(&h5->unack); in h5_open()
232 skb_queue_head_init(&h5->rel); in h5_open()
233 skb_queue_head_init(&h5->unrel); in h5_open()
237 timer_setup(&h5->timer, h5_timed_event, 0); in h5_open()
239 h5->tx_win = H5_TX_WIN_MAX; in h5_open()
241 if (h5->vnd && h5->vnd->open) in h5_open()
242 h5->vnd->open(h5); in h5_open()
244 set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags); in h5_open()
248 mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); in h5_open()
255 struct h5 *h5 = hu->priv; in h5_close()
257 del_timer_sync(&h5->timer); in h5_close()
259 skb_queue_purge(&h5->unack); in h5_close()
260 skb_queue_purge(&h5->rel); in h5_close()
261 skb_queue_purge(&h5->unrel); in h5_close()
263 kfree_skb(h5->rx_skb); in h5_close()
264 h5->rx_skb = NULL; in h5_close()
266 if (h5->vnd && h5->vnd->close) in h5_close()
267 h5->vnd->close(h5); in h5_close()
269 if (!hu->serdev) in h5_close()
277 struct h5 *h5 = hu->priv; in h5_setup()
279 if (h5->vnd && h5->vnd->setup) in h5_setup()
280 return h5->vnd->setup(h5); in h5_setup()
292 spin_lock_irqsave(&h5->unack.lock, flags); in h5_pkt_cull()
294 to_remove = skb_queue_len(&h5->unack); in h5_pkt_cull()
298 seq = h5->tx_seq; in h5_pkt_cull()
301 if (h5->rx_ack == seq) in h5_pkt_cull()
304 to_remove--; in h5_pkt_cull()
305 seq = (seq - 1) & 0x07; in h5_pkt_cull()
308 if (seq != h5->rx_ack) in h5_pkt_cull()
312 skb_queue_walk_safe(&h5->unack, skb, tmp) { in h5_pkt_cull()
316 __skb_unlink(skb, &h5->unack); in h5_pkt_cull()
320 if (skb_queue_empty(&h5->unack)) in h5_pkt_cull()
321 del_timer(&h5->timer); in h5_pkt_cull()
324 spin_unlock_irqrestore(&h5->unack.lock, flags); in h5_pkt_cull()
329 struct h5 *h5 = hu->priv; in h5_handle_internal_rx()
337 const unsigned char *hdr = h5->rx_skb->data; in h5_handle_internal_rx()
338 const unsigned char *data = &h5->rx_skb->data[4]; in h5_handle_internal_rx()
340 BT_DBG("%s", hu->hdev->name); in h5_handle_internal_rx()
351 if (h5->state == H5_ACTIVE) in h5_handle_internal_rx()
355 if (h5->state == H5_ACTIVE) in h5_handle_internal_rx()
357 h5->state = H5_INITIALIZED; in h5_handle_internal_rx()
364 h5->tx_win = (data[2] & 0x07); in h5_handle_internal_rx()
365 BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win); in h5_handle_internal_rx()
366 h5->state = H5_ACTIVE; in h5_handle_internal_rx()
371 h5->sleep = H5_SLEEPING; in h5_handle_internal_rx()
375 h5->sleep = H5_AWAKE; in h5_handle_internal_rx()
379 h5->sleep = H5_AWAKE; in h5_handle_internal_rx()
390 struct h5 *h5 = hu->priv; in h5_complete_rx_pkt()
391 const unsigned char *hdr = h5->rx_skb->data; in h5_complete_rx_pkt()
394 h5->tx_ack = (h5->tx_ack + 1) % 8; in h5_complete_rx_pkt()
395 set_bit(H5_TX_ACK_REQ, &h5->flags); in h5_complete_rx_pkt()
399 h5->rx_ack = H5_HDR_ACK(hdr); in h5_complete_rx_pkt()
408 hci_skb_pkt_type(h5->rx_skb) = H5_HDR_PKT_TYPE(hdr); in h5_complete_rx_pkt()
410 /* Remove Three-wire header */ in h5_complete_rx_pkt()
411 skb_pull(h5->rx_skb, 4); in h5_complete_rx_pkt()
413 hci_recv_frame(hu->hdev, h5->rx_skb); in h5_complete_rx_pkt()
414 h5->rx_skb = NULL; in h5_complete_rx_pkt()
435 struct h5 *h5 = hu->priv; in h5_rx_payload()
436 const unsigned char *hdr = h5->rx_skb->data; in h5_rx_payload()
439 h5->rx_func = h5_rx_crc; in h5_rx_payload()
440 h5->rx_pending = 2; in h5_rx_payload()
450 struct h5 *h5 = hu->priv; in h5_rx_3wire_hdr()
451 const unsigned char *hdr = h5->rx_skb->data; in h5_rx_3wire_hdr()
454 hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr), in h5_rx_3wire_hdr()
459 bt_dev_err(hu->hdev, "Invalid header checksum"); in h5_rx_3wire_hdr()
464 if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5->tx_ack) { in h5_rx_3wire_hdr()
465 bt_dev_err(hu->hdev, "Out-of-order packet arrived (%u != %u)", in h5_rx_3wire_hdr()
466 H5_HDR_SEQ(hdr), h5->tx_ack); in h5_rx_3wire_hdr()
467 set_bit(H5_TX_ACK_REQ, &h5->flags); in h5_rx_3wire_hdr()
473 if (h5->state != H5_ACTIVE && in h5_rx_3wire_hdr()
475 bt_dev_err(hu->hdev, "Non-link packet received in non-active state"); in h5_rx_3wire_hdr()
480 h5->rx_func = h5_rx_payload; in h5_rx_3wire_hdr()
481 h5->rx_pending = H5_HDR_LEN(hdr); in h5_rx_3wire_hdr()
488 struct h5 *h5 = hu->priv; in h5_rx_pkt_start()
493 h5->rx_func = h5_rx_3wire_hdr; in h5_rx_pkt_start()
494 h5->rx_pending = 4; in h5_rx_pkt_start()
496 h5->rx_skb = bt_skb_alloc(H5_MAX_LEN, GFP_ATOMIC); in h5_rx_pkt_start()
497 if (!h5->rx_skb) { in h5_rx_pkt_start()
498 bt_dev_err(hu->hdev, "Can't allocate mem for new packet"); in h5_rx_pkt_start()
500 return -ENOMEM; in h5_rx_pkt_start()
503 h5->rx_skb->dev = (void *)hu->hdev; in h5_rx_pkt_start()
510 struct h5 *h5 = hu->priv; in h5_rx_delimiter()
513 h5->rx_func = h5_rx_pkt_start; in h5_rx_delimiter()
523 if (!test_bit(H5_RX_ESC, &h5->flags) && c == SLIP_ESC) { in h5_unslip_one_byte()
524 set_bit(H5_RX_ESC, &h5->flags); in h5_unslip_one_byte()
528 if (test_and_clear_bit(H5_RX_ESC, &h5->flags)) { in h5_unslip_one_byte()
543 skb_put_data(h5->rx_skb, byte, 1); in h5_unslip_one_byte()
544 h5->rx_pending--; in h5_unslip_one_byte()
546 BT_DBG("unslipped 0x%02hhx, rx_pending %zu", *byte, h5->rx_pending); in h5_unslip_one_byte()
551 if (h5->rx_skb) { in h5_reset_rx()
552 kfree_skb(h5->rx_skb); in h5_reset_rx()
553 h5->rx_skb = NULL; in h5_reset_rx()
556 h5->rx_func = h5_rx_delimiter; in h5_reset_rx()
557 h5->rx_pending = 0; in h5_reset_rx()
558 clear_bit(H5_RX_ESC, &h5->flags); in h5_reset_rx()
563 struct h5 *h5 = hu->priv; in h5_recv()
566 BT_DBG("%s pending %zu count %d", hu->hdev->name, h5->rx_pending, in h5_recv()
572 if (h5->rx_pending > 0) { in h5_recv()
574 bt_dev_err(hu->hdev, "Too short H5 packet"); in h5_recv()
581 ptr++; count--; in h5_recv()
585 processed = h5->rx_func(hu, *ptr); in h5_recv()
590 count -= processed; in h5_recv()
593 if (hu->serdev) { in h5_recv()
594 pm_runtime_get(&hu->serdev->dev); in h5_recv()
595 pm_runtime_mark_last_busy(&hu->serdev->dev); in h5_recv()
596 pm_runtime_put_autosuspend(&hu->serdev->dev); in h5_recv()
604 struct h5 *h5 = hu->priv; in h5_enqueue()
606 if (skb->len > 0xfff) { in h5_enqueue()
607 bt_dev_err(hu->hdev, "Packet too long (%u bytes)", skb->len); in h5_enqueue()
612 if (h5->state != H5_ACTIVE) { in h5_enqueue()
613 bt_dev_err(hu->hdev, "Ignoring HCI data in non-active state"); in h5_enqueue()
621 skb_queue_tail(&h5->rel, skb); in h5_enqueue()
626 skb_queue_tail(&h5->unrel, skb); in h5_enqueue()
630 bt_dev_err(hu->hdev, "Unknown packet type %u", hci_skb_pkt_type(skb)); in h5_enqueue()
635 if (hu->serdev) { in h5_enqueue()
636 pm_runtime_get_sync(&hu->serdev->dev); in h5_enqueue()
637 pm_runtime_mark_last_busy(&hu->serdev->dev); in h5_enqueue()
638 pm_runtime_put_autosuspend(&hu->serdev->dev); in h5_enqueue()
686 struct h5 *h5 = hu->priv; in h5_prepare_pkt()
692 bt_dev_err(hu->hdev, "Unknown packet type %u", pkt_type); in h5_prepare_pkt()
710 hdr[0] = h5->tx_ack << 3; in h5_prepare_pkt()
711 clear_bit(H5_TX_ACK_REQ, &h5->flags); in h5_prepare_pkt()
716 hdr[0] |= h5->tx_seq; in h5_prepare_pkt()
717 h5->tx_seq = (h5->tx_seq + 1) % 8; in h5_prepare_pkt()
725 hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr), in h5_prepare_pkt()
742 struct h5 *h5 = hu->priv; in h5_dequeue()
746 if (h5->sleep != H5_AWAKE) { in h5_dequeue()
749 if (h5->sleep == H5_WAKING_UP) in h5_dequeue()
752 h5->sleep = H5_WAKING_UP; in h5_dequeue()
755 mod_timer(&h5->timer, jiffies + HZ / 100); in h5_dequeue()
759 skb = skb_dequeue(&h5->unrel); in h5_dequeue()
762 skb->data, skb->len); in h5_dequeue()
768 skb_queue_head(&h5->unrel, skb); in h5_dequeue()
769 bt_dev_err(hu->hdev, "Could not dequeue pkt because alloc_skb failed"); in h5_dequeue()
772 spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING); in h5_dequeue()
774 if (h5->unack.qlen >= h5->tx_win) in h5_dequeue()
777 skb = skb_dequeue(&h5->rel); in h5_dequeue()
780 skb->data, skb->len); in h5_dequeue()
782 __skb_queue_tail(&h5->unack, skb); in h5_dequeue()
783 mod_timer(&h5->timer, jiffies + H5_ACK_TIMEOUT); in h5_dequeue()
784 spin_unlock_irqrestore(&h5->unack.lock, flags); in h5_dequeue()
788 skb_queue_head(&h5->rel, skb); in h5_dequeue()
789 bt_dev_err(hu->hdev, "Could not dequeue pkt because alloc_skb failed"); in h5_dequeue()
793 spin_unlock_irqrestore(&h5->unack.lock, flags); in h5_dequeue()
795 if (test_bit(H5_TX_ACK_REQ, &h5->flags)) in h5_dequeue()
809 .name = "Three-wire (H5)",
821 struct device *dev = &serdev->dev; in h5_serdev_probe()
827 return -ENOMEM; in h5_serdev_probe()
829 h5->hu = &h5->serdev_hu; in h5_serdev_probe()
830 h5->serdev_hu.serdev = serdev; in h5_serdev_probe()
836 match = acpi_match_device(dev->driver->acpi_match_table, dev); in h5_serdev_probe()
838 return -ENODEV; in h5_serdev_probe()
840 data = (const struct h5_device_data *)match->driver_data; in h5_serdev_probe()
841 h5->vnd = data->vnd; in h5_serdev_probe()
842 h5->id = (char *)match->id; in h5_serdev_probe()
844 if (h5->vnd->acpi_gpio_map) in h5_serdev_probe()
846 h5->vnd->acpi_gpio_map); in h5_serdev_probe()
850 return -ENODEV; in h5_serdev_probe()
852 h5->vnd = data->vnd; in h5_serdev_probe()
855 if (data->driver_info & H5_INFO_WAKEUP_DISABLE) in h5_serdev_probe()
856 set_bit(H5_WAKEUP_DISABLE, &h5->flags); in h5_serdev_probe()
858 h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); in h5_serdev_probe()
859 if (IS_ERR(h5->enable_gpio)) in h5_serdev_probe()
860 return PTR_ERR(h5->enable_gpio); in h5_serdev_probe()
862 h5->device_wake_gpio = devm_gpiod_get_optional(dev, "device-wake", in h5_serdev_probe()
864 if (IS_ERR(h5->device_wake_gpio)) in h5_serdev_probe()
865 return PTR_ERR(h5->device_wake_gpio); in h5_serdev_probe()
867 return hci_uart_register_device_priv(&h5->serdev_hu, &h5p, in h5_serdev_probe()
868 h5->vnd->sizeof_priv); in h5_serdev_probe()
875 hci_uart_unregister_device(&h5->serdev_hu); in h5_serdev_remove()
883 if (h5->vnd && h5->vnd->suspend) in h5_serdev_suspend()
884 ret = h5->vnd->suspend(h5); in h5_serdev_suspend()
894 if (h5->vnd && h5->vnd->resume) in h5_serdev_resume()
895 ret = h5->vnd->resume(h5); in h5_serdev_resume()
911 btrtl_dev = btrtl_initialize(h5->hu->hdev, h5->id); in h5_btrtl_setup()
915 err = btrtl_get_uart_settings(h5->hu->hdev, btrtl_dev, in h5_btrtl_setup()
922 skb = __hci_cmd_sync(h5->hu->hdev, 0xfc17, sizeof(baudrate_data), in h5_btrtl_setup()
925 rtl_dev_err(h5->hu->hdev, "set baud rate command failed\n"); in h5_btrtl_setup()
934 serdev_device_set_baudrate(h5->hu->serdev, controller_baudrate); in h5_btrtl_setup()
935 serdev_device_set_flow_control(h5->hu->serdev, flow_control); in h5_btrtl_setup()
938 set_bit(H5_HW_FLOW_CONTROL, &h5->flags); in h5_btrtl_setup()
940 err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev); in h5_btrtl_setup()
941 /* Give the device some time before the hci-core sends it a reset */ in h5_btrtl_setup()
946 btrtl_set_quirks(h5->hu->hdev, btrtl_dev); in h5_btrtl_setup()
961 if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) in h5_btrtl_open()
962 set_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &h5->hu->flags); in h5_btrtl_open()
965 serdev_device_set_flow_control(h5->hu->serdev, false); in h5_btrtl_open()
966 serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN); in h5_btrtl_open()
967 serdev_device_set_baudrate(h5->hu->serdev, 115200); in h5_btrtl_open()
969 if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) { in h5_btrtl_open()
970 pm_runtime_set_active(&h5->hu->serdev->dev); in h5_btrtl_open()
971 pm_runtime_use_autosuspend(&h5->hu->serdev->dev); in h5_btrtl_open()
972 pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev, in h5_btrtl_open()
974 pm_runtime_enable(&h5->hu->serdev->dev); in h5_btrtl_open()
978 gpiod_set_value_cansleep(h5->enable_gpio, 0); in h5_btrtl_open()
979 gpiod_set_value_cansleep(h5->device_wake_gpio, 0); in h5_btrtl_open()
983 gpiod_set_value_cansleep(h5->enable_gpio, 1); in h5_btrtl_open()
984 gpiod_set_value_cansleep(h5->device_wake_gpio, 1); in h5_btrtl_open()
990 if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) in h5_btrtl_close()
991 pm_runtime_disable(&h5->hu->serdev->dev); in h5_btrtl_close()
993 gpiod_set_value_cansleep(h5->device_wake_gpio, 0); in h5_btrtl_close()
994 gpiod_set_value_cansleep(h5->enable_gpio, 0); in h5_btrtl_close()
998 * suspend/resume, causing it to lose its firmware and all state. So we simply
1005 serdev_device_set_flow_control(h5->hu->serdev, false); in h5_btrtl_suspend()
1006 gpiod_set_value_cansleep(h5->device_wake_gpio, 0); in h5_btrtl_suspend()
1008 if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) in h5_btrtl_suspend()
1009 gpiod_set_value_cansleep(h5->enable_gpio, 0); in h5_btrtl_suspend()
1025 ret = device_reprobe(reprobe->dev); in h5_btrtl_reprobe_worker()
1026 if (ret && ret != -EPROBE_DEFER) in h5_btrtl_reprobe_worker()
1027 dev_err(reprobe->dev, "Reprobe error %d\n", ret); in h5_btrtl_reprobe_worker()
1029 put_device(reprobe->dev); in h5_btrtl_reprobe_worker()
1036 if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) { in h5_btrtl_resume()
1041 return -ENOMEM; in h5_btrtl_resume()
1045 INIT_WORK(&reprobe->work, h5_btrtl_reprobe_worker); in h5_btrtl_resume()
1046 reprobe->dev = get_device(&h5->hu->serdev->dev); in h5_btrtl_resume()
1047 queue_work(system_long_wq, &reprobe->work); in h5_btrtl_resume()
1049 gpiod_set_value_cansleep(h5->device_wake_gpio, 1); in h5_btrtl_resume()
1051 if (test_bit(H5_HW_FLOW_CONTROL, &h5->flags)) in h5_btrtl_resume()
1052 serdev_device_set_flow_control(h5->hu->serdev, true); in h5_btrtl_resume()
1062 { "device-wake-gpios", &btrtl_device_wake_gpios, 1 },
1063 { "enable-gpios", &btrtl_enable_gpios, 1 },
1064 { "host-wake-gpios", &btrtl_host_wake_gpios, 1 },
1106 { .compatible = "realtek,rtl8822cs-bt",
1108 { .compatible = "realtek,rtl8723bs-bt",
1110 { .compatible = "realtek,rtl8723cs-bt",
1112 { .compatible = "realtek,rtl8723ds-bt",