diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
| commit | 034dd340b08be1f2f0477ad16131d609f9dbd53c (patch) | |
| tree | 2536f4b2d7893ccd916b5abdf3c454ad6edc03c2 /drivers/bluetooth/btintel_pcie.h | |
| download | linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.tar.gz linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.zip | |
Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt:
- Fix error output of boot instance creation failure
Currently if a boot instance creation fails, instead of printing out
the name of the instance that failed, it prints "(null)". That is
because it prints "cur_str" that had already been processed by
strsep(). Print the saved name instead.
While at it, print the error code of the failure.
- Fix use-after-free for same named historgrams
Histograms can be named so that they can be used in multiple events.
But if the named histogram has a variable attached, the second event
that uses the named histogram which duplicates it and needs to free
the original after duplication leaves the old variable in place and
still visible. If another histogram uses than variable, it will use
the stale one which will try to reference the freed duplicate
histogram and crash the kernel.
Free the duplicate variables along with the duplicated histogram
data.
- Check return value of kthread_run() in event self test
The events self tests uses a kthread for testing but does not check
if it succeeded in creating a kthread. If the kthread creation were
to fail, the code will still try to call kthread_stop() on the error
returned.
- Fix race between reading trace_pipe and updating subbuffer size
If a user is reading the trace_pipe file at the same time they update
the ring buffer sub-buffer size, can cause the trace_pipe read to
read stale data. Add trace_access_lock() around updating the ring
buffer sub-buffer size.
- Fix eventfs_inode on failure path in creation of the events directory
In the creation of the "events" directory, if after allocating the
eventfs_inode a failure is detected, it calls cleanup_ei() which
calls free_ei(). The free_ei() will test if eventfs_inode being freed
has no children. It is a bug if it does. But on the failure case of
the creation of the "events" directory, the children lists have not
yet been initialized and the free will trigger a warning because
list_empty() on an uninitialized list returns false.
Move the initialization into init_ei() where it makes more sense and
makes sure that a created eventfs_inode has its lists initialized
upon creation.
- Check return value of kthread_run() in ftrace direct sample code
The sample code that shows how to use the ftrace direct calls does
not test the return of kthread_run() to see if it succeeds. Return a
failure if the kthread_run() doesn't succeed.
- Clear user events state on fork in case of alloc failure
On fork, the child gets a pointer to the parent's user events state.
It makes a copy of it then updates the child's pointer to it. But if
the allocation fails, the duplication function leaves the child with
a pointer to its parent's descriptor. When the child cleans up its
data, it will free the parent's descriptor while the parent is still
using it.
In the duplication function, set the child's user_event_mm to NULL
before testing if the allocation succeeded, and when it exits it will
not free the parent's descriptor.
- Fix retry exhaustion in simple ring buffer reader swap
simple_ring_buffer_swap_reader_page() starts with retry set to 8 and
post-decrements it only after a failed link replacement. On the final
attempt, a successful replacement leaves retry at zero, while a
failed replacement leaves it at -1.
But the check for success expects the retry value to be non-zero and
exits with an error on zero. This is the opposite result. Fix it.
- Fail nicely when the remote swap_reader_page() returns an error
Currently, if the swap_reader_page() of a remote buffer fails, it
triggers a WARN_ON_ONCE() and continues normally. Instead, have it
exit with an error and a pr_warn() print instead of a full WARNING.
* tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
ring-buffer: Stop remote reader update when page swap fails
tracing: Fix retry exhaustion in simple ring buffer reader swap
tracing/user_events: Clear copied tracing state before fork duplication
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify
eventfs: Initialize ei->children and ei->list in init_ei()
tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
tracing: Fix crash passing ERR_PTR to kthread_stop()
tracing: Fix use-after-free with same-name named triggers
tracing: Fix logged instance name on creation failure
Diffstat (limited to 'drivers/bluetooth/btintel_pcie.h')
| -rw-r--r-- | drivers/bluetooth/btintel_pcie.h | 588 |
1 files changed, 588 insertions, 0 deletions
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h new file mode 100644 index 000000000..749369b24 --- /dev/null +++ b/drivers/bluetooth/btintel_pcie.h @@ -0,0 +1,588 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * + * Bluetooth support for Intel PCIe devices + * + * Copyright (C) 2024 Intel Corporation + */ + +/* Control and Status Register(BTINTEL_PCIE_CSR) */ +#define BTINTEL_PCIE_CSR_BASE (0x000) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_REG (BTINTEL_PCIE_CSR_BASE + 0x024) +#define BTINTEL_PCIE_CSR_HW_REV_REG (BTINTEL_PCIE_CSR_BASE + 0x028) +#define BTINTEL_PCIE_CSR_RF_ID_REG (BTINTEL_PCIE_CSR_BASE + 0x09C) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_REG (BTINTEL_PCIE_CSR_BASE + 0x108) +#define BTINTEL_PCIE_CSR_IPC_CONTROL_REG (BTINTEL_PCIE_CSR_BASE + 0x10C) +#define BTINTEL_PCIE_CSR_IPC_STATUS_REG (BTINTEL_PCIE_CSR_BASE + 0x110) +#define BTINTEL_PCIE_CSR_IPC_SLEEP_CTL_REG (BTINTEL_PCIE_CSR_BASE + 0x114) +#define BTINTEL_PCIE_CSR_CI_ADDR_LSB_REG (BTINTEL_PCIE_CSR_BASE + 0x118) +#define BTINTEL_PCIE_CSR_CI_ADDR_MSB_REG (BTINTEL_PCIE_CSR_BASE + 0x11C) +#define BTINTEL_PCIE_CSR_IMG_RESPONSE_REG (BTINTEL_PCIE_CSR_BASE + 0x12C) +#define BTINTEL_PCIE_CSR_MBOX_1_REG (BTINTEL_PCIE_CSR_BASE + 0x170) +#define BTINTEL_PCIE_CSR_MBOX_2_REG (BTINTEL_PCIE_CSR_BASE + 0x174) +#define BTINTEL_PCIE_CSR_MBOX_3_REG (BTINTEL_PCIE_CSR_BASE + 0x178) +#define BTINTEL_PCIE_CSR_MBOX_4_REG (BTINTEL_PCIE_CSR_BASE + 0x17C) +#define BTINTEL_PCIE_CSR_MBOX_STATUS_REG (BTINTEL_PCIE_CSR_BASE + 0x180) +#define BTINTEL_PCIE_PRPH_DEV_ADDR_REG (BTINTEL_PCIE_CSR_BASE + 0x440) +#define BTINTEL_PCIE_PRPH_DEV_RD_REG (BTINTEL_PCIE_CSR_BASE + 0x458) +#define BTINTEL_PCIE_CSR_HBUS_TARG_WRPTR (BTINTEL_PCIE_CSR_BASE + 0x460) + +/* BTINTEL_PCIE_CSR Function Control Register */ +#define BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA (BIT(0)) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT (BIT(6)) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT (BIT(7)) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS (BIT(20)) + +#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ (BIT(21)) + +#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_STS (BIT(28)) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON (BIT(29)) +#define BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET (BIT(31)) + +/* Value for BTINTEL_PCIE_CSR_BOOT_STAGE register */ +#define BTINTEL_PCIE_CSR_BOOT_STAGE_ROM (BIT(0)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_IML (BIT(1)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW (BIT(2)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_ROM_LOCKDOWN (BIT(10)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_IML_LOCKDOWN (BIT(11)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_WARNING (BIT(12)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER (BIT(13)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED (BIT(14)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON (BIT(16)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_ALIVE (BIT(23)) +#define BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY (BIT(24)) + +/* Registers for MSI-X */ +#define BTINTEL_PCIE_CSR_MSIX_BASE (0x2000) +#define BTINTEL_PCIE_CSR_MSIX_FH_INT_CAUSES (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0800) +#define BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0804) +#define BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0808) +#define BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK (BTINTEL_PCIE_CSR_MSIX_BASE + 0x080C) +#define BTINTEL_PCIE_CSR_MSIX_AUTOMASK_ST (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0810) +#define BTINTEL_PCIE_CSR_MSIX_AUTOMASK_EN (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0814) +#define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880) +#define BTINTEL_PCIE_CSR_MSIX_IVAR(cause) (BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause)) + +/* IOSF Debug Register */ +#define BTINTEL_PCIE_DBGC_BASE_ADDR (0xf3800300) +#define BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS (BTINTEL_PCIE_DBGC_BASE_ADDR + 0x1C) +#define BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND (BTINTEL_PCIE_DBGC_BASE_ADDR + 0x2C) + +#define BTINTEL_PCIE_DBGC_BASE_ADDR_SCP (0xf0d5d500) +#define BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS_SCP (BTINTEL_PCIE_DBGC_BASE_ADDR_SCP + 0x1C) +#define BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND_SCP (BTINTEL_PCIE_DBGC_BASE_ADDR_SCP + 0x2C) + +#define BTINTEL_PCIE_DBG_IDX_BIT_MASK 0x0F +#define BTINTEL_PCIE_DBGC_DBG_BUF_IDX(data) (((data) >> 24) & BTINTEL_PCIE_DBG_IDX_BIT_MASK) +#define BTINTEL_PCIE_DBG_OFFSET_BIT_MASK 0xFFFFFF + +/* The DRAM buffer count, each buffer size, and + * fragment buffer size + */ +#define BTINTEL_PCIE_DBGC_BUFFER_COUNT 16 +#define BTINTEL_PCIE_DBGC_BUFFER_SIZE (256 * 1024) /* 256 KB */ + +#define BTINTEL_PCIE_DBGC_FRAG_VERSION 1 +#define BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT BTINTEL_PCIE_DBGC_BUFFER_COUNT + +/* Magic number(4), version(4), size of payload length(4) */ +#define BTINTEL_PCIE_DBGC_FRAG_HEADER_SIZE 12 + +/* Num of alloc Dbg buff (4) + (LSB(4), MSB(4), Size(4)) for each buffer */ +#define BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE 196 + +/* Causes for the FH register interrupts */ +enum msix_fh_int_causes { + BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0 = BIT(0), /* cause 0 */ + BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1 = BIT(1), /* cause 1 */ +}; + +/* Causes for the HW register interrupts */ +enum msix_hw_int_causes { + BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0 = BIT(0), /* cause 32 */ + BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1 = BIT(1), /* cause 33 */ + BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP = BIT(3), /* cause 35 */ + BTINTEL_PCIE_MSIX_HW_INT_CAUSES_FWTRIG = BIT(5), /* cause 37 */ +}; + +/* PCIe device states + * Host-Device interface is active + * Host-Device interface is inactive(as reflected by IPC_SLEEP_CONTROL_CSR_AD) + * Host-Device interface is inactive(as reflected by IPC_SLEEP_CONTROL_CSR_AD) + */ +enum { + BTINTEL_PCIE_STATE_D0 = 0, + BTINTEL_PCIE_STATE_D3_HOT = 2, + BTINTEL_PCIE_STATE_D3_COLD = 3, +}; + +enum { + BTINTEL_PCIE_CORE_HALTED, + BTINTEL_PCIE_COREDUMP_INPROGRESS, + BTINTEL_PCIE_FWTRIGGER_DUMP_INPROGRESS, + BTINTEL_PCIE_RECOVERY_IN_PROGRESS, + BTINTEL_PCIE_SETUP_DONE +}; + +enum btintel_pcie_tlv_type { + BTINTEL_CNVI_BT, + BTINTEL_WRITE_PTR, + BTINTEL_WRAP_CTR, + BTINTEL_TRIGGER_REASON, + BTINTEL_FW_SHA, + BTINTEL_CNVR_TOP, + BTINTEL_CNVI_TOP, + BTINTEL_DUMP_TIME, + BTINTEL_FW_BUILD, + BTINTEL_VENDOR, + BTINTEL_DRIVER, + BTINTEL_EVENT_TYPE, + BTINTEL_EVENT_ID +}; + +/* causes for the MBOX interrupts */ +enum msix_mbox_int_causes { + BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX1 = BIT(0), /* cause MBOX1 */ + BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX2 = BIT(1), /* cause MBOX2 */ + BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX3 = BIT(2), /* cause MBOX3 */ + BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX4 = BIT(3), /* cause MBOX4 */ +}; + +enum btintel_pcie_reset_type { + BTINTEL_PCIE_IOSF_PRR_FLR = 0, + BTINTEL_PCIE_IOSF_PRR_PLDR = 1, +}; + +#define BTINTEL_PCIE_MSIX_NON_AUTO_CLEAR_CAUSE BIT(7) + +/* Minimum and Maximum number of MSI-X Vector + * Intel Bluetooth PCIe support only 1 vector + */ +#define BTINTEL_PCIE_MSIX_VEC_MAX 1 +#define BTINTEL_PCIE_MSIX_VEC_MIN 1 + +/* Default poll time for MAC access during init */ +#define BTINTEL_DEFAULT_MAC_ACCESS_TIMEOUT_US 200000 + +/* Default interrupt timeout in msec */ +#define BTINTEL_DEFAULT_INTR_TIMEOUT_MS 3000 + +#define BTINTEL_PCIE_DX_TRANSITION_MAX_RETRIES 3 + +/* The number of descriptors in TX queues */ +#define BTINTEL_PCIE_TX_DESCS_COUNT 32 + +/* The number of descriptors in RX queues */ +#define BTINTEL_PCIE_RX_DESCS_COUNT 64 + +/* Number of Queue for TX and RX + * It indicates the index of the IA(Index Array) + */ +enum { + BTINTEL_PCIE_TXQ_NUM = 0, + BTINTEL_PCIE_RXQ_NUM = 1, + BTINTEL_PCIE_NUM_QUEUES = 2, +}; + +/* The size of DMA buffer for TX and RX in bytes */ +#define BTINTEL_PCIE_BUFFER_SIZE 4096 + +#define BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS 500 + +/* Doorbell vector for TFD */ +#define BTINTEL_PCIE_TX_DB_VEC 0 + +/* Doorbell vector for FRBD */ +#define BTINTEL_PCIE_RX_DB_VEC 513 + +/* RBD buffer size mapping */ +#define BTINTEL_PCIE_RBD_SIZE_4K 0x04 + +/* + * Struct for Context Information (v2) + * + * All members are write-only for host and read-only for device. + * + * @version: Version of context information + * @size: Size of context information + * @config: Config with which host wants peripheral to execute + * Subset of capability register published by device + * @addr_tr_hia: Address of TR Head Index Array + * @addr_tr_tia: Address of TR Tail Index Array + * @addr_cr_hia: Address of CR Head Index Array + * @addr_cr_tia: Address of CR Tail Index Array + * @num_tr_ia: Number of entries in TR Index Arrays + * @num_cr_ia: Number of entries in CR Index Arrays + * @rbd_siz: RBD Size { 0x4=4K } + * @addr_tfdq: Address of TFD Queue(tx) + * @addr_urbdq0: Address of URBD Queue(tx) + * @num_tfdq: Number of TFD in TFD Queue(tx) + * @num_urbdq0: Number of URBD in URBD Queue(tx) + * @tfdq_db_vec: Queue number of TFD + * @urbdq0_db_vec: Queue number of URBD + * @addr_frbdq: Address of FRBD Queue(rx) + * @addr_urbdq1: Address of URBD Queue(rx) + * @num_frbdq: Number of FRBD in FRBD Queue(rx) + * @frbdq_db_vec: Queue number of FRBD + * @num_urbdq1: Number of URBD in URBD Queue(rx) + * @urbdq_db_vec: Queue number of URBDQ1 + * @tr_msi_vec: Transfer Ring MSI-X Vector + * @cr_msi_vec: Completion Ring MSI-X Vector + * @dbgc_addr: DBGC first fragment address + * @dbgc_size: DBGC buffer size + * @early_enable: Enarly debug enable + * @dbg_output_mode: Debug output mode + * Bit[4] DBGC O/P { 0=SRAM, 1=DRAM(not relevant for NPK) } + * Bit[5] DBGC I/P { 0=BDBG, 1=DBGI } + * Bits[6:7] DBGI O/P(relevant if bit[5] = 1) + * 0=BT DBGC, 1=WiFi DBGC, 2=NPK } + * @dbg_preset: Debug preset + * @ext_addr: Address of context information extension + * @ext_size: Size of context information part + * + * Total 38 DWords + */ +struct ctx_info { + u16 version; + u16 size; + u32 config; + u32 reserved_dw02; + u32 reserved_dw03; + u64 addr_tr_hia; + u64 addr_tr_tia; + u64 addr_cr_hia; + u64 addr_cr_tia; + u16 num_tr_ia; + u16 num_cr_ia; + u32 rbd_size:4, + reserved_dw13:28; + u64 addr_tfdq; + u64 addr_urbdq0; + u16 num_tfdq; + u16 num_urbdq0; + u16 tfdq_db_vec; + u16 urbdq0_db_vec; + u64 addr_frbdq; + u64 addr_urbdq1; + u16 num_frbdq; + u16 frbdq_db_vec; + u16 num_urbdq1; + u16 urbdq_db_vec; + u16 tr_msi_vec; + u16 cr_msi_vec; + u32 reserved_dw27; + u64 dbgc_addr; + u32 dbgc_size; + u32 early_enable:1, + reserved_dw31:3, + dbg_output_mode:4, + dbg_preset:8, + reserved2_dw31:16; + u64 ext_addr; + u32 ext_size; + u32 test_param; + u32 reserved_dw36; + u32 reserved_dw37; +} __packed; + +/* Transfer Descriptor for TX + * @type: Not in use. Set to 0x0 + * @size: Size of data in the buffer + * @addr: DMA Address of buffer + */ +struct tfd { + u8 type; + u16 size; + u8 reserved; + u64 addr; + u32 reserved1; +} __packed; + +/* URB Descriptor for TX + * @tfd_index: Index of TFD in TFDQ + 1 + * @num_txq: Queue index of TFD Queue + * @cmpl_count: Completion count. Always 0x01 + * @immediate_cmpl: Immediate completion flag: Always 0x01 + */ +struct urbd0 { + u32 tfd_index:16, + num_txq:8, + cmpl_count:4, + reserved:3, + immediate_cmpl:1; +} __packed; + +/* FRB Descriptor for RX + * @tag: RX buffer tag (index of RX buffer queue) + * @addr: Address of buffer + */ +struct frbd { + u32 tag:16, + reserved:16; + u32 reserved2; + u64 addr; +} __packed; + +/* URB Descriptor for RX + * @frbd_tag: Tag from FRBD + * @status: Status + */ +struct urbd1 { + u32 frbd_tag:16, + status:1, + reserved:14, + fixed:1; +} __packed; + +/* RFH header in RX packet + * @packet_len: Length of the data in the buffer + * @rxq: RX Queue number + * @cmd_id: Command ID. Not in Use + */ +struct rfh_hdr { + u64 packet_len:16, + rxq:6, + reserved:10, + cmd_id:16, + reserved1:16; +} __packed; + +/* Internal data buffer + * @data: pointer to the data buffer + * @p_addr: physical address of data buffer + */ +struct data_buf { + u8 *data; + dma_addr_t data_p_addr; +}; + +/* Index Array */ +struct ia { + dma_addr_t tr_hia_p_addr; + u16 *tr_hia; + dma_addr_t tr_tia_p_addr; + u16 *tr_tia; + dma_addr_t cr_hia_p_addr; + u16 *cr_hia; + dma_addr_t cr_tia_p_addr; + u16 *cr_tia; +}; + +/* Structure for TX Queue + * @count: Number of descriptors + * @tfds: Array of TFD + * @urbd0s: Array of URBD0 + * @buf: Array of data_buf structure + */ +struct txq { + u16 count; + + dma_addr_t tfds_p_addr; + struct tfd *tfds; + + dma_addr_t urbd0s_p_addr; + struct urbd0 *urbd0s; + + dma_addr_t buf_p_addr; + void *buf_v_addr; + struct data_buf *bufs; +}; + +/* Structure for RX Queue + * @count: Number of descriptors + * @frbds: Array of FRBD + * @urbd1s: Array of URBD1 + * @buf: Array of data_buf structure + */ +struct rxq { + u16 count; + + dma_addr_t frbds_p_addr; + struct frbd *frbds; + + dma_addr_t urbd1s_p_addr; + struct urbd1 *urbd1s; + + dma_addr_t buf_p_addr; + void *buf_v_addr; + struct data_buf *bufs; +}; + +/* Structure for DRAM Buffer + * @count: Number of descriptors + * @buf: Array of data_buf structure + */ +struct btintel_pcie_dbgc { + u16 count; + + void *frag_v_addr; + dma_addr_t frag_p_addr; + u16 frag_size; + + dma_addr_t buf_p_addr; + void *buf_v_addr; + struct data_buf *bufs; +}; + +struct btintel_pcie_dump_header { + const char *driver_name; + u32 cnvi_top; + u32 cnvr_top; + u16 fw_timestamp; + u8 fw_build_type; + u32 fw_build_num; + u32 fw_git_sha1; + u32 cnvi_bt; + u32 write_ptr; + u32 wrap_ctr; + u16 trigger_reason; + int state; + u8 event_type; + u16 event_id; +}; + +/* struct btintel_pcie_data + * @pdev: pci device + * @hdev: hdev device + * @flags: driver state + * @irq_lock: spinlock for MSI-X + * @hci_rx_lock: spinlock for HCI RX flow + * @base_addr: pci base address (from BAR) + * @msix_entries: array of MSI-X entries + * @msix_enabled: true if MSI-X is enabled; + * @alloc_vecs: number of interrupt vectors allocated + * @def_irq: default irq for all causes + * @fh_init_mask: initial unmasked rxq causes + * @hw_init_mask: initial unmaksed hw causes + * @boot_stage_cache: cached value of boot stage register + * @img_resp_cache: cached value of image response register + * @cnvi: CNVi register value + * @cnvr: CNVr register value + * @gp0_received: condition for gp0 interrupt + * @gp0_wait_q: wait_q for gp0 interrupt + * @tx_wait_done: condition for tx interrupt + * @tx_wait_q: wait_q for tx interrupt + * @workqueue: workqueue for RX work + * @rx_skb_q: SKB queue for RX packet + * @rx_work: RX work struct to process the RX packet in @rx_skb_q + * @dump_workqueue: dedicated ordered workqueue serializing the coredump, + * hardware exception, and firmware-trigger dump workers + * @coredump_work: work struct for DRAM trace coredump collection + * @hwexp_work: work struct for hardware exception event read + * @fwtrigger_work: work struct for firmware-triggered diagnostic event read + * @dma_pool: DMA pool for descriptors, index array and ci + * @dma_p_addr: DMA address for pool + * @dma_v_addr: address of pool + * @ci_p_addr: DMA address for CI struct + * @ci: CI struct + * @ia: Index Array struct + * @txq: TX Queue struct + * @rxq: RX Queue struct + * @alive_intr_ctxt: Alive interrupt context + * @pm_sx_event: PM event on which system got suspended + */ +struct btintel_pcie_data { + struct pci_dev *pdev; + struct hci_dev *hdev; + + unsigned long flags; + /* lock used in MSI-X interrupt */ + spinlock_t irq_lock; + /* lock to serialize rx events */ + spinlock_t hci_rx_lock; + + void __iomem *base_addr; + + struct msix_entry msix_entries[BTINTEL_PCIE_MSIX_VEC_MAX]; + bool msix_enabled; + u32 alloc_vecs; + u32 def_irq; + + u32 fh_init_mask; + u32 hw_init_mask; + + u32 boot_stage_cache; + u32 img_resp_cache; + + u32 cnvi; + u32 cnvr; + + bool gp0_received; + wait_queue_head_t gp0_wait_q; + + bool tx_wait_done; + wait_queue_head_t tx_wait_q; + + struct workqueue_struct *workqueue; + struct sk_buff_head rx_skb_q; + struct work_struct rx_work; + struct work_struct reset_work; + + struct workqueue_struct *dump_workqueue; + struct work_struct coredump_work; + struct work_struct hwexp_work; + struct work_struct fwtrigger_work; + + struct dma_pool *dma_pool; + dma_addr_t dma_p_addr; + void *dma_v_addr; + + dma_addr_t ci_p_addr; + struct ctx_info *ci; + struct ia ia; + struct txq txq; + struct rxq rxq; + u32 alive_intr_ctxt; + enum btintel_pcie_reset_type reset_type; + struct btintel_pcie_dbgc dbgc; + struct btintel_pcie_dump_header dmp_hdr; + u8 pm_sx_event; + u32 debug_evt_addr; + u32 debug_evt_size; +}; + +static inline u32 btintel_pcie_rd_reg32(struct btintel_pcie_data *data, + u32 offset) +{ + return ioread32(data->base_addr + offset); +} + +static inline void btintel_pcie_wr_reg8(struct btintel_pcie_data *data, + u32 offset, u8 val) +{ + iowrite8(val, data->base_addr + offset); +} + +static inline void btintel_pcie_wr_reg32(struct btintel_pcie_data *data, + u32 offset, u32 val) +{ + iowrite32(val, data->base_addr + offset); +} + +static inline void btintel_pcie_set_reg_bits(struct btintel_pcie_data *data, + u32 offset, u32 bits) +{ + u32 r; + + r = ioread32(data->base_addr + offset); + r |= bits; + iowrite32(r, data->base_addr + offset); +} + +static inline void btintel_pcie_clr_reg_bits(struct btintel_pcie_data *data, + u32 offset, u32 bits) +{ + u32 r; + + r = ioread32(data->base_addr + offset); + r &= ~bits; + iowrite32(r, data->base_addr + offset); +} + +static inline u32 btintel_pcie_rd_dev_mem(struct btintel_pcie_data *data, + u32 addr) +{ + btintel_pcie_wr_reg32(data, BTINTEL_PCIE_PRPH_DEV_ADDR_REG, addr); + return btintel_pcie_rd_reg32(data, BTINTEL_PCIE_PRPH_DEV_RD_REG); +} + |
