Lines Matching +full:taurus +full:- +full:bf +full:- +full:cal +full:- +full:blob

1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
11 #include <linux/dma-mapping.h>
256 * - virtual: set if there is no associated shared memory and only the
258 * - sync: only set for the SCO rings
404 * payload_size: optional in-place payload size
405 * mapped_payload_size: optional out-of-place payload size
411 * setup a corresponding completion ring for device->host messages
413 * buffers used by device->host messages in the completion
483 * Chip-specific configuration struct
495 * vendor-specific subsystem control
544 * hw: Pointer to chip-specific struct bcm4377_hw
545 * taurus_cal_blob: "Taurus" calibration blob used for some chips
546 * taurus_cal_size: "Taurus" calibration blob size
547 * taurus_beamforming_cal_blob: "Taurus" beamforming calibration blob used for
549 * taurus_beamforming_cal_size: "Taurus" beamforming calibration blob size
559 * {hci_acl,sco}_event_ring: Completion rings used for device->host messages
622 dev_dbg(&bcm4377->pdev->dev, "write %d to doorbell #%d (0x%x)\n", val, in bcm4377_ring_doorbell()
624 iowrite32(db, bcm4377->bar0 + BCM4377_BAR0_DOORBELL); in bcm4377_ring_doorbell()
634 if (generation != ring->generation) { in bcm4377_extract_msgid()
636 &bcm4377->pdev->dev, in bcm4377_extract_msgid()
638 generation, ring->generation, ring->ring_id); in bcm4377_extract_msgid()
639 return -EINVAL; in bcm4377_extract_msgid()
642 if (*msgid >= ring->n_entries) { in bcm4377_extract_msgid()
643 dev_warn(&bcm4377->pdev->dev, in bcm4377_extract_msgid()
645 ring->ring_id, *msgid, ring->n_entries); in bcm4377_extract_msgid()
646 return -EINVAL; in bcm4377_extract_msgid()
662 spin_lock_irqsave(&ring->lock, flags); in bcm4377_handle_event()
663 if (!ring->enabled) { in bcm4377_handle_event()
664 dev_warn(&bcm4377->pdev->dev, in bcm4377_handle_event()
666 ring->ring_id); in bcm4377_handle_event()
670 if (ring->d2h_buffers_only && in bcm4377_handle_event()
675 if (len > ring->mapped_payload_size) { in bcm4377_handle_event()
677 &bcm4377->pdev->dev, in bcm4377_handle_event()
679 ring->ring_id, len, ring->mapped_payload_size); in bcm4377_handle_event()
683 payload = ring->payloads + msgid * ring->mapped_payload_size; in bcm4377_handle_event()
692 hci_recv_frame(bcm4377->hdev, skb); in bcm4377_handle_event()
695 head = le16_to_cpu(bcm4377->ring_state->xfer_ring_head[ring->ring_id]); in bcm4377_handle_event()
696 head = (head + 1) % ring->n_entries; in bcm4377_handle_event()
697 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = cpu_to_le16(head); in bcm4377_handle_event()
699 bcm4377_ring_doorbell(bcm4377, ring->doorbell, head); in bcm4377_handle_event()
701 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_handle_event()
711 spin_lock_irqsave(&ring->lock, flags); in bcm4377_handle_ack()
716 if (!test_bit(msgid, ring->msgids)) { in bcm4377_handle_ack()
718 &bcm4377->pdev->dev, in bcm4377_handle_ack()
720 ring->ring_id, msgid); in bcm4377_handle_ack()
724 if (ring->allow_wait && ring->events[msgid]) { in bcm4377_handle_ack()
725 complete(ring->events[msgid]); in bcm4377_handle_ack()
726 ring->events[msgid] = NULL; in bcm4377_handle_ack()
729 bitmap_release_region(ring->msgids, msgid, 0); in bcm4377_handle_ack()
732 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_handle_ack()
744 if (pos >= ring->n_entries) { in bcm4377_handle_completion()
745 dev_warn(&bcm4377->pdev->dev, in bcm4377_handle_completion()
747 ring->ring_id); in bcm4377_handle_completion()
751 entry_size = sizeof(*entry) + ring->payload_size; in bcm4377_handle_completion()
752 entry = ring->ring + pos * entry_size; in bcm4377_handle_completion()
753 data = ring->ring + pos * entry_size + sizeof(*entry); in bcm4377_handle_completion()
754 data_len = le32_to_cpu(entry->len); in bcm4377_handle_completion()
755 msg_id = le16_to_cpu(entry->msg_id); in bcm4377_handle_completion()
756 transfer_ring = le16_to_cpu(entry->ring_id); in bcm4377_handle_completion()
758 if ((ring->transfer_rings & BIT(transfer_ring)) == 0) { in bcm4377_handle_completion()
760 &bcm4377->pdev->dev, in bcm4377_handle_completion()
762 pos, transfer_ring, ring->ring_id); in bcm4377_handle_completion()
766 dev_dbg(&bcm4377->pdev->dev, in bcm4377_handle_completion()
768 ring->ring_id, transfer_ring, msg_id); in bcm4377_handle_completion()
772 bcm4377_handle_ack(bcm4377, &bcm4377->control_h2d_ring, msg_id); in bcm4377_handle_completion()
775 bcm4377_handle_ack(bcm4377, &bcm4377->hci_h2d_ring, msg_id); in bcm4377_handle_completion()
778 bcm4377_handle_ack(bcm4377, &bcm4377->sco_h2d_ring, msg_id); in bcm4377_handle_completion()
781 bcm4377_handle_ack(bcm4377, &bcm4377->acl_h2d_ring, msg_id); in bcm4377_handle_completion()
785 bcm4377_handle_event(bcm4377, &bcm4377->hci_d2h_ring, msg_id, in bcm4377_handle_completion()
786 entry->flags, HCI_EVENT_PKT, data, in bcm4377_handle_completion()
790 bcm4377_handle_event(bcm4377, &bcm4377->sco_d2h_ring, msg_id, in bcm4377_handle_completion()
791 entry->flags, HCI_SCODATA_PKT, data, in bcm4377_handle_completion()
795 bcm4377_handle_event(bcm4377, &bcm4377->acl_d2h_ring, msg_id, in bcm4377_handle_completion()
796 entry->flags, HCI_ACLDATA_PKT, data, in bcm4377_handle_completion()
802 &bcm4377->pdev->dev, in bcm4377_handle_completion()
804 ring->ring_id, transfer_ring, msg_id); in bcm4377_handle_completion()
812 __le16 *heads = bcm4377->ring_state->completion_ring_head; in bcm4377_poll_completion_ring()
813 __le16 *tails = bcm4377->ring_state->completion_ring_tail; in bcm4377_poll_completion_ring()
815 if (!ring->enabled) in bcm4377_poll_completion_ring()
818 tail = le16_to_cpu(tails[ring->ring_id]); in bcm4377_poll_completion_ring()
819 dev_dbg(&bcm4377->pdev->dev, in bcm4377_poll_completion_ring()
820 "completion ring #%d: head: %d, tail: %d\n", ring->ring_id, in bcm4377_poll_completion_ring()
821 le16_to_cpu(heads[ring->ring_id]), tail); in bcm4377_poll_completion_ring()
823 while (tail != le16_to_cpu(READ_ONCE(heads[ring->ring_id]))) { in bcm4377_poll_completion_ring()
833 tail = (tail + 1) % ring->n_entries; in bcm4377_poll_completion_ring()
834 tails[ring->ring_id] = cpu_to_le16(tail); in bcm4377_poll_completion_ring()
843 bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE); in bcm4377_irq()
844 rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS); in bcm4377_irq()
846 if (bootstage != bcm4377->bootstage || in bcm4377_irq()
847 rti_status != bcm4377->rti_status) { in bcm4377_irq()
848 dev_dbg(&bcm4377->pdev->dev, in bcm4377_irq()
849 "bootstage = %d -> %d, rti state = %d -> %d\n", in bcm4377_irq()
850 bcm4377->bootstage, bootstage, bcm4377->rti_status, in bcm4377_irq()
852 complete(&bcm4377->event); in bcm4377_irq()
853 bcm4377->bootstage = bootstage; in bcm4377_irq()
854 bcm4377->rti_status = rti_status; in bcm4377_irq()
858 dev_err(&bcm4377->pdev->dev, "RTI status is %d\n", rti_status); in bcm4377_irq()
860 bcm4377_poll_completion_ring(bcm4377, &bcm4377->control_ack_ring); in bcm4377_irq()
861 bcm4377_poll_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_irq()
862 bcm4377_poll_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_irq()
863 bcm4377_poll_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_irq()
864 bcm4377_poll_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_irq()
882 if (len > ring->payload_size && len > ring->mapped_payload_size) { in bcm4377_enqueue()
884 &bcm4377->pdev->dev, in bcm4377_enqueue()
886 len, ring->ring_id, ring->payload_size, in bcm4377_enqueue()
887 ring->mapped_payload_size); in bcm4377_enqueue()
888 return -EINVAL; in bcm4377_enqueue()
890 if (wait && !ring->allow_wait) in bcm4377_enqueue()
891 return -EINVAL; in bcm4377_enqueue()
892 if (ring->virtual) in bcm4377_enqueue()
893 return -EINVAL; in bcm4377_enqueue()
895 spin_lock_irqsave(&ring->lock, flags); in bcm4377_enqueue()
897 head = le16_to_cpu(bcm4377->ring_state->xfer_ring_head[ring->ring_id]); in bcm4377_enqueue()
898 tail = le16_to_cpu(bcm4377->ring_state->xfer_ring_tail[ring->ring_id]); in bcm4377_enqueue()
900 new_head = (head + 1) % ring->n_entries; in bcm4377_enqueue()
903 dev_warn(&bcm4377->pdev->dev, in bcm4377_enqueue()
905 ring->ring_id); in bcm4377_enqueue()
906 ret = -EINVAL; in bcm4377_enqueue()
910 msgid = bitmap_find_free_region(ring->msgids, ring->n_entries, 0); in bcm4377_enqueue()
912 dev_warn(&bcm4377->pdev->dev, in bcm4377_enqueue()
913 "can't find message id for ring %d\n", ring->ring_id); in bcm4377_enqueue()
914 ret = -EINVAL; in bcm4377_enqueue()
918 raw_msgid = FIELD_PREP(BCM4377_MSGID_GENERATION, ring->generation); in bcm4377_enqueue()
921 offset = head * (sizeof(*entry) + ring->payload_size); in bcm4377_enqueue()
922 entry = ring->ring + offset; in bcm4377_enqueue()
925 entry->id = cpu_to_le16(raw_msgid); in bcm4377_enqueue()
926 entry->len = cpu_to_le16(len); in bcm4377_enqueue()
928 if (len <= ring->payload_size) { in bcm4377_enqueue()
929 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_IN_FOOTER; in bcm4377_enqueue()
930 payload = ring->ring + offset + sizeof(*entry); in bcm4377_enqueue()
932 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_MAPPED; in bcm4377_enqueue()
933 entry->payload = cpu_to_le64(ring->payloads_dma + in bcm4377_enqueue()
934 msgid * ring->mapped_payload_size); in bcm4377_enqueue()
935 payload = ring->payloads + msgid * ring->mapped_payload_size; in bcm4377_enqueue()
941 ring->events[msgid] = &event; in bcm4377_enqueue()
949 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_enqueue()
951 dev_dbg(&bcm4377->pdev->dev, in bcm4377_enqueue()
952 "updating head for transfer queue #%d to %d\n", ring->ring_id, in bcm4377_enqueue()
954 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = in bcm4377_enqueue()
957 if (!ring->sync) in bcm4377_enqueue()
958 bcm4377_ring_doorbell(bcm4377, ring->doorbell, new_head); in bcm4377_enqueue()
962 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_enqueue()
968 ret = -ETIMEDOUT; in bcm4377_enqueue()
972 spin_lock_irqsave(&ring->lock, flags); in bcm4377_enqueue()
973 ring->events[msgid] = NULL; in bcm4377_enqueue()
974 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_enqueue()
986 if (ring->enabled) { in bcm4377_create_completion_ring()
987 dev_warn(&bcm4377->pdev->dev, in bcm4377_create_completion_ring()
988 "completion ring %d already enabled\n", ring->ring_id); in bcm4377_create_completion_ring()
992 memset(ring->ring, 0, in bcm4377_create_completion_ring()
993 ring->n_entries * (sizeof(struct bcm4377_completion_ring_entry) + in bcm4377_create_completion_ring()
994 ring->payload_size)); in bcm4377_create_completion_ring()
997 msg.id = cpu_to_le16(ring->ring_id); in bcm4377_create_completion_ring()
998 msg.id_again = cpu_to_le16(ring->ring_id); in bcm4377_create_completion_ring()
999 msg.ring_iova = cpu_to_le64(ring->ring_dma); in bcm4377_create_completion_ring()
1000 msg.n_elements = cpu_to_le16(ring->n_entries); in bcm4377_create_completion_ring()
1003 msg.intmod_delay = cpu_to_le16(ring->delay); in bcm4377_create_completion_ring()
1004 msg.footer_size = ring->payload_size / 4; in bcm4377_create_completion_ring()
1006 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_create_completion_ring()
1009 ring->enabled = true; in bcm4377_create_completion_ring()
1022 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_destroy_completion_ring()
1024 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_destroy_completion_ring()
1027 dev_warn(&bcm4377->pdev->dev, in bcm4377_destroy_completion_ring()
1029 ring->ring_id); in bcm4377_destroy_completion_ring()
1031 ring->enabled = false; in bcm4377_destroy_completion_ring()
1043 if (ring->virtual) in bcm4377_create_transfer_ring()
1045 if (ring->sync) in bcm4377_create_transfer_ring()
1048 spin_lock_irqsave(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1051 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_create_transfer_ring()
1052 msg.ring_id_again = cpu_to_le16(ring->ring_id); in bcm4377_create_transfer_ring()
1053 msg.ring_iova = cpu_to_le64(ring->ring_dma); in bcm4377_create_transfer_ring()
1054 msg.n_elements = cpu_to_le16(ring->n_entries); in bcm4377_create_transfer_ring()
1055 msg.completion_ring_id = cpu_to_le16(ring->completion_ring); in bcm4377_create_transfer_ring()
1056 msg.doorbell = cpu_to_le16(ring->doorbell); in bcm4377_create_transfer_ring()
1058 msg.footer_size = ring->payload_size / 4; in bcm4377_create_transfer_ring()
1060 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = 0; in bcm4377_create_transfer_ring()
1061 bcm4377->ring_state->xfer_ring_tail[ring->ring_id] = 0; in bcm4377_create_transfer_ring()
1062 ring->generation++; in bcm4377_create_transfer_ring()
1063 spin_unlock_irqrestore(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1065 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_create_transfer_ring()
1068 spin_lock_irqsave(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1070 if (ring->d2h_buffers_only) { in bcm4377_create_transfer_ring()
1071 for (i = 0; i < ring->n_entries; ++i) { in bcm4377_create_transfer_ring()
1073 ring->ring + i * sizeof(*entry); in bcm4377_create_transfer_ring()
1075 ring->generation); in bcm4377_create_transfer_ring()
1079 entry->id = cpu_to_le16(raw_msgid); in bcm4377_create_transfer_ring()
1080 entry->len = cpu_to_le16(ring->mapped_payload_size); in bcm4377_create_transfer_ring()
1081 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_MAPPED; in bcm4377_create_transfer_ring()
1082 entry->payload = in bcm4377_create_transfer_ring()
1083 cpu_to_le64(ring->payloads_dma + in bcm4377_create_transfer_ring()
1084 i * ring->mapped_payload_size); in bcm4377_create_transfer_ring()
1089 * send some messages if this is a device->host ring to allow the device in bcm4377_create_transfer_ring()
1092 if (ring->virtual || ring->d2h_buffers_only) { in bcm4377_create_transfer_ring()
1093 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = in bcm4377_create_transfer_ring()
1095 bcm4377_ring_doorbell(bcm4377, ring->doorbell, 0xf); in bcm4377_create_transfer_ring()
1098 ring->enabled = true; in bcm4377_create_transfer_ring()
1099 spin_unlock_irqrestore(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1112 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_destroy_transfer_ring()
1114 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_destroy_transfer_ring()
1117 dev_warn(&bcm4377->pdev->dev, in bcm4377_destroy_transfer_ring()
1118 "failed to destroy transfer ring %d\n", ring->ring_id); in bcm4377_destroy_transfer_ring()
1120 ring->enabled = false; in bcm4377_destroy_transfer_ring()
1132 return -EINVAL; in __bcm4378_send_calibration_chunk()
1139 skb = __hci_cmd_sync(bcm4377->hdev, 0xfd97, sizeof(cmd), &cmd, in __bcm4378_send_calibration_chunk()
1157 dev_err(&bcm4377->pdev->dev, in __bcm4378_send_calibration()
1159 return -ENOENT; in __bcm4378_send_calibration()
1162 for (i = 0, left = data_size; i < blocks; ++i, left -= transfer_len) { in __bcm4378_send_calibration()
1168 transfer_len, blocks - i - 1); in __bcm4378_send_calibration()
1170 dev_err(&bcm4377->pdev->dev, in __bcm4378_send_calibration()
1181 if ((strcmp(bcm4377->stepping, "b1") == 0) || in bcm4378_send_calibration()
1182 strcmp(bcm4377->stepping, "b3") == 0) in bcm4378_send_calibration()
1184 bcm4377, bcm4377->taurus_beamforming_cal_blob, in bcm4378_send_calibration()
1185 bcm4377->taurus_beamforming_cal_size); in bcm4378_send_calibration()
1188 bcm4377->taurus_cal_blob, in bcm4378_send_calibration()
1189 bcm4377->taurus_cal_size); in bcm4378_send_calibration()
1194 if (strcmp(bcm4377->stepping, "c2") == 0) in bcm4387_send_calibration()
1196 bcm4377, bcm4377->taurus_beamforming_cal_blob, in bcm4387_send_calibration()
1197 bcm4377->taurus_beamforming_cal_size); in bcm4387_send_calibration()
1200 bcm4377->taurus_cal_blob, in bcm4387_send_calibration()
1201 bcm4377->taurus_cal_size); in bcm4387_send_calibration()
1208 bcm4377, bcm4377->taurus_beamforming_cal_blob, in bcm4388_send_calibration()
1209 bcm4377->taurus_beamforming_cal_size); in bcm4388_send_calibration()
1219 snprintf(name0, sizeof(name0), "brcm/brcmbt%04x%s-%s-%s.%s", in bcm4377_request_blob()
1220 bcm4377->hw->id, bcm4377->stepping, bcm4377->board_type, in bcm4377_request_blob()
1221 bcm4377->vendor, suffix); in bcm4377_request_blob()
1222 snprintf(name1, sizeof(name1), "brcm/brcmbt%04x%s-%s.%s", in bcm4377_request_blob()
1223 bcm4377->hw->id, bcm4377->stepping, bcm4377->board_type, in bcm4377_request_blob()
1225 dev_dbg(&bcm4377->pdev->dev, "Trying to load firmware: '%s' or '%s'\n", in bcm4377_request_blob()
1228 ret = firmware_request_nowarn(&fw, name0, &bcm4377->pdev->dev); in bcm4377_request_blob()
1231 ret = firmware_request_nowarn(&fw, name1, &bcm4377->pdev->dev); in bcm4377_request_blob()
1235 dev_err(&bcm4377->pdev->dev, in bcm4377_request_blob()
1245 skb = __hci_cmd_sync(bcm4377->hdev, 0xfd98, fw->size, fw->data, in bcm4377_send_ptb()
1267 return -EINVAL; in bcm4378_send_ptb_chunk()
1273 skb = __hci_cmd_sync(bcm4377->hdev, 0xfe0d, sizeof(cmd), &cmd, in bcm4378_send_ptb_chunk()
1285 size_t chunks = DIV_ROUND_UP(fw->size, (size_t)BCM4378_PTB_CHUNK_SIZE); in bcm4378_send_ptb()
1289 for (i = 0, left = fw->size; i < chunks; ++i, left -= transfer_len) { in bcm4378_send_ptb()
1292 dev_dbg(&bcm4377->pdev->dev, "sending ptb chunk %zu/%zu\n", in bcm4378_send_ptb()
1295 bcm4377, fw->data + i * BCM4378_PTB_CHUNK_SIZE, in bcm4378_send_ptb()
1296 transfer_len, chunks - i - 1); in bcm4378_send_ptb()
1298 dev_err(&bcm4377->pdev->dev, in bcm4378_send_ptb()
1312 dev_dbg(&bcm4377->pdev->dev, "creating rings\n"); in bcm4377_hci_open()
1315 &bcm4377->hci_acl_ack_ring); in bcm4377_hci_open()
1319 &bcm4377->hci_acl_event_ring); in bcm4377_hci_open()
1322 ret = bcm4377_create_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_open()
1325 ret = bcm4377_create_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_open()
1328 dev_dbg(&bcm4377->pdev->dev, in bcm4377_hci_open()
1331 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_open()
1334 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_open()
1337 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_open()
1340 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_open()
1343 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_open()
1346 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_hci_open()
1349 dev_dbg(&bcm4377->pdev->dev, in bcm4377_hci_open()
1355 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_open()
1357 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_open()
1359 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_open()
1361 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_open()
1363 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_open()
1365 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_open()
1367 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_open()
1369 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_hci_open()
1371 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_hci_open()
1373 dev_err(&bcm4377->pdev->dev, "Creating rings failed with %d\n", ret); in bcm4377_hci_open()
1381 dev_dbg(&bcm4377->pdev->dev, "destroying rings in hci_close\n"); in bcm4377_hci_close()
1383 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_hci_close()
1384 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_close()
1385 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_close()
1386 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_close()
1387 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_close()
1388 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_close()
1390 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_close()
1391 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_close()
1392 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_hci_close()
1393 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_hci_close()
1401 if (addr->b[0] != 0x93) in bcm4377_is_valid_bdaddr()
1403 if (addr->b[1] != 0x76) in bcm4377_is_valid_bdaddr()
1405 if (addr->b[2] != 0x00) in bcm4377_is_valid_bdaddr()
1407 if (addr->b[4] != (bcm4377->hw->id & 0xff)) in bcm4377_is_valid_bdaddr()
1409 if (addr->b[5] != (bcm4377->hw->id >> 8)) in bcm4377_is_valid_bdaddr()
1419 skb = __hci_cmd_sync(bcm4377->hdev, HCI_OP_READ_BD_ADDR, 0, NULL, in bcm4377_check_bdaddr()
1424 dev_err(&bcm4377->pdev->dev, "HCI_OP_READ_BD_ADDR failed (%d)", in bcm4377_check_bdaddr()
1429 if (skb->len != sizeof(*bda)) { in bcm4377_check_bdaddr()
1430 dev_err(&bcm4377->pdev->dev, in bcm4377_check_bdaddr()
1433 return -EIO; in bcm4377_check_bdaddr()
1436 bda = (struct hci_rp_read_bd_addr *)skb->data; in bcm4377_check_bdaddr()
1437 if (!bcm4377_is_valid_bdaddr(bcm4377, &bda->bdaddr)) in bcm4377_check_bdaddr()
1438 set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &bcm4377->hdev->quirks); in bcm4377_check_bdaddr()
1450 if (bcm4377->hw->send_calibration) { in bcm4377_hci_setup()
1451 ret = bcm4377->hw->send_calibration(bcm4377); in bcm4377_hci_setup()
1458 dev_err(&bcm4377->pdev->dev, "failed to load PTB data"); in bcm4377_hci_setup()
1459 return -ENOENT; in bcm4377_hci_setup()
1462 ret = bcm4377->hw->send_ptb(bcm4377, fw); in bcm4377_hci_setup()
1478 hdev->stat.cmd_tx++; in bcm4377_hci_send_frame()
1479 ring = &bcm4377->hci_h2d_ring; in bcm4377_hci_send_frame()
1483 hdev->stat.acl_tx++; in bcm4377_hci_send_frame()
1484 ring = &bcm4377->acl_h2d_ring; in bcm4377_hci_send_frame()
1488 hdev->stat.sco_tx++; in bcm4377_hci_send_frame()
1489 ring = &bcm4377->sco_h2d_ring; in bcm4377_hci_send_frame()
1493 return -EILSEQ; in bcm4377_hci_send_frame()
1496 ret = bcm4377_enqueue(bcm4377, ring, skb->data, skb->len, false); in bcm4377_hci_send_frame()
1498 hdev->stat.err_tx++; in bcm4377_hci_send_frame()
1502 hdev->stat.byte_tx += skb->len; in bcm4377_hci_send_frame()
1516 dev_err(&bcm4377->pdev->dev, in bcm4377_hci_set_bdaddr()
1530 spin_lock_init(&ring->lock); in bcm4377_alloc_transfer_ring()
1531 ring->payload_size = ALIGN(ring->payload_size, 4); in bcm4377_alloc_transfer_ring()
1532 ring->mapped_payload_size = ALIGN(ring->mapped_payload_size, 4); in bcm4377_alloc_transfer_ring()
1534 if (ring->payload_size > BCM4377_XFER_RING_MAX_INPLACE_PAYLOAD_SIZE) in bcm4377_alloc_transfer_ring()
1535 return -EINVAL; in bcm4377_alloc_transfer_ring()
1536 if (ring->n_entries > BCM4377_MAX_RING_SIZE) in bcm4377_alloc_transfer_ring()
1537 return -EINVAL; in bcm4377_alloc_transfer_ring()
1538 if (ring->virtual && ring->allow_wait) in bcm4377_alloc_transfer_ring()
1539 return -EINVAL; in bcm4377_alloc_transfer_ring()
1541 if (ring->d2h_buffers_only) { in bcm4377_alloc_transfer_ring()
1542 if (ring->virtual) in bcm4377_alloc_transfer_ring()
1543 return -EINVAL; in bcm4377_alloc_transfer_ring()
1544 if (ring->payload_size) in bcm4377_alloc_transfer_ring()
1545 return -EINVAL; in bcm4377_alloc_transfer_ring()
1546 if (!ring->mapped_payload_size) in bcm4377_alloc_transfer_ring()
1547 return -EINVAL; in bcm4377_alloc_transfer_ring()
1549 if (ring->virtual) in bcm4377_alloc_transfer_ring()
1553 ring->payload_size + sizeof(struct bcm4377_xfer_ring_entry); in bcm4377_alloc_transfer_ring()
1554 ring->ring = dmam_alloc_coherent(&bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1555 ring->n_entries * entry_size, in bcm4377_alloc_transfer_ring()
1556 &ring->ring_dma, GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1557 if (!ring->ring) in bcm4377_alloc_transfer_ring()
1558 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1560 if (ring->allow_wait) { in bcm4377_alloc_transfer_ring()
1561 ring->events = devm_kcalloc(&bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1562 ring->n_entries, in bcm4377_alloc_transfer_ring()
1563 sizeof(*ring->events), GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1564 if (!ring->events) in bcm4377_alloc_transfer_ring()
1565 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1568 if (ring->mapped_payload_size) { in bcm4377_alloc_transfer_ring()
1569 ring->payloads = dmam_alloc_coherent( in bcm4377_alloc_transfer_ring()
1570 &bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1571 ring->n_entries * ring->mapped_payload_size, in bcm4377_alloc_transfer_ring()
1572 &ring->payloads_dma, GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1573 if (!ring->payloads) in bcm4377_alloc_transfer_ring()
1574 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1585 ring->payload_size = ALIGN(ring->payload_size, 4); in bcm4377_alloc_completion_ring()
1586 if (ring->payload_size > BCM4377_XFER_RING_MAX_INPLACE_PAYLOAD_SIZE) in bcm4377_alloc_completion_ring()
1587 return -EINVAL; in bcm4377_alloc_completion_ring()
1588 if (ring->n_entries > BCM4377_MAX_RING_SIZE) in bcm4377_alloc_completion_ring()
1589 return -EINVAL; in bcm4377_alloc_completion_ring()
1591 entry_size = ring->payload_size + in bcm4377_alloc_completion_ring()
1594 ring->ring = dmam_alloc_coherent(&bcm4377->pdev->dev, in bcm4377_alloc_completion_ring()
1595 ring->n_entries * entry_size, in bcm4377_alloc_completion_ring()
1596 &ring->ring_dma, GFP_KERNEL); in bcm4377_alloc_completion_ring()
1597 if (!ring->ring) in bcm4377_alloc_completion_ring()
1598 return -ENOMEM; in bcm4377_alloc_completion_ring()
1604 struct device *dev = &bcm4377->pdev->dev; in bcm4377_init_context()
1607 bcm4377->ctx = dmam_alloc_coherent(dev, sizeof(*bcm4377->ctx), in bcm4377_init_context()
1608 &bcm4377->ctx_dma, GFP_KERNEL); in bcm4377_init_context()
1609 if (!bcm4377->ctx) in bcm4377_init_context()
1610 return -ENOMEM; in bcm4377_init_context()
1611 memset(bcm4377->ctx, 0, sizeof(*bcm4377->ctx)); in bcm4377_init_context()
1613 bcm4377->ring_state = in bcm4377_init_context()
1614 dmam_alloc_coherent(dev, sizeof(*bcm4377->ring_state), in bcm4377_init_context()
1615 &bcm4377->ring_state_dma, GFP_KERNEL); in bcm4377_init_context()
1616 if (!bcm4377->ring_state) in bcm4377_init_context()
1617 return -ENOMEM; in bcm4377_init_context()
1618 memset(bcm4377->ring_state, 0, sizeof(*bcm4377->ring_state)); in bcm4377_init_context()
1620 bcm4377->ctx->version = cpu_to_le16(1); in bcm4377_init_context()
1621 bcm4377->ctx->size = cpu_to_le16(sizeof(*bcm4377->ctx)); in bcm4377_init_context()
1622 bcm4377->ctx->enabled_caps = cpu_to_le32(2); in bcm4377_init_context()
1629 if (!dmam_alloc_coherent(&bcm4377->pdev->dev, 0x20, in bcm4377_init_context()
1631 return -ENOMEM; in bcm4377_init_context()
1632 bcm4377->ctx->peripheral_info_addr = cpu_to_le64(peripheral_info_dma); in bcm4377_init_context()
1634 bcm4377->ctx->xfer_ring_heads_addr = cpu_to_le64( in bcm4377_init_context()
1635 bcm4377->ring_state_dma + in bcm4377_init_context()
1637 bcm4377->ctx->xfer_ring_tails_addr = cpu_to_le64( in bcm4377_init_context()
1638 bcm4377->ring_state_dma + in bcm4377_init_context()
1640 bcm4377->ctx->completion_ring_heads_addr = cpu_to_le64( in bcm4377_init_context()
1641 bcm4377->ring_state_dma + in bcm4377_init_context()
1643 bcm4377->ctx->completion_ring_tails_addr = cpu_to_le64( in bcm4377_init_context()
1644 bcm4377->ring_state_dma + in bcm4377_init_context()
1647 bcm4377->ctx->n_completion_rings = in bcm4377_init_context()
1649 bcm4377->ctx->n_xfer_rings = cpu_to_le16(BCM4377_N_TRANSFER_RINGS); in bcm4377_init_context()
1651 bcm4377->ctx->control_completion_ring_addr = in bcm4377_init_context()
1652 cpu_to_le64(bcm4377->control_ack_ring.ring_dma); in bcm4377_init_context()
1653 bcm4377->ctx->control_completion_ring_n_entries = in bcm4377_init_context()
1654 cpu_to_le16(bcm4377->control_ack_ring.n_entries); in bcm4377_init_context()
1655 bcm4377->ctx->control_completion_ring_doorbell = cpu_to_le16(0xffff); in bcm4377_init_context()
1656 bcm4377->ctx->control_completion_ring_msi = 0; in bcm4377_init_context()
1657 bcm4377->ctx->control_completion_ring_header_size = 0; in bcm4377_init_context()
1658 bcm4377->ctx->control_completion_ring_footer_size = 0; in bcm4377_init_context()
1660 bcm4377->ctx->control_xfer_ring_addr = in bcm4377_init_context()
1661 cpu_to_le64(bcm4377->control_h2d_ring.ring_dma); in bcm4377_init_context()
1662 bcm4377->ctx->control_xfer_ring_n_entries = in bcm4377_init_context()
1663 cpu_to_le16(bcm4377->control_h2d_ring.n_entries); in bcm4377_init_context()
1664 bcm4377->ctx->control_xfer_ring_doorbell = in bcm4377_init_context()
1665 cpu_to_le16(bcm4377->control_h2d_ring.doorbell); in bcm4377_init_context()
1666 bcm4377->ctx->control_xfer_ring_msi = 0; in bcm4377_init_context()
1667 bcm4377->ctx->control_xfer_ring_header_size = 0; in bcm4377_init_context()
1668 bcm4377->ctx->control_xfer_ring_footer_size = in bcm4377_init_context()
1669 bcm4377->control_h2d_ring.payload_size / 4; in bcm4377_init_context()
1671 dev_dbg(&bcm4377->pdev->dev, "context initialized at IOVA %pad", in bcm4377_init_context()
1672 &bcm4377->ctx_dma); in bcm4377_init_context()
1691 bcm4377->control_ack_ring.ring_id = BCM4377_ACK_RING_CONTROL; in bcm4377_prepare_rings()
1692 bcm4377->control_ack_ring.n_entries = 32; in bcm4377_prepare_rings()
1693 bcm4377->control_ack_ring.transfer_rings = in bcm4377_prepare_rings()
1696 bcm4377->hci_acl_ack_ring.ring_id = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1697 bcm4377->hci_acl_ack_ring.n_entries = 2 * BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1698 bcm4377->hci_acl_ack_ring.transfer_rings = in bcm4377_prepare_rings()
1700 bcm4377->hci_acl_ack_ring.delay = 1000; in bcm4377_prepare_rings()
1707 bcm4377->hci_acl_event_ring.ring_id = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1708 bcm4377->hci_acl_event_ring.payload_size = MAX_EVENT_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1709 bcm4377->hci_acl_event_ring.n_entries = 2 * BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1710 bcm4377->hci_acl_event_ring.transfer_rings = in bcm4377_prepare_rings()
1712 bcm4377->hci_acl_event_ring.delay = 1000; in bcm4377_prepare_rings()
1714 bcm4377->sco_ack_ring.ring_id = BCM4377_ACK_RING_SCO; in bcm4377_prepare_rings()
1715 bcm4377->sco_ack_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1716 bcm4377->sco_ack_ring.transfer_rings = BIT(BCM4377_XFER_RING_SCO_H2D); in bcm4377_prepare_rings()
1718 bcm4377->sco_event_ring.ring_id = BCM4377_EVENT_RING_SCO; in bcm4377_prepare_rings()
1719 bcm4377->sco_event_ring.payload_size = MAX_SCO_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1720 bcm4377->sco_event_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1721 bcm4377->sco_event_ring.transfer_rings = BIT(BCM4377_XFER_RING_SCO_D2H); in bcm4377_prepare_rings()
1723 bcm4377->control_h2d_ring.ring_id = BCM4377_XFER_RING_CONTROL; in bcm4377_prepare_rings()
1724 bcm4377->control_h2d_ring.doorbell = BCM4377_DOORBELL_CONTROL; in bcm4377_prepare_rings()
1725 bcm4377->control_h2d_ring.payload_size = BCM4377_CONTROL_MSG_SIZE; in bcm4377_prepare_rings()
1726 bcm4377->control_h2d_ring.completion_ring = BCM4377_ACK_RING_CONTROL; in bcm4377_prepare_rings()
1727 bcm4377->control_h2d_ring.allow_wait = true; in bcm4377_prepare_rings()
1728 bcm4377->control_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1730 bcm4377->hci_h2d_ring.ring_id = BCM4377_XFER_RING_HCI_H2D; in bcm4377_prepare_rings()
1731 bcm4377->hci_h2d_ring.doorbell = BCM4377_DOORBELL_HCI_H2D; in bcm4377_prepare_rings()
1732 bcm4377->hci_h2d_ring.payload_size = MAX_EVENT_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1733 bcm4377->hci_h2d_ring.completion_ring = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1734 bcm4377->hci_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1736 bcm4377->hci_d2h_ring.ring_id = BCM4377_XFER_RING_HCI_D2H; in bcm4377_prepare_rings()
1737 bcm4377->hci_d2h_ring.doorbell = BCM4377_DOORBELL_HCI_D2H; in bcm4377_prepare_rings()
1738 bcm4377->hci_d2h_ring.completion_ring = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1739 bcm4377->hci_d2h_ring.virtual = true; in bcm4377_prepare_rings()
1740 bcm4377->hci_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1742 bcm4377->sco_h2d_ring.ring_id = BCM4377_XFER_RING_SCO_H2D; in bcm4377_prepare_rings()
1743 bcm4377->sco_h2d_ring.doorbell = BCM4377_DOORBELL_SCO; in bcm4377_prepare_rings()
1744 bcm4377->sco_h2d_ring.payload_size = MAX_SCO_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1745 bcm4377->sco_h2d_ring.completion_ring = BCM4377_ACK_RING_SCO; in bcm4377_prepare_rings()
1746 bcm4377->sco_h2d_ring.sync = true; in bcm4377_prepare_rings()
1747 bcm4377->sco_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1749 bcm4377->sco_d2h_ring.ring_id = BCM4377_XFER_RING_SCO_D2H; in bcm4377_prepare_rings()
1750 bcm4377->sco_d2h_ring.doorbell = BCM4377_DOORBELL_SCO; in bcm4377_prepare_rings()
1751 bcm4377->sco_d2h_ring.completion_ring = BCM4377_EVENT_RING_SCO; in bcm4377_prepare_rings()
1752 bcm4377->sco_d2h_ring.virtual = true; in bcm4377_prepare_rings()
1753 bcm4377->sco_d2h_ring.sync = true; in bcm4377_prepare_rings()
1754 bcm4377->sco_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1760 bcm4377->acl_h2d_ring.ring_id = BCM4377_XFER_RING_ACL_H2D; in bcm4377_prepare_rings()
1761 bcm4377->acl_h2d_ring.doorbell = BCM4377_DOORBELL_ACL_H2D; in bcm4377_prepare_rings()
1762 bcm4377->acl_h2d_ring.mapped_payload_size = MAX_ACL_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1763 bcm4377->acl_h2d_ring.completion_ring = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1764 bcm4377->acl_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1770 bcm4377->acl_d2h_ring.ring_id = BCM4377_XFER_RING_ACL_D2H; in bcm4377_prepare_rings()
1771 bcm4377->acl_d2h_ring.doorbell = BCM4377_DOORBELL_ACL_D2H; in bcm4377_prepare_rings()
1772 bcm4377->acl_d2h_ring.completion_ring = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1773 bcm4377->acl_d2h_ring.d2h_buffers_only = true; in bcm4377_prepare_rings()
1774 bcm4377->acl_d2h_ring.mapped_payload_size = MAX_ACL_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1775 bcm4377->acl_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1779 * and only devres-managed allocations are used in bcm4377_prepare_rings()
1781 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->control_h2d_ring); in bcm4377_prepare_rings()
1784 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_prepare_rings()
1787 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_prepare_rings()
1790 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_prepare_rings()
1793 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_prepare_rings()
1796 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_prepare_rings()
1799 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_prepare_rings()
1804 &bcm4377->control_ack_ring); in bcm4377_prepare_rings()
1808 &bcm4377->hci_acl_ack_ring); in bcm4377_prepare_rings()
1812 &bcm4377->hci_acl_event_ring); in bcm4377_prepare_rings()
1815 ret = bcm4377_alloc_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_prepare_rings()
1818 ret = bcm4377_alloc_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_prepare_rings()
1822 dev_dbg(&bcm4377->pdev->dev, "all rings allocated and prepared\n"); in bcm4377_prepare_rings()
1835 bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE); in bcm4377_boot()
1836 rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS); in bcm4377_boot()
1839 dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n", in bcm4377_boot()
1841 return -EINVAL; in bcm4377_boot()
1845 dev_err(&bcm4377->pdev->dev, "RTI status is %d and not 0\n", in bcm4377_boot()
1847 return -EINVAL; in bcm4377_boot()
1852 dev_err(&bcm4377->pdev->dev, "Failed to load firmware\n"); in bcm4377_boot()
1853 return -ENOENT; in bcm4377_boot()
1856 bfr = dma_alloc_coherent(&bcm4377->pdev->dev, fw->size, &fw_dma, in bcm4377_boot()
1859 ret = -ENOMEM; in bcm4377_boot()
1863 memcpy(bfr, fw->data, fw->size); in bcm4377_boot()
1865 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_LO); in bcm4377_boot()
1866 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_HI); in bcm4377_boot()
1868 bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE); in bcm4377_boot()
1871 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_LO); in bcm4377_boot()
1873 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_HI); in bcm4377_boot()
1874 iowrite32(fw->size, in bcm4377_boot()
1875 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_SIZE); in bcm4377_boot()
1876 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL); in bcm4377_boot()
1878 dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n"); in bcm4377_boot()
1880 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_boot()
1883 ret = -ETIMEDOUT; in bcm4377_boot()
1889 if (bcm4377->bootstage != 2) { in bcm4377_boot()
1890 dev_err(&bcm4377->pdev->dev, "boostage %d != 2\n", in bcm4377_boot()
1891 bcm4377->bootstage); in bcm4377_boot()
1892 ret = -ENXIO; in bcm4377_boot()
1896 dev_dbg(&bcm4377->pdev->dev, "firmware has booted (stage = %x)\n", in bcm4377_boot()
1897 bcm4377->bootstage); in bcm4377_boot()
1901 dma_free_coherent(&bcm4377->pdev->dev, fw->size, bfr, fw_dma); in bcm4377_boot()
1911 dev_dbg(&bcm4377->pdev->dev, "starting RTI\n"); in bcm4377_setup_rti()
1912 iowrite32(1, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL); in bcm4377_setup_rti()
1914 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_setup_rti()
1917 dev_err(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1919 return -ETIMEDOUT; in bcm4377_setup_rti()
1924 if (bcm4377->rti_status != 1) { in bcm4377_setup_rti()
1925 dev_err(&bcm4377->pdev->dev, "RTI did not ack state 1 (%d)\n", in bcm4377_setup_rti()
1926 bcm4377->rti_status); in bcm4377_setup_rti()
1927 return -ENODEV; in bcm4377_setup_rti()
1929 dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n"); in bcm4377_setup_rti()
1932 iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_LO); in bcm4377_setup_rti()
1933 iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_HI); in bcm4377_setup_rti()
1935 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_SIZE); in bcm4377_setup_rti()
1938 iowrite32(lower_32_bits(bcm4377->ctx_dma), in bcm4377_setup_rti()
1939 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_LO); in bcm4377_setup_rti()
1940 iowrite32(upper_32_bits(bcm4377->ctx_dma), in bcm4377_setup_rti()
1941 bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_HI); in bcm4377_setup_rti()
1942 iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL); in bcm4377_setup_rti()
1944 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_setup_rti()
1947 dev_err(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1949 return -ETIMEDOUT; in bcm4377_setup_rti()
1954 if (bcm4377->rti_status != 2) { in bcm4377_setup_rti()
1955 dev_err(&bcm4377->pdev->dev, "RTI did not ack state 2 (%d)\n", in bcm4377_setup_rti()
1956 bcm4377->rti_status); in bcm4377_setup_rti()
1957 return -ENODEV; in bcm4377_setup_rti()
1960 dev_dbg(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1962 bcm4377->control_ack_ring.enabled = true; in bcm4377_setup_rti()
1972 if (len >= sizeof(bcm4377->vendor)) in bcm4377_parse_otp_board_params()
1973 return -EINVAL; in bcm4377_parse_otp_board_params()
1975 strscpy(bcm4377->vendor, val, len + 1); in bcm4377_parse_otp_board_params()
1986 if (len >= sizeof(bcm4377->stepping)) in bcm4377_parse_otp_chip_params()
1987 return -EINVAL; in bcm4377_parse_otp_chip_params()
1990 bcm4377->stepping[idx] = tolower(val[idx]); in bcm4377_parse_otp_chip_params()
1995 len--; in bcm4377_parse_otp_chip_params()
1998 bcm4377->stepping[idx] = '\0'; in bcm4377_parse_otp_chip_params()
2015 return -EINVAL; in bcm4377_parse_otp_str()
2019 len = end - p; in bcm4377_parse_otp_str()
2022 if (len > (BCM4377_OTP_MAX_PARAM_LEN - 1)) in bcm4377_parse_otp_str()
2023 return -EINVAL; in bcm4377_parse_otp_str()
2035 ret = -EINVAL; in bcm4377_parse_otp_str()
2057 /* 4-byte header and two empty strings */ in bcm4377_parse_otp_sys_vendor()
2059 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2062 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2067 idx += strnlen(chip_params, size - idx) + 1; in bcm4377_parse_otp_sys_vendor()
2069 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2074 idx += strnlen(board_params, size - idx); in bcm4377_parse_otp_sys_vendor()
2076 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2078 /* At this point both strings are guaranteed NUL-terminated */ in bcm4377_parse_otp_sys_vendor()
2079 dev_dbg(&bcm4377->pdev->dev, in bcm4377_parse_otp_sys_vendor()
2093 if (!bcm4377->stepping[0] || !bcm4377->vendor[0]) in bcm4377_parse_otp_sys_vendor()
2094 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2096 dev_dbg(&bcm4377->pdev->dev, "OTP: stepping=%s, vendor=%s\n", in bcm4377_parse_otp_sys_vendor()
2097 bcm4377->stepping, bcm4377->vendor); in bcm4377_parse_otp_sys_vendor()
2105 int ret = -ENOENT; in bcm4377_parse_otp()
2109 return -ENOMEM; in bcm4377_parse_otp()
2112 otp[i] = ioread8(bcm4377->bar0 + bcm4377->hw->otp_offset + i); in bcm4377_parse_otp()
2115 while (i < (BCM4377_OTP_SIZE - 1)) { in bcm4377_parse_otp()
2127 dev_dbg(&bcm4377->pdev->dev, in bcm4377_parse_otp()
2133 dev_dbg(&bcm4377->pdev->dev, "OTP @ 0x%x (%d): CIS", i, in bcm4377_parse_otp()
2137 dev_dbg(&bcm4377->pdev->dev, "OTP @ 0x%x (%d): unknown", in bcm4377_parse_otp()
2154 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2156 bcm4377->hw->bar0_window1); in bcm4377_init_cfg()
2160 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2162 bcm4377->hw->bar0_window2); in bcm4377_init_cfg()
2167 bcm4377->pdev, BCM4377_PCIECFG_BAR0_CORE2_WINDOW1, in bcm4377_init_cfg()
2172 if (bcm4377->hw->has_bar0_core2_window2) { in bcm4377_init_cfg()
2173 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2175 bcm4377->hw->bar0_core2_window2); in bcm4377_init_cfg()
2180 ret = pci_write_config_dword(bcm4377->pdev, BCM4377_PCIECFG_BAR2_WINDOW, in bcm4377_init_cfg()
2185 ret = pci_read_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2190 if (bcm4377->hw->clear_pciecfg_subsystem_ctrl_bit19) in bcm4377_init_cfg()
2194 return pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2203 if (board_type_dmi_id && board_type_dmi_id->driver_data) { in bcm4377_probe_dmi()
2204 bcm4377->board_type = board_type_dmi_id->driver_data; in bcm4377_probe_dmi()
2205 dev_dbg(&bcm4377->pdev->dev, in bcm4377_probe_dmi()
2207 bcm4377->board_type); in bcm4377_probe_dmi()
2215 struct device_node *np = bcm4377->pdev->dev.of_node; in bcm4377_probe_of()
2221 ret = of_property_read_string(np, "brcm,board-type", in bcm4377_probe_of()
2222 &bcm4377->board_type); in bcm4377_probe_of()
2224 dev_err(&bcm4377->pdev->dev, "no brcm,board-type property\n"); in bcm4377_probe_of()
2228 bcm4377->taurus_beamforming_cal_blob = in bcm4377_probe_of()
2229 of_get_property(np, "brcm,taurus-bf-cal-blob", in bcm4377_probe_of()
2230 &bcm4377->taurus_beamforming_cal_size); in bcm4377_probe_of()
2231 if (!bcm4377->taurus_beamforming_cal_blob) { in bcm4377_probe_of()
2232 dev_err(&bcm4377->pdev->dev, in bcm4377_probe_of()
2233 "no brcm,taurus-bf-cal-blob property\n"); in bcm4377_probe_of()
2234 return -ENOENT; in bcm4377_probe_of()
2236 bcm4377->taurus_cal_blob = of_get_property(np, "brcm,taurus-cal-blob", in bcm4377_probe_of()
2237 &bcm4377->taurus_cal_size); in bcm4377_probe_of()
2238 if (!bcm4377->taurus_cal_blob) { in bcm4377_probe_of()
2239 dev_err(&bcm4377->pdev->dev, in bcm4377_probe_of()
2240 "no brcm,taurus-cal-blob property\n"); in bcm4377_probe_of()
2241 return -ENOENT; in bcm4377_probe_of()
2249 pci_disable_link_state(bcm4377->pdev, in bcm4377_disable_aspm()
2257 pcie_capability_clear_word(bcm4377->pdev, PCI_EXP_LNKCTL, in bcm4377_disable_aspm()
2282 ret = dma_set_mask_and_coherent(&pdev->dev, BCM4377_DMA_MASK); in bcm4377_probe()
2286 bcm4377 = devm_kzalloc(&pdev->dev, sizeof(*bcm4377), GFP_KERNEL); in bcm4377_probe()
2288 return -ENOMEM; in bcm4377_probe()
2290 bcm4377->pdev = pdev; in bcm4377_probe()
2291 bcm4377->hw = &bcm4377_hw_variants[id->driver_data]; in bcm4377_probe()
2292 init_completion(&bcm4377->event); in bcm4377_probe()
2308 if (!bcm4377->board_type) { in bcm4377_probe()
2309 dev_err(&pdev->dev, "unable to determine board type\n"); in bcm4377_probe()
2310 return -ENODEV; in bcm4377_probe()
2313 if (bcm4377->hw->disable_aspm) in bcm4377_probe()
2319 &pdev->dev, in bcm4377_probe()
2340 bcm4377->bar0 = pcim_iomap(pdev, 0, 0); in bcm4377_probe()
2341 if (!bcm4377->bar0) in bcm4377_probe()
2342 return -EBUSY; in bcm4377_probe()
2343 bcm4377->bar2 = pcim_iomap(pdev, 2, 0); in bcm4377_probe()
2344 if (!bcm4377->bar2) in bcm4377_probe()
2345 return -EBUSY; in bcm4377_probe()
2349 dev_err(&pdev->dev, "Reading OTP failed with %d\n", ret); in bcm4377_probe()
2360 return -ENODEV; in bcm4377_probe()
2361 ret = devm_add_action_or_reset(&pdev->dev, bcm4377_pci_free_irq_vectors, in bcm4377_probe()
2368 return -ENODEV; in bcm4377_probe()
2370 ret = devm_request_irq(&pdev->dev, irq, bcm4377_irq, 0, "bcm4377", in bcm4377_probe()
2377 return -ENOMEM; in bcm4377_probe()
2378 ret = devm_add_action_or_reset(&pdev->dev, bcm4377_hci_free_dev, hdev); in bcm4377_probe()
2382 bcm4377->hdev = hdev; in bcm4377_probe()
2384 hdev->bus = HCI_PCI; in bcm4377_probe()
2385 hdev->open = bcm4377_hci_open; in bcm4377_probe()
2386 hdev->close = bcm4377_hci_close; in bcm4377_probe()
2387 hdev->send = bcm4377_hci_send_frame; in bcm4377_probe()
2388 hdev->set_bdaddr = bcm4377_hci_set_bdaddr; in bcm4377_probe()
2389 hdev->setup = bcm4377_hci_setup; in bcm4377_probe()
2391 if (bcm4377->hw->broken_mws_transport_config) in bcm4377_probe()
2392 set_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &hdev->quirks); in bcm4377_probe()
2393 if (bcm4377->hw->broken_ext_scan) in bcm4377_probe()
2394 set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); in bcm4377_probe()
2395 if (bcm4377->hw->broken_le_coded) in bcm4377_probe()
2396 set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks); in bcm4377_probe()
2397 if (bcm4377->hw->broken_le_ext_adv_report_phy) in bcm4377_probe()
2398 set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks); in bcm4377_probe()
2402 SET_HCIDEV_DEV(hdev, &pdev->dev); in bcm4377_probe()
2415 return devm_add_action_or_reset(&pdev->dev, bcm4377_hci_unregister_dev, in bcm4377_probe()
2424 ret = hci_suspend_dev(bcm4377->hdev); in bcm4377_suspend()
2429 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_suspend()
2439 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_resume()
2441 return hci_resume_dev(bcm4377->hdev); in bcm4377_resume()