162306a36Sopenharmony_ci/* SPDX-License-Identifier: ISC */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc. 462306a36Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef _PCI_H_ 862306a36Sopenharmony_ci#define _PCI_H_ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/interrupt.h> 1162306a36Sopenharmony_ci#include <linux/mutex.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "hw.h" 1462306a36Sopenharmony_ci#include "ce.h" 1562306a36Sopenharmony_ci#include "ahb.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * maximum number of bytes that can be 1962306a36Sopenharmony_ci * handled atomically by DiagRead/DiagWrite 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci#define DIAG_TRANSFER_LIMIT 2048 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct bmi_xfer { 2462306a36Sopenharmony_ci bool tx_done; 2562306a36Sopenharmony_ci bool rx_done; 2662306a36Sopenharmony_ci bool wait_for_resp; 2762306a36Sopenharmony_ci u32 resp_len; 2862306a36Sopenharmony_ci}; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * PCI-specific Target state 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * NOTE: Structure is shared between Host software and Target firmware! 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * Much of this may be of interest to the Host so 3662306a36Sopenharmony_ci * HOST_INTEREST->hi_interconnect_state points here 3762306a36Sopenharmony_ci * (and all members are 32-bit quantities in order to 3862306a36Sopenharmony_ci * facilitate Host access). In particular, Host software is 3962306a36Sopenharmony_ci * required to initialize pipe_cfg_addr and svc_to_pipe_map. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_cistruct pcie_state { 4262306a36Sopenharmony_ci /* Pipe configuration Target address */ 4362306a36Sopenharmony_ci /* NB: ce_pipe_config[CE_COUNT] */ 4462306a36Sopenharmony_ci u32 pipe_cfg_addr; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci /* Service to pipe map Target address */ 4762306a36Sopenharmony_ci /* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */ 4862306a36Sopenharmony_ci u32 svc_to_pipe_map; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* number of MSI interrupts requested */ 5162306a36Sopenharmony_ci u32 msi_requested; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* number of MSI interrupts granted */ 5462306a36Sopenharmony_ci u32 msi_granted; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* Message Signalled Interrupt address */ 5762306a36Sopenharmony_ci u32 msi_addr; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci /* Base data */ 6062306a36Sopenharmony_ci u32 msi_data; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* 6362306a36Sopenharmony_ci * Data for firmware interrupt; 6462306a36Sopenharmony_ci * MSI data for other interrupts are 6562306a36Sopenharmony_ci * in various SoC registers 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_ci u32 msi_fw_intr_data; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci /* PCIE_PWR_METHOD_* */ 7062306a36Sopenharmony_ci u32 power_mgmt_method; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* PCIE_CONFIG_FLAG_* */ 7362306a36Sopenharmony_ci u32 config_flags; 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* PCIE_CONFIG_FLAG definitions */ 7762306a36Sopenharmony_ci#define PCIE_CONFIG_FLAG_ENABLE_L1 0x0000001 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* Per-pipe state. */ 8062306a36Sopenharmony_cistruct ath10k_pci_pipe { 8162306a36Sopenharmony_ci /* Handle of underlying Copy Engine */ 8262306a36Sopenharmony_ci struct ath10k_ce_pipe *ce_hdl; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci /* Our pipe number; facilitates use of pipe_info ptrs. */ 8562306a36Sopenharmony_ci u8 pipe_num; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* Convenience back pointer to hif_ce_state. */ 8862306a36Sopenharmony_ci struct ath10k *hif_ce_state; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci size_t buf_sz; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* protects compl_free and num_send_allowed */ 9362306a36Sopenharmony_ci spinlock_t pipe_lock; 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistruct ath10k_pci_supp_chip { 9762306a36Sopenharmony_ci u32 dev_id; 9862306a36Sopenharmony_ci u32 rev_id; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cienum ath10k_pci_irq_mode { 10262306a36Sopenharmony_ci ATH10K_PCI_IRQ_AUTO = 0, 10362306a36Sopenharmony_ci ATH10K_PCI_IRQ_LEGACY = 1, 10462306a36Sopenharmony_ci ATH10K_PCI_IRQ_MSI = 2, 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistruct ath10k_pci { 10862306a36Sopenharmony_ci struct pci_dev *pdev; 10962306a36Sopenharmony_ci struct device *dev; 11062306a36Sopenharmony_ci struct ath10k *ar; 11162306a36Sopenharmony_ci void __iomem *mem; 11262306a36Sopenharmony_ci size_t mem_len; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /* Operating interrupt mode */ 11562306a36Sopenharmony_ci enum ath10k_pci_irq_mode oper_irq_mode; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* Copy Engine used for Diagnostic Accesses */ 12062306a36Sopenharmony_ci struct ath10k_ce_pipe *ce_diag; 12162306a36Sopenharmony_ci /* For protecting ce_diag */ 12262306a36Sopenharmony_ci struct mutex ce_diag_mutex; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci struct work_struct dump_work; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci struct ath10k_ce ce; 12762306a36Sopenharmony_ci struct timer_list rx_post_retry; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci /* Due to HW quirks it is recommended to disable ASPM during device 13062306a36Sopenharmony_ci * bootup. To do that the original PCI-E Link Control is stored before 13162306a36Sopenharmony_ci * device bootup is executed and re-programmed later. 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci u16 link_ctl; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci /* Protects ps_awake and ps_wake_refcount */ 13662306a36Sopenharmony_ci spinlock_t ps_lock; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /* The device has a special powersave-oriented register. When device is 13962306a36Sopenharmony_ci * considered asleep it drains less power and driver is forbidden from 14062306a36Sopenharmony_ci * accessing most MMIO registers. If host were to access them without 14162306a36Sopenharmony_ci * waking up the device might scribble over host memory or return 14262306a36Sopenharmony_ci * 0xdeadbeef readouts. 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci unsigned long ps_wake_refcount; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* Waking up takes some time (up to 2ms in some cases) so it can be bad 14762306a36Sopenharmony_ci * for latency. To mitigate this the device isn't immediately allowed 14862306a36Sopenharmony_ci * to sleep after all references are undone - instead there's a grace 14962306a36Sopenharmony_ci * period after which the powersave register is updated unless some 15062306a36Sopenharmony_ci * activity to/from device happened in the meantime. 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci * Also see comments on ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC. 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci struct timer_list ps_timer; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* MMIO registers are used to communicate with the device. With 15762306a36Sopenharmony_ci * intensive traffic accessing powersave register would be a bit 15862306a36Sopenharmony_ci * wasteful overhead and would needlessly stall CPU. It is far more 15962306a36Sopenharmony_ci * efficient to rely on a variable in RAM and update it only upon 16062306a36Sopenharmony_ci * powersave register state changes. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci bool ps_awake; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* pci power save, disable for QCA988X and QCA99X0. 16562306a36Sopenharmony_ci * Writing 'false' to this variable avoids frequent locking 16662306a36Sopenharmony_ci * on MMIO read/write. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci bool pci_ps; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* Chip specific pci reset routine used to do a safe reset */ 17162306a36Sopenharmony_ci int (*pci_soft_reset)(struct ath10k *ar); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci /* Chip specific pci full reset function */ 17462306a36Sopenharmony_ci int (*pci_hard_reset)(struct ath10k *ar); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* chip specific methods for converting target CPU virtual address 17762306a36Sopenharmony_ci * space to CE address space 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci struct ce_attr *attr; 18262306a36Sopenharmony_ci struct ce_pipe_config *pipe_config; 18362306a36Sopenharmony_ci struct ce_service_to_pipe *serv_to_pipe; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci /* Keep this entry in the last, memory for struct ath10k_ahb is 18662306a36Sopenharmony_ci * allocated (ahb support enabled case) in the continuation of 18762306a36Sopenharmony_ci * this struct. 18862306a36Sopenharmony_ci */ 18962306a36Sopenharmony_ci struct ath10k_ahb ahb[]; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci}; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci return (struct ath10k_pci *)ar->drv_priv; 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci#define ATH10K_PCI_RX_POST_RETRY_MS 50 19962306a36Sopenharmony_ci#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ 20062306a36Sopenharmony_ci#define PCIE_WAKE_TIMEOUT 30000 /* 30ms */ 20162306a36Sopenharmony_ci#define PCIE_WAKE_LATE_US 10000 /* 10ms */ 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#define BAR_NUM 0 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci#define CDC_WAR_MAGIC_STR 0xceef0000 20662306a36Sopenharmony_ci#define CDC_WAR_DATA_CE 4 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ 20962306a36Sopenharmony_ci#define DIAG_ACCESS_CE_TIMEOUT_US 10000 /* 10 ms */ 21062306a36Sopenharmony_ci#define DIAG_ACCESS_CE_WAIT_US 50 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_civoid ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value); 21362306a36Sopenharmony_civoid ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val); 21462306a36Sopenharmony_civoid ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ciu32 ath10k_pci_read32(struct ath10k *ar, u32 offset); 21762306a36Sopenharmony_ciu32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr); 21862306a36Sopenharmony_ciu32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciint ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, 22162306a36Sopenharmony_ci struct ath10k_hif_sg_item *items, int n_items); 22262306a36Sopenharmony_ciint ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf, 22362306a36Sopenharmony_ci size_t buf_len); 22462306a36Sopenharmony_ciint ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, 22562306a36Sopenharmony_ci const void *data, int nbytes); 22662306a36Sopenharmony_ciint ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, void *req, u32 req_len, 22762306a36Sopenharmony_ci void *resp, u32 *resp_len); 22862306a36Sopenharmony_ciint ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id, 22962306a36Sopenharmony_ci u8 *ul_pipe, u8 *dl_pipe); 23062306a36Sopenharmony_civoid ath10k_pci_hif_get_default_pipe(struct ath10k *ar, u8 *ul_pipe, 23162306a36Sopenharmony_ci u8 *dl_pipe); 23262306a36Sopenharmony_civoid ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, 23362306a36Sopenharmony_ci int force); 23462306a36Sopenharmony_ciu16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe); 23562306a36Sopenharmony_civoid ath10k_pci_hif_power_down(struct ath10k *ar); 23662306a36Sopenharmony_ciint ath10k_pci_alloc_pipes(struct ath10k *ar); 23762306a36Sopenharmony_civoid ath10k_pci_free_pipes(struct ath10k *ar); 23862306a36Sopenharmony_civoid ath10k_pci_rx_replenish_retry(struct timer_list *t); 23962306a36Sopenharmony_civoid ath10k_pci_ce_deinit(struct ath10k *ar); 24062306a36Sopenharmony_civoid ath10k_pci_init_napi(struct ath10k *ar); 24162306a36Sopenharmony_ciint ath10k_pci_init_pipes(struct ath10k *ar); 24262306a36Sopenharmony_ciint ath10k_pci_init_config(struct ath10k *ar); 24362306a36Sopenharmony_civoid ath10k_pci_rx_post(struct ath10k *ar); 24462306a36Sopenharmony_civoid ath10k_pci_flush(struct ath10k *ar); 24562306a36Sopenharmony_civoid ath10k_pci_enable_legacy_irq(struct ath10k *ar); 24662306a36Sopenharmony_cibool ath10k_pci_irq_pending(struct ath10k *ar); 24762306a36Sopenharmony_civoid ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); 24862306a36Sopenharmony_civoid ath10k_pci_irq_msi_fw_mask(struct ath10k *ar); 24962306a36Sopenharmony_ciint ath10k_pci_wait_for_target_init(struct ath10k *ar); 25062306a36Sopenharmony_ciint ath10k_pci_setup_resource(struct ath10k *ar); 25162306a36Sopenharmony_civoid ath10k_pci_release_resource(struct ath10k *ar); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci/* QCA6174 is known to have Tx/Rx issues when SOC_WAKE register is poked too 25462306a36Sopenharmony_ci * frequently. To avoid this put SoC to sleep after a very conservative grace 25562306a36Sopenharmony_ci * period. Adjust with great care. 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_ci#define ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC 60 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci#endif /* _PCI_H_ */ 260