#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)
#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_STOP_MAC_ACCESS_DIS (BIT(22))
#define BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ (BIT(23))
#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))
#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_ERR (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))
#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))
#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_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
#define BTINTEL_PCIE_DBGC_BUFFER_COUNT 16
#define BTINTEL_PCIE_DBGC_BUFFER_SIZE (256 * 1024)
#define BTINTEL_PCIE_DBGC_FRAG_VERSION 1
#define BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT BTINTEL_PCIE_DBGC_BUFFER_COUNT
#define BTINTEL_PCIE_DBGC_FRAG_HEADER_SIZE 12
#define BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE 196
enum msix_fh_int_causes {
BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0 = BIT(0),
BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1 = BIT(1),
};
enum msix_hw_int_causes {
BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0 = BIT(0),
BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1 = BIT(1),
BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP = BIT(3),
};
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_HWEXP_INPROGRESS,
BTINTEL_PCIE_COREDUMP_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,
};
enum msix_mbox_int_causes {
BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX1 = BIT(0),
BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX2 = BIT(1),
BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX3 = BIT(2),
BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX4 = BIT(3),
};
#define BTINTEL_PCIE_MSIX_NON_AUTO_CLEAR_CAUSE BIT(7)
#define BTINTEL_PCIE_MSIX_VEC_MAX 1
#define BTINTEL_PCIE_MSIX_VEC_MIN 1
#define BTINTEL_DEFAULT_MAC_ACCESS_TIMEOUT_US 200000
#define BTINTEL_DEFAULT_INTR_TIMEOUT_MS 3000
#define BTINTEL_PCIE_TX_DESCS_COUNT 32
#define BTINTEL_PCIE_RX_DESCS_COUNT 64
enum {
BTINTEL_PCIE_TXQ_NUM = 0,
BTINTEL_PCIE_RXQ_NUM = 1,
BTINTEL_PCIE_NUM_QUEUES = 2,
};
#define BTINTEL_PCIE_BUFFER_SIZE 4096
#define BTINTEL_PCIE_DMA_POOL_ALIGNMENT 256
#define BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS 500
#define BTINTEL_PCIE_TX_DB_VEC 0
#define BTINTEL_PCIE_RX_DB_VEC 513
#define BTINTEL_PCIE_RBD_SIZE_4K 0x04
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;
struct tfd {
u8 type;
u16 size;
u8 reserved;
u64 addr;
u32 reserved1;
} __packed;
struct urbd0 {
u32 tfd_index:16,
num_txq:8,
cmpl_count:4,
reserved:3,
immediate_cmpl:1;
} __packed;
struct frbd {
u32 tag:16,
reserved:16;
u32 reserved2;
u64 addr;
} __packed;
struct urbd1 {
u32 frbd_tag:16,
status:1,
reserved:14,
fixed:1;
} __packed;
struct rfh_hdr {
u64 packet_len:16,
rxq:6,
reserved:10,
cmd_id:16,
reserved1:16;
} __packed;
struct data_buf {
u8 *data;
dma_addr_t data_p_addr;
};
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;
};
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;
};
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;
};
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;
};
struct btintel_pcie_data {
struct pci_dev *pdev;
struct hci_dev *hdev;
unsigned long flags;
spinlock_t irq_lock;
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 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;
struct btintel_pcie_dbgc dbgc;
struct btintel_pcie_dump_header dmp_hdr;
};
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);
}