Lines Matching +full:taurus +full:- +full:cal +full:- +full:blob
1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
11 #include <linux/dma-mapping.h>
253 * - virtual: set if there is no associated shared memory and only the
255 * - sync: only set for the SCO rings
401 * payload_size: optional in-place payload size
402 * mapped_payload_size: optional out-of-place payload size
408 * setup a corresponding completion ring for device->host messages
410 * buffers used by device->host messages in the completion
480 * Chip-specific configuration struct
491 * vendor-specific subsystem control
534 * hw: Pointer to chip-specific struct bcm4377_hw
535 * taurus_cal_blob: "Taurus" calibration blob used for some chips
536 * taurus_cal_size: "Taurus" calibration blob size
537 * taurus_beamforming_cal_blob: "Taurus" beamforming calibration blob used for
539 * taurus_beamforming_cal_size: "Taurus" beamforming calibration blob size
549 * {hci_acl,sco}_event_ring: Completion rings used for device->host messages
612 dev_dbg(&bcm4377->pdev->dev, "write %d to doorbell #%d (0x%x)\n", val, in bcm4377_ring_doorbell()
614 iowrite32(db, bcm4377->bar0 + BCM4377_BAR0_DOORBELL); in bcm4377_ring_doorbell()
624 if (generation != ring->generation) { in bcm4377_extract_msgid()
626 &bcm4377->pdev->dev, in bcm4377_extract_msgid()
628 generation, ring->generation, ring->ring_id); in bcm4377_extract_msgid()
629 return -EINVAL; in bcm4377_extract_msgid()
632 if (*msgid >= ring->n_entries) { in bcm4377_extract_msgid()
633 dev_warn(&bcm4377->pdev->dev, in bcm4377_extract_msgid()
635 ring->ring_id, *msgid, ring->n_entries); in bcm4377_extract_msgid()
636 return -EINVAL; in bcm4377_extract_msgid()
652 spin_lock_irqsave(&ring->lock, flags); in bcm4377_handle_event()
653 if (!ring->enabled) { in bcm4377_handle_event()
654 dev_warn(&bcm4377->pdev->dev, in bcm4377_handle_event()
656 ring->ring_id); in bcm4377_handle_event()
660 if (ring->d2h_buffers_only && in bcm4377_handle_event()
665 if (len > ring->mapped_payload_size) { in bcm4377_handle_event()
667 &bcm4377->pdev->dev, in bcm4377_handle_event()
669 ring->ring_id, len, ring->mapped_payload_size); in bcm4377_handle_event()
673 payload = ring->payloads + msgid * ring->mapped_payload_size; in bcm4377_handle_event()
682 hci_recv_frame(bcm4377->hdev, skb); in bcm4377_handle_event()
685 head = le16_to_cpu(bcm4377->ring_state->xfer_ring_head[ring->ring_id]); in bcm4377_handle_event()
686 head = (head + 1) % ring->n_entries; in bcm4377_handle_event()
687 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = cpu_to_le16(head); in bcm4377_handle_event()
689 bcm4377_ring_doorbell(bcm4377, ring->doorbell, head); in bcm4377_handle_event()
691 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_handle_event()
701 spin_lock_irqsave(&ring->lock, flags); in bcm4377_handle_ack()
706 if (!test_bit(msgid, ring->msgids)) { in bcm4377_handle_ack()
708 &bcm4377->pdev->dev, in bcm4377_handle_ack()
710 ring->ring_id, msgid); in bcm4377_handle_ack()
714 if (ring->allow_wait && ring->events[msgid]) { in bcm4377_handle_ack()
715 complete(ring->events[msgid]); in bcm4377_handle_ack()
716 ring->events[msgid] = NULL; in bcm4377_handle_ack()
719 bitmap_release_region(ring->msgids, msgid, 0); in bcm4377_handle_ack()
722 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_handle_ack()
734 if (pos >= ring->n_entries) { in bcm4377_handle_completion()
735 dev_warn(&bcm4377->pdev->dev, in bcm4377_handle_completion()
737 ring->ring_id); in bcm4377_handle_completion()
741 entry_size = sizeof(*entry) + ring->payload_size; in bcm4377_handle_completion()
742 entry = ring->ring + pos * entry_size; in bcm4377_handle_completion()
743 data = ring->ring + pos * entry_size + sizeof(*entry); in bcm4377_handle_completion()
744 data_len = le32_to_cpu(entry->len); in bcm4377_handle_completion()
745 msg_id = le16_to_cpu(entry->msg_id); in bcm4377_handle_completion()
746 transfer_ring = le16_to_cpu(entry->ring_id); in bcm4377_handle_completion()
748 if ((ring->transfer_rings & BIT(transfer_ring)) == 0) { in bcm4377_handle_completion()
750 &bcm4377->pdev->dev, in bcm4377_handle_completion()
752 pos, transfer_ring, ring->ring_id); in bcm4377_handle_completion()
756 dev_dbg(&bcm4377->pdev->dev, in bcm4377_handle_completion()
758 ring->ring_id, transfer_ring, msg_id); in bcm4377_handle_completion()
762 bcm4377_handle_ack(bcm4377, &bcm4377->control_h2d_ring, msg_id); in bcm4377_handle_completion()
765 bcm4377_handle_ack(bcm4377, &bcm4377->hci_h2d_ring, msg_id); in bcm4377_handle_completion()
768 bcm4377_handle_ack(bcm4377, &bcm4377->sco_h2d_ring, msg_id); in bcm4377_handle_completion()
771 bcm4377_handle_ack(bcm4377, &bcm4377->acl_h2d_ring, msg_id); in bcm4377_handle_completion()
775 bcm4377_handle_event(bcm4377, &bcm4377->hci_d2h_ring, msg_id, in bcm4377_handle_completion()
776 entry->flags, HCI_EVENT_PKT, data, in bcm4377_handle_completion()
780 bcm4377_handle_event(bcm4377, &bcm4377->sco_d2h_ring, msg_id, in bcm4377_handle_completion()
781 entry->flags, HCI_SCODATA_PKT, data, in bcm4377_handle_completion()
785 bcm4377_handle_event(bcm4377, &bcm4377->acl_d2h_ring, msg_id, in bcm4377_handle_completion()
786 entry->flags, HCI_ACLDATA_PKT, data, in bcm4377_handle_completion()
792 &bcm4377->pdev->dev, in bcm4377_handle_completion()
794 ring->ring_id, transfer_ring, msg_id); in bcm4377_handle_completion()
802 __le16 *heads = bcm4377->ring_state->completion_ring_head; in bcm4377_poll_completion_ring()
803 __le16 *tails = bcm4377->ring_state->completion_ring_tail; in bcm4377_poll_completion_ring()
805 if (!ring->enabled) in bcm4377_poll_completion_ring()
808 tail = le16_to_cpu(tails[ring->ring_id]); in bcm4377_poll_completion_ring()
809 dev_dbg(&bcm4377->pdev->dev, in bcm4377_poll_completion_ring()
810 "completion ring #%d: head: %d, tail: %d\n", ring->ring_id, in bcm4377_poll_completion_ring()
811 le16_to_cpu(heads[ring->ring_id]), tail); in bcm4377_poll_completion_ring()
813 while (tail != le16_to_cpu(READ_ONCE(heads[ring->ring_id]))) { in bcm4377_poll_completion_ring()
823 tail = (tail + 1) % ring->n_entries; in bcm4377_poll_completion_ring()
824 tails[ring->ring_id] = cpu_to_le16(tail); in bcm4377_poll_completion_ring()
833 bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE); in bcm4377_irq()
834 rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS); in bcm4377_irq()
836 if (bootstage != bcm4377->bootstage || in bcm4377_irq()
837 rti_status != bcm4377->rti_status) { in bcm4377_irq()
838 dev_dbg(&bcm4377->pdev->dev, in bcm4377_irq()
839 "bootstage = %d -> %d, rti state = %d -> %d\n", in bcm4377_irq()
840 bcm4377->bootstage, bootstage, bcm4377->rti_status, in bcm4377_irq()
842 complete(&bcm4377->event); in bcm4377_irq()
843 bcm4377->bootstage = bootstage; in bcm4377_irq()
844 bcm4377->rti_status = rti_status; in bcm4377_irq()
848 dev_err(&bcm4377->pdev->dev, "RTI status is %d\n", rti_status); in bcm4377_irq()
850 bcm4377_poll_completion_ring(bcm4377, &bcm4377->control_ack_ring); in bcm4377_irq()
851 bcm4377_poll_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_irq()
852 bcm4377_poll_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_irq()
853 bcm4377_poll_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_irq()
854 bcm4377_poll_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_irq()
872 if (len > ring->payload_size && len > ring->mapped_payload_size) { in bcm4377_enqueue()
874 &bcm4377->pdev->dev, in bcm4377_enqueue()
876 len, ring->ring_id, ring->payload_size, in bcm4377_enqueue()
877 ring->mapped_payload_size); in bcm4377_enqueue()
878 return -EINVAL; in bcm4377_enqueue()
880 if (wait && !ring->allow_wait) in bcm4377_enqueue()
881 return -EINVAL; in bcm4377_enqueue()
882 if (ring->virtual) in bcm4377_enqueue()
883 return -EINVAL; in bcm4377_enqueue()
885 spin_lock_irqsave(&ring->lock, flags); in bcm4377_enqueue()
887 head = le16_to_cpu(bcm4377->ring_state->xfer_ring_head[ring->ring_id]); in bcm4377_enqueue()
888 tail = le16_to_cpu(bcm4377->ring_state->xfer_ring_tail[ring->ring_id]); in bcm4377_enqueue()
890 new_head = (head + 1) % ring->n_entries; in bcm4377_enqueue()
893 dev_warn(&bcm4377->pdev->dev, in bcm4377_enqueue()
895 ring->ring_id); in bcm4377_enqueue()
896 ret = -EINVAL; in bcm4377_enqueue()
900 msgid = bitmap_find_free_region(ring->msgids, ring->n_entries, 0); in bcm4377_enqueue()
902 dev_warn(&bcm4377->pdev->dev, in bcm4377_enqueue()
903 "can't find message id for ring %d\n", ring->ring_id); in bcm4377_enqueue()
904 ret = -EINVAL; in bcm4377_enqueue()
908 raw_msgid = FIELD_PREP(BCM4377_MSGID_GENERATION, ring->generation); in bcm4377_enqueue()
911 offset = head * (sizeof(*entry) + ring->payload_size); in bcm4377_enqueue()
912 entry = ring->ring + offset; in bcm4377_enqueue()
915 entry->id = cpu_to_le16(raw_msgid); in bcm4377_enqueue()
916 entry->len = cpu_to_le16(len); in bcm4377_enqueue()
918 if (len <= ring->payload_size) { in bcm4377_enqueue()
919 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_IN_FOOTER; in bcm4377_enqueue()
920 payload = ring->ring + offset + sizeof(*entry); in bcm4377_enqueue()
922 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_MAPPED; in bcm4377_enqueue()
923 entry->payload = cpu_to_le64(ring->payloads_dma + in bcm4377_enqueue()
924 msgid * ring->mapped_payload_size); in bcm4377_enqueue()
925 payload = ring->payloads + msgid * ring->mapped_payload_size; in bcm4377_enqueue()
931 ring->events[msgid] = &event; in bcm4377_enqueue()
939 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_enqueue()
941 dev_dbg(&bcm4377->pdev->dev, in bcm4377_enqueue()
942 "updating head for transfer queue #%d to %d\n", ring->ring_id, in bcm4377_enqueue()
944 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = in bcm4377_enqueue()
947 if (!ring->sync) in bcm4377_enqueue()
948 bcm4377_ring_doorbell(bcm4377, ring->doorbell, new_head); in bcm4377_enqueue()
952 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_enqueue()
958 ret = -ETIMEDOUT; in bcm4377_enqueue()
962 spin_lock_irqsave(&ring->lock, flags); in bcm4377_enqueue()
963 ring->events[msgid] = NULL; in bcm4377_enqueue()
964 spin_unlock_irqrestore(&ring->lock, flags); in bcm4377_enqueue()
976 if (ring->enabled) { in bcm4377_create_completion_ring()
977 dev_warn(&bcm4377->pdev->dev, in bcm4377_create_completion_ring()
978 "completion ring %d already enabled\n", ring->ring_id); in bcm4377_create_completion_ring()
982 memset(ring->ring, 0, in bcm4377_create_completion_ring()
983 ring->n_entries * (sizeof(struct bcm4377_completion_ring_entry) + in bcm4377_create_completion_ring()
984 ring->payload_size)); in bcm4377_create_completion_ring()
987 msg.id = cpu_to_le16(ring->ring_id); in bcm4377_create_completion_ring()
988 msg.id_again = cpu_to_le16(ring->ring_id); in bcm4377_create_completion_ring()
989 msg.ring_iova = cpu_to_le64(ring->ring_dma); in bcm4377_create_completion_ring()
990 msg.n_elements = cpu_to_le16(ring->n_entries); in bcm4377_create_completion_ring()
993 msg.intmod_delay = cpu_to_le16(ring->delay); in bcm4377_create_completion_ring()
994 msg.footer_size = ring->payload_size / 4; in bcm4377_create_completion_ring()
996 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_create_completion_ring()
999 ring->enabled = true; in bcm4377_create_completion_ring()
1012 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_destroy_completion_ring()
1014 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_destroy_completion_ring()
1017 dev_warn(&bcm4377->pdev->dev, in bcm4377_destroy_completion_ring()
1019 ring->ring_id); in bcm4377_destroy_completion_ring()
1021 ring->enabled = false; in bcm4377_destroy_completion_ring()
1033 if (ring->virtual) in bcm4377_create_transfer_ring()
1035 if (ring->sync) in bcm4377_create_transfer_ring()
1038 spin_lock_irqsave(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1041 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_create_transfer_ring()
1042 msg.ring_id_again = cpu_to_le16(ring->ring_id); in bcm4377_create_transfer_ring()
1043 msg.ring_iova = cpu_to_le64(ring->ring_dma); in bcm4377_create_transfer_ring()
1044 msg.n_elements = cpu_to_le16(ring->n_entries); in bcm4377_create_transfer_ring()
1045 msg.completion_ring_id = cpu_to_le16(ring->completion_ring); in bcm4377_create_transfer_ring()
1046 msg.doorbell = cpu_to_le16(ring->doorbell); in bcm4377_create_transfer_ring()
1048 msg.footer_size = ring->payload_size / 4; in bcm4377_create_transfer_ring()
1050 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = 0; in bcm4377_create_transfer_ring()
1051 bcm4377->ring_state->xfer_ring_tail[ring->ring_id] = 0; in bcm4377_create_transfer_ring()
1052 ring->generation++; in bcm4377_create_transfer_ring()
1053 spin_unlock_irqrestore(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1055 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_create_transfer_ring()
1058 spin_lock_irqsave(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1060 if (ring->d2h_buffers_only) { in bcm4377_create_transfer_ring()
1061 for (i = 0; i < ring->n_entries; ++i) { in bcm4377_create_transfer_ring()
1063 ring->ring + i * sizeof(*entry); in bcm4377_create_transfer_ring()
1065 ring->generation); in bcm4377_create_transfer_ring()
1069 entry->id = cpu_to_le16(raw_msgid); in bcm4377_create_transfer_ring()
1070 entry->len = cpu_to_le16(ring->mapped_payload_size); in bcm4377_create_transfer_ring()
1071 entry->flags = BCM4377_XFER_RING_FLAG_PAYLOAD_MAPPED; in bcm4377_create_transfer_ring()
1072 entry->payload = in bcm4377_create_transfer_ring()
1073 cpu_to_le64(ring->payloads_dma + in bcm4377_create_transfer_ring()
1074 i * ring->mapped_payload_size); in bcm4377_create_transfer_ring()
1079 * send some messages if this is a device->host ring to allow the device in bcm4377_create_transfer_ring()
1082 if (ring->virtual || ring->d2h_buffers_only) { in bcm4377_create_transfer_ring()
1083 bcm4377->ring_state->xfer_ring_head[ring->ring_id] = in bcm4377_create_transfer_ring()
1085 bcm4377_ring_doorbell(bcm4377, ring->doorbell, 0xf); in bcm4377_create_transfer_ring()
1088 ring->enabled = true; in bcm4377_create_transfer_ring()
1089 spin_unlock_irqrestore(&ring->lock, spinlock_flags); in bcm4377_create_transfer_ring()
1102 msg.ring_id = cpu_to_le16(ring->ring_id); in bcm4377_destroy_transfer_ring()
1104 ret = bcm4377_enqueue(bcm4377, &bcm4377->control_h2d_ring, &msg, in bcm4377_destroy_transfer_ring()
1107 dev_warn(&bcm4377->pdev->dev, in bcm4377_destroy_transfer_ring()
1108 "failed to destroy transfer ring %d\n", ring->ring_id); in bcm4377_destroy_transfer_ring()
1110 ring->enabled = false; in bcm4377_destroy_transfer_ring()
1122 return -EINVAL; in __bcm4378_send_calibration_chunk()
1129 skb = __hci_cmd_sync(bcm4377->hdev, 0xfd97, sizeof(cmd), &cmd, in __bcm4378_send_calibration_chunk()
1147 dev_err(&bcm4377->pdev->dev, in __bcm4378_send_calibration()
1149 return -ENOENT; in __bcm4378_send_calibration()
1152 for (i = 0, left = data_size; i < blocks; ++i, left -= transfer_len) { in __bcm4378_send_calibration()
1158 transfer_len, blocks - i - 1); in __bcm4378_send_calibration()
1160 dev_err(&bcm4377->pdev->dev, in __bcm4378_send_calibration()
1171 if ((strcmp(bcm4377->stepping, "b1") == 0) || in bcm4378_send_calibration()
1172 strcmp(bcm4377->stepping, "b3") == 0) in bcm4378_send_calibration()
1174 bcm4377, bcm4377->taurus_beamforming_cal_blob, in bcm4378_send_calibration()
1175 bcm4377->taurus_beamforming_cal_size); in bcm4378_send_calibration()
1178 bcm4377->taurus_cal_blob, in bcm4378_send_calibration()
1179 bcm4377->taurus_cal_size); in bcm4378_send_calibration()
1184 if (strcmp(bcm4377->stepping, "c2") == 0) in bcm4387_send_calibration()
1186 bcm4377, bcm4377->taurus_beamforming_cal_blob, in bcm4387_send_calibration()
1187 bcm4377->taurus_beamforming_cal_size); in bcm4387_send_calibration()
1190 bcm4377->taurus_cal_blob, in bcm4387_send_calibration()
1191 bcm4377->taurus_cal_size); in bcm4387_send_calibration()
1201 snprintf(name0, sizeof(name0), "brcm/brcmbt%04x%s-%s-%s.%s", in bcm4377_request_blob()
1202 bcm4377->hw->id, bcm4377->stepping, bcm4377->board_type, in bcm4377_request_blob()
1203 bcm4377->vendor, suffix); in bcm4377_request_blob()
1204 snprintf(name1, sizeof(name1), "brcm/brcmbt%04x%s-%s.%s", in bcm4377_request_blob()
1205 bcm4377->hw->id, bcm4377->stepping, bcm4377->board_type, in bcm4377_request_blob()
1207 dev_dbg(&bcm4377->pdev->dev, "Trying to load firmware: '%s' or '%s'\n", in bcm4377_request_blob()
1210 ret = firmware_request_nowarn(&fw, name0, &bcm4377->pdev->dev); in bcm4377_request_blob()
1213 ret = firmware_request_nowarn(&fw, name1, &bcm4377->pdev->dev); in bcm4377_request_blob()
1217 dev_err(&bcm4377->pdev->dev, in bcm4377_request_blob()
1227 skb = __hci_cmd_sync(bcm4377->hdev, 0xfd98, fw->size, fw->data, in bcm4377_send_ptb()
1249 return -EINVAL; in bcm4378_send_ptb_chunk()
1255 skb = __hci_cmd_sync(bcm4377->hdev, 0xfe0d, sizeof(cmd), &cmd, in bcm4378_send_ptb_chunk()
1267 size_t chunks = DIV_ROUND_UP(fw->size, (size_t)BCM4378_PTB_CHUNK_SIZE); in bcm4378_send_ptb()
1271 for (i = 0, left = fw->size; i < chunks; ++i, left -= transfer_len) { in bcm4378_send_ptb()
1274 dev_dbg(&bcm4377->pdev->dev, "sending ptb chunk %zu/%zu\n", in bcm4378_send_ptb()
1277 bcm4377, fw->data + i * BCM4378_PTB_CHUNK_SIZE, in bcm4378_send_ptb()
1278 transfer_len, chunks - i - 1); in bcm4378_send_ptb()
1280 dev_err(&bcm4377->pdev->dev, in bcm4378_send_ptb()
1294 dev_dbg(&bcm4377->pdev->dev, "creating rings\n"); in bcm4377_hci_open()
1297 &bcm4377->hci_acl_ack_ring); in bcm4377_hci_open()
1301 &bcm4377->hci_acl_event_ring); in bcm4377_hci_open()
1304 ret = bcm4377_create_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_open()
1307 ret = bcm4377_create_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_open()
1310 dev_dbg(&bcm4377->pdev->dev, in bcm4377_hci_open()
1313 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_open()
1316 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_open()
1319 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_open()
1322 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_open()
1325 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_open()
1328 ret = bcm4377_create_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_hci_open()
1331 dev_dbg(&bcm4377->pdev->dev, in bcm4377_hci_open()
1337 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_open()
1339 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_open()
1341 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_open()
1343 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_open()
1345 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_open()
1347 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_open()
1349 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_open()
1351 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_hci_open()
1353 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_hci_open()
1355 dev_err(&bcm4377->pdev->dev, "Creating rings failed with %d\n", ret); in bcm4377_hci_open()
1363 dev_dbg(&bcm4377->pdev->dev, "destroying rings in hci_close\n"); in bcm4377_hci_close()
1365 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_hci_close()
1366 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_hci_close()
1367 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_hci_close()
1368 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_hci_close()
1369 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_hci_close()
1370 bcm4377_destroy_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_hci_close()
1372 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_hci_close()
1373 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_hci_close()
1374 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_event_ring); in bcm4377_hci_close()
1375 bcm4377_destroy_completion_ring(bcm4377, &bcm4377->hci_acl_ack_ring); in bcm4377_hci_close()
1383 if (addr->b[0] != 0x93) in bcm4377_is_valid_bdaddr()
1385 if (addr->b[1] != 0x76) in bcm4377_is_valid_bdaddr()
1387 if (addr->b[2] != 0x00) in bcm4377_is_valid_bdaddr()
1389 if (addr->b[4] != (bcm4377->hw->id & 0xff)) in bcm4377_is_valid_bdaddr()
1391 if (addr->b[5] != (bcm4377->hw->id >> 8)) in bcm4377_is_valid_bdaddr()
1401 skb = __hci_cmd_sync(bcm4377->hdev, HCI_OP_READ_BD_ADDR, 0, NULL, in bcm4377_check_bdaddr()
1406 dev_err(&bcm4377->pdev->dev, "HCI_OP_READ_BD_ADDR failed (%d)", in bcm4377_check_bdaddr()
1411 if (skb->len != sizeof(*bda)) { in bcm4377_check_bdaddr()
1412 dev_err(&bcm4377->pdev->dev, in bcm4377_check_bdaddr()
1415 return -EIO; in bcm4377_check_bdaddr()
1418 bda = (struct hci_rp_read_bd_addr *)skb->data; in bcm4377_check_bdaddr()
1419 if (!bcm4377_is_valid_bdaddr(bcm4377, &bda->bdaddr)) in bcm4377_check_bdaddr()
1420 set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &bcm4377->hdev->quirks); in bcm4377_check_bdaddr()
1432 if (bcm4377->hw->send_calibration) { in bcm4377_hci_setup()
1433 ret = bcm4377->hw->send_calibration(bcm4377); in bcm4377_hci_setup()
1440 dev_err(&bcm4377->pdev->dev, "failed to load PTB data"); in bcm4377_hci_setup()
1441 return -ENOENT; in bcm4377_hci_setup()
1444 ret = bcm4377->hw->send_ptb(bcm4377, fw); in bcm4377_hci_setup()
1460 hdev->stat.cmd_tx++; in bcm4377_hci_send_frame()
1461 ring = &bcm4377->hci_h2d_ring; in bcm4377_hci_send_frame()
1465 hdev->stat.acl_tx++; in bcm4377_hci_send_frame()
1466 ring = &bcm4377->acl_h2d_ring; in bcm4377_hci_send_frame()
1470 hdev->stat.sco_tx++; in bcm4377_hci_send_frame()
1471 ring = &bcm4377->sco_h2d_ring; in bcm4377_hci_send_frame()
1475 return -EILSEQ; in bcm4377_hci_send_frame()
1478 ret = bcm4377_enqueue(bcm4377, ring, skb->data, skb->len, false); in bcm4377_hci_send_frame()
1480 hdev->stat.err_tx++; in bcm4377_hci_send_frame()
1484 hdev->stat.byte_tx += skb->len; in bcm4377_hci_send_frame()
1498 dev_err(&bcm4377->pdev->dev, in bcm4377_hci_set_bdaddr()
1512 spin_lock_init(&ring->lock); in bcm4377_alloc_transfer_ring()
1513 ring->payload_size = ALIGN(ring->payload_size, 4); in bcm4377_alloc_transfer_ring()
1514 ring->mapped_payload_size = ALIGN(ring->mapped_payload_size, 4); in bcm4377_alloc_transfer_ring()
1516 if (ring->payload_size > BCM4377_XFER_RING_MAX_INPLACE_PAYLOAD_SIZE) in bcm4377_alloc_transfer_ring()
1517 return -EINVAL; in bcm4377_alloc_transfer_ring()
1518 if (ring->n_entries > BCM4377_MAX_RING_SIZE) in bcm4377_alloc_transfer_ring()
1519 return -EINVAL; in bcm4377_alloc_transfer_ring()
1520 if (ring->virtual && ring->allow_wait) in bcm4377_alloc_transfer_ring()
1521 return -EINVAL; in bcm4377_alloc_transfer_ring()
1523 if (ring->d2h_buffers_only) { in bcm4377_alloc_transfer_ring()
1524 if (ring->virtual) in bcm4377_alloc_transfer_ring()
1525 return -EINVAL; in bcm4377_alloc_transfer_ring()
1526 if (ring->payload_size) in bcm4377_alloc_transfer_ring()
1527 return -EINVAL; in bcm4377_alloc_transfer_ring()
1528 if (!ring->mapped_payload_size) in bcm4377_alloc_transfer_ring()
1529 return -EINVAL; in bcm4377_alloc_transfer_ring()
1531 if (ring->virtual) in bcm4377_alloc_transfer_ring()
1535 ring->payload_size + sizeof(struct bcm4377_xfer_ring_entry); in bcm4377_alloc_transfer_ring()
1536 ring->ring = dmam_alloc_coherent(&bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1537 ring->n_entries * entry_size, in bcm4377_alloc_transfer_ring()
1538 &ring->ring_dma, GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1539 if (!ring->ring) in bcm4377_alloc_transfer_ring()
1540 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1542 if (ring->allow_wait) { in bcm4377_alloc_transfer_ring()
1543 ring->events = devm_kcalloc(&bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1544 ring->n_entries, in bcm4377_alloc_transfer_ring()
1545 sizeof(*ring->events), GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1546 if (!ring->events) in bcm4377_alloc_transfer_ring()
1547 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1550 if (ring->mapped_payload_size) { in bcm4377_alloc_transfer_ring()
1551 ring->payloads = dmam_alloc_coherent( in bcm4377_alloc_transfer_ring()
1552 &bcm4377->pdev->dev, in bcm4377_alloc_transfer_ring()
1553 ring->n_entries * ring->mapped_payload_size, in bcm4377_alloc_transfer_ring()
1554 &ring->payloads_dma, GFP_KERNEL); in bcm4377_alloc_transfer_ring()
1555 if (!ring->payloads) in bcm4377_alloc_transfer_ring()
1556 return -ENOMEM; in bcm4377_alloc_transfer_ring()
1567 ring->payload_size = ALIGN(ring->payload_size, 4); in bcm4377_alloc_completion_ring()
1568 if (ring->payload_size > BCM4377_XFER_RING_MAX_INPLACE_PAYLOAD_SIZE) in bcm4377_alloc_completion_ring()
1569 return -EINVAL; in bcm4377_alloc_completion_ring()
1570 if (ring->n_entries > BCM4377_MAX_RING_SIZE) in bcm4377_alloc_completion_ring()
1571 return -EINVAL; in bcm4377_alloc_completion_ring()
1573 entry_size = ring->payload_size + in bcm4377_alloc_completion_ring()
1576 ring->ring = dmam_alloc_coherent(&bcm4377->pdev->dev, in bcm4377_alloc_completion_ring()
1577 ring->n_entries * entry_size, in bcm4377_alloc_completion_ring()
1578 &ring->ring_dma, GFP_KERNEL); in bcm4377_alloc_completion_ring()
1579 if (!ring->ring) in bcm4377_alloc_completion_ring()
1580 return -ENOMEM; in bcm4377_alloc_completion_ring()
1586 struct device *dev = &bcm4377->pdev->dev; in bcm4377_init_context()
1589 bcm4377->ctx = dmam_alloc_coherent(dev, sizeof(*bcm4377->ctx), in bcm4377_init_context()
1590 &bcm4377->ctx_dma, GFP_KERNEL); in bcm4377_init_context()
1591 if (!bcm4377->ctx) in bcm4377_init_context()
1592 return -ENOMEM; in bcm4377_init_context()
1593 memset(bcm4377->ctx, 0, sizeof(*bcm4377->ctx)); in bcm4377_init_context()
1595 bcm4377->ring_state = in bcm4377_init_context()
1596 dmam_alloc_coherent(dev, sizeof(*bcm4377->ring_state), in bcm4377_init_context()
1597 &bcm4377->ring_state_dma, GFP_KERNEL); in bcm4377_init_context()
1598 if (!bcm4377->ring_state) in bcm4377_init_context()
1599 return -ENOMEM; in bcm4377_init_context()
1600 memset(bcm4377->ring_state, 0, sizeof(*bcm4377->ring_state)); in bcm4377_init_context()
1602 bcm4377->ctx->version = cpu_to_le16(1); in bcm4377_init_context()
1603 bcm4377->ctx->size = cpu_to_le16(sizeof(*bcm4377->ctx)); in bcm4377_init_context()
1604 bcm4377->ctx->enabled_caps = cpu_to_le32(2); in bcm4377_init_context()
1611 if (!dmam_alloc_coherent(&bcm4377->pdev->dev, 0x20, in bcm4377_init_context()
1613 return -ENOMEM; in bcm4377_init_context()
1614 bcm4377->ctx->peripheral_info_addr = cpu_to_le64(peripheral_info_dma); in bcm4377_init_context()
1616 bcm4377->ctx->xfer_ring_heads_addr = cpu_to_le64( in bcm4377_init_context()
1617 bcm4377->ring_state_dma + in bcm4377_init_context()
1619 bcm4377->ctx->xfer_ring_tails_addr = cpu_to_le64( in bcm4377_init_context()
1620 bcm4377->ring_state_dma + in bcm4377_init_context()
1622 bcm4377->ctx->completion_ring_heads_addr = cpu_to_le64( in bcm4377_init_context()
1623 bcm4377->ring_state_dma + in bcm4377_init_context()
1625 bcm4377->ctx->completion_ring_tails_addr = cpu_to_le64( in bcm4377_init_context()
1626 bcm4377->ring_state_dma + in bcm4377_init_context()
1629 bcm4377->ctx->n_completion_rings = in bcm4377_init_context()
1631 bcm4377->ctx->n_xfer_rings = cpu_to_le16(BCM4377_N_TRANSFER_RINGS); in bcm4377_init_context()
1633 bcm4377->ctx->control_completion_ring_addr = in bcm4377_init_context()
1634 cpu_to_le64(bcm4377->control_ack_ring.ring_dma); in bcm4377_init_context()
1635 bcm4377->ctx->control_completion_ring_n_entries = in bcm4377_init_context()
1636 cpu_to_le16(bcm4377->control_ack_ring.n_entries); in bcm4377_init_context()
1637 bcm4377->ctx->control_completion_ring_doorbell = cpu_to_le16(0xffff); in bcm4377_init_context()
1638 bcm4377->ctx->control_completion_ring_msi = 0; in bcm4377_init_context()
1639 bcm4377->ctx->control_completion_ring_header_size = 0; in bcm4377_init_context()
1640 bcm4377->ctx->control_completion_ring_footer_size = 0; in bcm4377_init_context()
1642 bcm4377->ctx->control_xfer_ring_addr = in bcm4377_init_context()
1643 cpu_to_le64(bcm4377->control_h2d_ring.ring_dma); in bcm4377_init_context()
1644 bcm4377->ctx->control_xfer_ring_n_entries = in bcm4377_init_context()
1645 cpu_to_le16(bcm4377->control_h2d_ring.n_entries); in bcm4377_init_context()
1646 bcm4377->ctx->control_xfer_ring_doorbell = in bcm4377_init_context()
1647 cpu_to_le16(bcm4377->control_h2d_ring.doorbell); in bcm4377_init_context()
1648 bcm4377->ctx->control_xfer_ring_msi = 0; in bcm4377_init_context()
1649 bcm4377->ctx->control_xfer_ring_header_size = 0; in bcm4377_init_context()
1650 bcm4377->ctx->control_xfer_ring_footer_size = in bcm4377_init_context()
1651 bcm4377->control_h2d_ring.payload_size / 4; in bcm4377_init_context()
1653 dev_dbg(&bcm4377->pdev->dev, "context initialized at IOVA %pad", in bcm4377_init_context()
1654 &bcm4377->ctx_dma); in bcm4377_init_context()
1673 bcm4377->control_ack_ring.ring_id = BCM4377_ACK_RING_CONTROL; in bcm4377_prepare_rings()
1674 bcm4377->control_ack_ring.n_entries = 32; in bcm4377_prepare_rings()
1675 bcm4377->control_ack_ring.transfer_rings = in bcm4377_prepare_rings()
1678 bcm4377->hci_acl_ack_ring.ring_id = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1679 bcm4377->hci_acl_ack_ring.n_entries = 2 * BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1680 bcm4377->hci_acl_ack_ring.transfer_rings = in bcm4377_prepare_rings()
1682 bcm4377->hci_acl_ack_ring.delay = 1000; in bcm4377_prepare_rings()
1689 bcm4377->hci_acl_event_ring.ring_id = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1690 bcm4377->hci_acl_event_ring.payload_size = MAX_EVENT_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1691 bcm4377->hci_acl_event_ring.n_entries = 2 * BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1692 bcm4377->hci_acl_event_ring.transfer_rings = in bcm4377_prepare_rings()
1694 bcm4377->hci_acl_event_ring.delay = 1000; in bcm4377_prepare_rings()
1696 bcm4377->sco_ack_ring.ring_id = BCM4377_ACK_RING_SCO; in bcm4377_prepare_rings()
1697 bcm4377->sco_ack_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1698 bcm4377->sco_ack_ring.transfer_rings = BIT(BCM4377_XFER_RING_SCO_H2D); in bcm4377_prepare_rings()
1700 bcm4377->sco_event_ring.ring_id = BCM4377_EVENT_RING_SCO; in bcm4377_prepare_rings()
1701 bcm4377->sco_event_ring.payload_size = MAX_SCO_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1702 bcm4377->sco_event_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1703 bcm4377->sco_event_ring.transfer_rings = BIT(BCM4377_XFER_RING_SCO_D2H); in bcm4377_prepare_rings()
1705 bcm4377->control_h2d_ring.ring_id = BCM4377_XFER_RING_CONTROL; in bcm4377_prepare_rings()
1706 bcm4377->control_h2d_ring.doorbell = BCM4377_DOORBELL_CONTROL; in bcm4377_prepare_rings()
1707 bcm4377->control_h2d_ring.payload_size = BCM4377_CONTROL_MSG_SIZE; in bcm4377_prepare_rings()
1708 bcm4377->control_h2d_ring.completion_ring = BCM4377_ACK_RING_CONTROL; in bcm4377_prepare_rings()
1709 bcm4377->control_h2d_ring.allow_wait = true; in bcm4377_prepare_rings()
1710 bcm4377->control_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1712 bcm4377->hci_h2d_ring.ring_id = BCM4377_XFER_RING_HCI_H2D; in bcm4377_prepare_rings()
1713 bcm4377->hci_h2d_ring.doorbell = BCM4377_DOORBELL_HCI_H2D; in bcm4377_prepare_rings()
1714 bcm4377->hci_h2d_ring.payload_size = MAX_EVENT_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1715 bcm4377->hci_h2d_ring.completion_ring = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1716 bcm4377->hci_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1718 bcm4377->hci_d2h_ring.ring_id = BCM4377_XFER_RING_HCI_D2H; in bcm4377_prepare_rings()
1719 bcm4377->hci_d2h_ring.doorbell = BCM4377_DOORBELL_HCI_D2H; in bcm4377_prepare_rings()
1720 bcm4377->hci_d2h_ring.completion_ring = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1721 bcm4377->hci_d2h_ring.virtual = true; in bcm4377_prepare_rings()
1722 bcm4377->hci_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1724 bcm4377->sco_h2d_ring.ring_id = BCM4377_XFER_RING_SCO_H2D; in bcm4377_prepare_rings()
1725 bcm4377->sco_h2d_ring.doorbell = BCM4377_DOORBELL_SCO; in bcm4377_prepare_rings()
1726 bcm4377->sco_h2d_ring.payload_size = MAX_SCO_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1727 bcm4377->sco_h2d_ring.completion_ring = BCM4377_ACK_RING_SCO; in bcm4377_prepare_rings()
1728 bcm4377->sco_h2d_ring.sync = true; in bcm4377_prepare_rings()
1729 bcm4377->sco_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1731 bcm4377->sco_d2h_ring.ring_id = BCM4377_XFER_RING_SCO_D2H; in bcm4377_prepare_rings()
1732 bcm4377->sco_d2h_ring.doorbell = BCM4377_DOORBELL_SCO; in bcm4377_prepare_rings()
1733 bcm4377->sco_d2h_ring.completion_ring = BCM4377_EVENT_RING_SCO; in bcm4377_prepare_rings()
1734 bcm4377->sco_d2h_ring.virtual = true; in bcm4377_prepare_rings()
1735 bcm4377->sco_d2h_ring.sync = true; in bcm4377_prepare_rings()
1736 bcm4377->sco_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1742 bcm4377->acl_h2d_ring.ring_id = BCM4377_XFER_RING_ACL_H2D; in bcm4377_prepare_rings()
1743 bcm4377->acl_h2d_ring.doorbell = BCM4377_DOORBELL_ACL_H2D; in bcm4377_prepare_rings()
1744 bcm4377->acl_h2d_ring.mapped_payload_size = MAX_ACL_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1745 bcm4377->acl_h2d_ring.completion_ring = BCM4377_ACK_RING_HCI_ACL; in bcm4377_prepare_rings()
1746 bcm4377->acl_h2d_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1752 bcm4377->acl_d2h_ring.ring_id = BCM4377_XFER_RING_ACL_D2H; in bcm4377_prepare_rings()
1753 bcm4377->acl_d2h_ring.doorbell = BCM4377_DOORBELL_ACL_D2H; in bcm4377_prepare_rings()
1754 bcm4377->acl_d2h_ring.completion_ring = BCM4377_EVENT_RING_HCI_ACL; in bcm4377_prepare_rings()
1755 bcm4377->acl_d2h_ring.d2h_buffers_only = true; in bcm4377_prepare_rings()
1756 bcm4377->acl_d2h_ring.mapped_payload_size = MAX_ACL_PAYLOAD_SIZE; in bcm4377_prepare_rings()
1757 bcm4377->acl_d2h_ring.n_entries = BCM4377_RING_N_ENTRIES; in bcm4377_prepare_rings()
1761 * and only devres-managed allocations are used in bcm4377_prepare_rings()
1763 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->control_h2d_ring); in bcm4377_prepare_rings()
1766 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->hci_h2d_ring); in bcm4377_prepare_rings()
1769 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->hci_d2h_ring); in bcm4377_prepare_rings()
1772 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->sco_h2d_ring); in bcm4377_prepare_rings()
1775 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->sco_d2h_ring); in bcm4377_prepare_rings()
1778 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->acl_h2d_ring); in bcm4377_prepare_rings()
1781 ret = bcm4377_alloc_transfer_ring(bcm4377, &bcm4377->acl_d2h_ring); in bcm4377_prepare_rings()
1786 &bcm4377->control_ack_ring); in bcm4377_prepare_rings()
1790 &bcm4377->hci_acl_ack_ring); in bcm4377_prepare_rings()
1794 &bcm4377->hci_acl_event_ring); in bcm4377_prepare_rings()
1797 ret = bcm4377_alloc_completion_ring(bcm4377, &bcm4377->sco_ack_ring); in bcm4377_prepare_rings()
1800 ret = bcm4377_alloc_completion_ring(bcm4377, &bcm4377->sco_event_ring); in bcm4377_prepare_rings()
1804 dev_dbg(&bcm4377->pdev->dev, "all rings allocated and prepared\n"); in bcm4377_prepare_rings()
1817 bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE); in bcm4377_boot()
1818 rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS); in bcm4377_boot()
1821 dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n", in bcm4377_boot()
1823 return -EINVAL; in bcm4377_boot()
1827 dev_err(&bcm4377->pdev->dev, "RTI status is %d and not 0\n", in bcm4377_boot()
1829 return -EINVAL; in bcm4377_boot()
1834 dev_err(&bcm4377->pdev->dev, "Failed to load firmware\n"); in bcm4377_boot()
1835 return -ENOENT; in bcm4377_boot()
1838 bfr = dma_alloc_coherent(&bcm4377->pdev->dev, fw->size, &fw_dma, in bcm4377_boot()
1841 ret = -ENOMEM; in bcm4377_boot()
1845 memcpy(bfr, fw->data, fw->size); in bcm4377_boot()
1847 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_LO); in bcm4377_boot()
1848 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_HI); in bcm4377_boot()
1850 bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE); in bcm4377_boot()
1852 iowrite32(lower_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_LO); in bcm4377_boot()
1853 iowrite32(upper_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_HI); in bcm4377_boot()
1854 iowrite32(fw->size, bcm4377->bar2 + BCM4377_BAR2_FW_SIZE); in bcm4377_boot()
1855 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL); in bcm4377_boot()
1857 dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n"); in bcm4377_boot()
1859 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_boot()
1862 ret = -ETIMEDOUT; in bcm4377_boot()
1868 if (bcm4377->bootstage != 2) { in bcm4377_boot()
1869 dev_err(&bcm4377->pdev->dev, "boostage %d != 2\n", in bcm4377_boot()
1870 bcm4377->bootstage); in bcm4377_boot()
1871 ret = -ENXIO; in bcm4377_boot()
1875 dev_dbg(&bcm4377->pdev->dev, "firmware has booted (stage = %x)\n", in bcm4377_boot()
1876 bcm4377->bootstage); in bcm4377_boot()
1880 dma_free_coherent(&bcm4377->pdev->dev, fw->size, bfr, fw_dma); in bcm4377_boot()
1890 dev_dbg(&bcm4377->pdev->dev, "starting RTI\n"); in bcm4377_setup_rti()
1891 iowrite32(1, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL); in bcm4377_setup_rti()
1893 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_setup_rti()
1896 dev_err(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1898 return -ETIMEDOUT; in bcm4377_setup_rti()
1903 if (bcm4377->rti_status != 1) { in bcm4377_setup_rti()
1904 dev_err(&bcm4377->pdev->dev, "RTI did not ack state 1 (%d)\n", in bcm4377_setup_rti()
1905 bcm4377->rti_status); in bcm4377_setup_rti()
1906 return -ENODEV; in bcm4377_setup_rti()
1908 dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n"); in bcm4377_setup_rti()
1911 iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_LO); in bcm4377_setup_rti()
1912 iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_HI); in bcm4377_setup_rti()
1914 bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_SIZE); in bcm4377_setup_rti()
1917 iowrite32(lower_32_bits(bcm4377->ctx_dma), in bcm4377_setup_rti()
1918 bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_LO); in bcm4377_setup_rti()
1919 iowrite32(upper_32_bits(bcm4377->ctx_dma), in bcm4377_setup_rti()
1920 bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_HI); in bcm4377_setup_rti()
1921 iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL); in bcm4377_setup_rti()
1923 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, in bcm4377_setup_rti()
1926 dev_err(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1928 return -ETIMEDOUT; in bcm4377_setup_rti()
1933 if (bcm4377->rti_status != 2) { in bcm4377_setup_rti()
1934 dev_err(&bcm4377->pdev->dev, "RTI did not ack state 2 (%d)\n", in bcm4377_setup_rti()
1935 bcm4377->rti_status); in bcm4377_setup_rti()
1936 return -ENODEV; in bcm4377_setup_rti()
1939 dev_dbg(&bcm4377->pdev->dev, in bcm4377_setup_rti()
1941 bcm4377->control_ack_ring.enabled = true; in bcm4377_setup_rti()
1951 if (len >= sizeof(bcm4377->vendor)) in bcm4377_parse_otp_board_params()
1952 return -EINVAL; in bcm4377_parse_otp_board_params()
1954 strscpy(bcm4377->vendor, val, len + 1); in bcm4377_parse_otp_board_params()
1965 if (len >= sizeof(bcm4377->stepping)) in bcm4377_parse_otp_chip_params()
1966 return -EINVAL; in bcm4377_parse_otp_chip_params()
1969 bcm4377->stepping[idx] = tolower(val[idx]); in bcm4377_parse_otp_chip_params()
1974 len--; in bcm4377_parse_otp_chip_params()
1977 bcm4377->stepping[idx] = '\0'; in bcm4377_parse_otp_chip_params()
1994 return -EINVAL; in bcm4377_parse_otp_str()
1998 len = end - p; in bcm4377_parse_otp_str()
2001 if (len > (BCM4377_OTP_MAX_PARAM_LEN - 1)) in bcm4377_parse_otp_str()
2002 return -EINVAL; in bcm4377_parse_otp_str()
2014 ret = -EINVAL; in bcm4377_parse_otp_str()
2036 /* 4-byte header and two empty strings */ in bcm4377_parse_otp_sys_vendor()
2038 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2041 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2046 idx += strnlen(chip_params, size - idx) + 1; in bcm4377_parse_otp_sys_vendor()
2048 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2053 idx += strnlen(board_params, size - idx); in bcm4377_parse_otp_sys_vendor()
2055 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2057 /* At this point both strings are guaranteed NUL-terminated */ in bcm4377_parse_otp_sys_vendor()
2058 dev_dbg(&bcm4377->pdev->dev, in bcm4377_parse_otp_sys_vendor()
2072 if (!bcm4377->stepping[0] || !bcm4377->vendor[0]) in bcm4377_parse_otp_sys_vendor()
2073 return -EINVAL; in bcm4377_parse_otp_sys_vendor()
2075 dev_dbg(&bcm4377->pdev->dev, "OTP: stepping=%s, vendor=%s\n", in bcm4377_parse_otp_sys_vendor()
2076 bcm4377->stepping, bcm4377->vendor); in bcm4377_parse_otp_sys_vendor()
2084 int ret = -ENOENT; in bcm4377_parse_otp()
2088 return -ENOMEM; in bcm4377_parse_otp()
2091 otp[i] = ioread8(bcm4377->bar0 + bcm4377->hw->otp_offset + i); in bcm4377_parse_otp()
2094 while (i < (BCM4377_OTP_SIZE - 1)) { in bcm4377_parse_otp()
2106 dev_dbg(&bcm4377->pdev->dev, in bcm4377_parse_otp()
2112 dev_dbg(&bcm4377->pdev->dev, "OTP @ 0x%x (%d): CIS", i, in bcm4377_parse_otp()
2116 dev_dbg(&bcm4377->pdev->dev, "OTP @ 0x%x (%d): unknown", in bcm4377_parse_otp()
2133 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2135 bcm4377->hw->bar0_window1); in bcm4377_init_cfg()
2139 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2141 bcm4377->hw->bar0_window2); in bcm4377_init_cfg()
2146 bcm4377->pdev, BCM4377_PCIECFG_BAR0_CORE2_WINDOW1, in bcm4377_init_cfg()
2151 if (bcm4377->hw->has_bar0_core2_window2) { in bcm4377_init_cfg()
2152 ret = pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2154 bcm4377->hw->bar0_core2_window2); in bcm4377_init_cfg()
2159 ret = pci_write_config_dword(bcm4377->pdev, BCM4377_PCIECFG_BAR2_WINDOW, in bcm4377_init_cfg()
2164 ret = pci_read_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2169 if (bcm4377->hw->clear_pciecfg_subsystem_ctrl_bit19) in bcm4377_init_cfg()
2173 return pci_write_config_dword(bcm4377->pdev, in bcm4377_init_cfg()
2182 if (board_type_dmi_id && board_type_dmi_id->driver_data) { in bcm4377_probe_dmi()
2183 bcm4377->board_type = board_type_dmi_id->driver_data; in bcm4377_probe_dmi()
2184 dev_dbg(&bcm4377->pdev->dev, in bcm4377_probe_dmi()
2186 bcm4377->board_type); in bcm4377_probe_dmi()
2194 struct device_node *np = bcm4377->pdev->dev.of_node; in bcm4377_probe_of()
2200 ret = of_property_read_string(np, "brcm,board-type", in bcm4377_probe_of()
2201 &bcm4377->board_type); in bcm4377_probe_of()
2203 dev_err(&bcm4377->pdev->dev, "no brcm,board-type property\n"); in bcm4377_probe_of()
2207 bcm4377->taurus_beamforming_cal_blob = in bcm4377_probe_of()
2208 of_get_property(np, "brcm,taurus-bf-cal-blob", in bcm4377_probe_of()
2209 &bcm4377->taurus_beamforming_cal_size); in bcm4377_probe_of()
2210 if (!bcm4377->taurus_beamforming_cal_blob) { in bcm4377_probe_of()
2211 dev_err(&bcm4377->pdev->dev, in bcm4377_probe_of()
2212 "no brcm,taurus-bf-cal-blob property\n"); in bcm4377_probe_of()
2213 return -ENOENT; in bcm4377_probe_of()
2215 bcm4377->taurus_cal_blob = of_get_property(np, "brcm,taurus-cal-blob", in bcm4377_probe_of()
2216 &bcm4377->taurus_cal_size); in bcm4377_probe_of()
2217 if (!bcm4377->taurus_cal_blob) { in bcm4377_probe_of()
2218 dev_err(&bcm4377->pdev->dev, in bcm4377_probe_of()
2219 "no brcm,taurus-cal-blob property\n"); in bcm4377_probe_of()
2220 return -ENOENT; in bcm4377_probe_of()
2228 pci_disable_link_state(bcm4377->pdev, in bcm4377_disable_aspm()
2236 pcie_capability_clear_word(bcm4377->pdev, PCI_EXP_LNKCTL, in bcm4377_disable_aspm()
2261 ret = dma_set_mask_and_coherent(&pdev->dev, BCM4377_DMA_MASK); in bcm4377_probe()
2265 bcm4377 = devm_kzalloc(&pdev->dev, sizeof(*bcm4377), GFP_KERNEL); in bcm4377_probe()
2267 return -ENOMEM; in bcm4377_probe()
2269 bcm4377->pdev = pdev; in bcm4377_probe()
2270 bcm4377->hw = &bcm4377_hw_variants[id->driver_data]; in bcm4377_probe()
2271 init_completion(&bcm4377->event); in bcm4377_probe()
2287 if (!bcm4377->board_type) { in bcm4377_probe()
2288 dev_err(&pdev->dev, "unable to determine board type\n"); in bcm4377_probe()
2289 return -ENODEV; in bcm4377_probe()
2292 if (bcm4377->hw->disable_aspm) in bcm4377_probe()
2298 &pdev->dev, in bcm4377_probe()
2319 bcm4377->bar0 = pcim_iomap(pdev, 0, 0); in bcm4377_probe()
2320 if (!bcm4377->bar0) in bcm4377_probe()
2321 return -EBUSY; in bcm4377_probe()
2322 bcm4377->bar2 = pcim_iomap(pdev, 2, 0); in bcm4377_probe()
2323 if (!bcm4377->bar2) in bcm4377_probe()
2324 return -EBUSY; in bcm4377_probe()
2328 dev_err(&pdev->dev, "Reading OTP failed with %d\n", ret); in bcm4377_probe()
2339 return -ENODEV; in bcm4377_probe()
2340 ret = devm_add_action_or_reset(&pdev->dev, bcm4377_pci_free_irq_vectors, in bcm4377_probe()
2347 return -ENODEV; in bcm4377_probe()
2349 ret = devm_request_irq(&pdev->dev, irq, bcm4377_irq, 0, "bcm4377", in bcm4377_probe()
2356 return -ENOMEM; in bcm4377_probe()
2357 ret = devm_add_action_or_reset(&pdev->dev, bcm4377_hci_free_dev, hdev); in bcm4377_probe()
2361 bcm4377->hdev = hdev; in bcm4377_probe()
2363 hdev->bus = HCI_PCI; in bcm4377_probe()
2364 hdev->open = bcm4377_hci_open; in bcm4377_probe()
2365 hdev->close = bcm4377_hci_close; in bcm4377_probe()
2366 hdev->send = bcm4377_hci_send_frame; in bcm4377_probe()
2367 hdev->set_bdaddr = bcm4377_hci_set_bdaddr; in bcm4377_probe()
2368 hdev->setup = bcm4377_hci_setup; in bcm4377_probe()
2370 if (bcm4377->hw->broken_mws_transport_config) in bcm4377_probe()
2371 set_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &hdev->quirks); in bcm4377_probe()
2372 if (bcm4377->hw->broken_ext_scan) in bcm4377_probe()
2373 set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); in bcm4377_probe()
2374 if (bcm4377->hw->broken_le_coded) in bcm4377_probe()
2375 set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks); in bcm4377_probe()
2379 SET_HCIDEV_DEV(hdev, &pdev->dev); in bcm4377_probe()
2392 return devm_add_action_or_reset(&pdev->dev, bcm4377_hci_unregister_dev, in bcm4377_probe()
2401 ret = hci_suspend_dev(bcm4377->hdev); in bcm4377_suspend()
2406 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_suspend()
2416 bcm4377->bar0 + BCM4377_BAR0_SLEEP_CONTROL); in bcm4377_resume()
2418 return hci_resume_dev(bcm4377->hdev); in bcm4377_resume()