#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/bcma/bcma.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/kthread.h>
#include <linux/io.h>
#include <linux/random.h>
#include <linux/unaligned.h>
#include <soc.h>
#include <chipcommon.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
#include <brcm_hw_ids.h>
#define brcmf_err(bus, fmt, ...) …
#include "debug.h"
#include "bus.h"
#include "commonring.h"
#include "msgbuf.h"
#include "pcie.h"
#include "firmware.h"
#include "chip.h"
#include "core.h"
#include "common.h"
enum brcmf_pcie_state { … };
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
BRCMF_FW_CLM_DEF(…) …;
MODULE_FIRMWARE(…) …;
MODULE_FIRMWARE(…) …;
MODULE_FIRMWARE(…) …;
MODULE_FIRMWARE(…) …;
MODULE_FIRMWARE(…) …;
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = …;
#define BRCMF_PCIE_FW_UP_TIMEOUT …
#define BRCMF_PCIE_REG_MAP_SIZE …
#define BRCMF_PCIE_BAR0_WINDOW …
#define BRCMF_PCIE_BAR0_REG_SIZE …
#define BRCMF_PCIE_BAR0_WRAPPERBASE …
#define BRCMF_PCIE_BAR0_WRAPBASE_DMP_OFFSET …
#define BRCMF_PCIE_BARO_PCIE_ENUM_OFFSET …
#define BRCMF_PCIE_ARMCR4REG_BANKIDX …
#define BRCMF_PCIE_ARMCR4REG_BANKPDA …
#define BRCMF_PCIE_REG_INTSTATUS …
#define BRCMF_PCIE_REG_INTMASK …
#define BRCMF_PCIE_REG_SBMBX …
#define BRCMF_PCIE_REG_LINK_STATUS_CTRL …
#define BRCMF_PCIE_PCIE2REG_INTMASK …
#define BRCMF_PCIE_PCIE2REG_MAILBOXINT …
#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK …
#define BRCMF_PCIE_PCIE2REG_CONFIGADDR …
#define BRCMF_PCIE_PCIE2REG_CONFIGDATA …
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 …
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 …
#define BRCMF_PCIE_64_PCIE2REG_INTMASK …
#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT …
#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK …
#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 …
#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 …
#define BRCMF_PCIE2_INTA …
#define BRCMF_PCIE2_INTB …
#define BRCMF_PCIE_INT_0 …
#define BRCMF_PCIE_INT_1 …
#define BRCMF_PCIE_INT_DEF …
#define BRCMF_PCIE_MB_INT_FN0_0 …
#define BRCMF_PCIE_MB_INT_FN0_1 …
#define BRCMF_PCIE_MB_INT_D2H0_DB0 …
#define BRCMF_PCIE_MB_INT_D2H0_DB1 …
#define BRCMF_PCIE_MB_INT_D2H1_DB0 …
#define BRCMF_PCIE_MB_INT_D2H1_DB1 …
#define BRCMF_PCIE_MB_INT_D2H2_DB0 …
#define BRCMF_PCIE_MB_INT_D2H2_DB1 …
#define BRCMF_PCIE_MB_INT_D2H3_DB0 …
#define BRCMF_PCIE_MB_INT_D2H3_DB1 …
#define BRCMF_PCIE_MB_INT_FN0 …
#define BRCMF_PCIE_MB_INT_D2H_DB …
#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 …
#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 …
#define BRCMF_PCIE_64_MB_INT_D2H_DB …
#define BRCMF_PCIE_SHARED_VERSION_7 …
#define BRCMF_PCIE_MIN_SHARED_VERSION …
#define BRCMF_PCIE_MAX_SHARED_VERSION …
#define BRCMF_PCIE_SHARED_VERSION_MASK …
#define BRCMF_PCIE_SHARED_DMA_INDEX …
#define BRCMF_PCIE_SHARED_DMA_2B_IDX …
#define BRCMF_PCIE_SHARED_HOSTRDY_DB1 …
#define BRCMF_PCIE_FLAGS_HTOD_SPLIT …
#define BRCMF_PCIE_FLAGS_DTOH_SPLIT …
#define BRCMF_SHARED_MAX_RXBUFPOST_OFFSET …
#define BRCMF_SHARED_RING_BASE_OFFSET …
#define BRCMF_SHARED_RX_DATAOFFSET_OFFSET …
#define BRCMF_SHARED_CONSOLE_ADDR_OFFSET …
#define BRCMF_SHARED_HTOD_MB_DATA_ADDR_OFFSET …
#define BRCMF_SHARED_DTOH_MB_DATA_ADDR_OFFSET …
#define BRCMF_SHARED_RING_INFO_ADDR_OFFSET …
#define BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET …
#define BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET …
#define BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET …
#define BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET …
#define BRCMF_RING_H2D_RING_COUNT_OFFSET …
#define BRCMF_RING_D2H_RING_COUNT_OFFSET …
#define BRCMF_RING_H2D_RING_MEM_OFFSET …
#define BRCMF_RING_H2D_RING_STATE_OFFSET …
#define BRCMF_RING_MEM_BASE_ADDR_OFFSET …
#define BRCMF_RING_MAX_ITEM_OFFSET …
#define BRCMF_RING_LEN_ITEMS_OFFSET …
#define BRCMF_RING_MEM_SZ …
#define BRCMF_RING_STATE_SZ …
#define BRCMF_DEF_MAX_RXBUFPOST …
#define BRCMF_CONSOLE_BUFADDR_OFFSET …
#define BRCMF_CONSOLE_BUFSIZE_OFFSET …
#define BRCMF_CONSOLE_WRITEIDX_OFFSET …
#define BRCMF_DMA_D2H_SCRATCH_BUF_LEN …
#define BRCMF_DMA_D2H_RINGUPD_BUF_LEN …
#define BRCMF_D2H_DEV_D3_ACK …
#define BRCMF_D2H_DEV_DS_ENTER_REQ …
#define BRCMF_D2H_DEV_DS_EXIT_NOTE …
#define BRCMF_D2H_DEV_FWHALT …
#define BRCMF_H2D_HOST_D3_INFORM …
#define BRCMF_H2D_HOST_DS_ACK …
#define BRCMF_H2D_HOST_D0_INFORM_IN_USE …
#define BRCMF_H2D_HOST_D0_INFORM …
#define BRCMF_PCIE_MBDATA_TIMEOUT …
#define BRCMF_PCIE_CFGREG_STATUS_CMD …
#define BRCMF_PCIE_CFGREG_PM_CSR …
#define BRCMF_PCIE_CFGREG_MSI_CAP …
#define BRCMF_PCIE_CFGREG_MSI_ADDR_L …
#define BRCMF_PCIE_CFGREG_MSI_ADDR_H …
#define BRCMF_PCIE_CFGREG_MSI_DATA …
#define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL …
#define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2 …
#define BRCMF_PCIE_CFGREG_RBAR_CTRL …
#define BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1 …
#define BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG …
#define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG …
#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB …
#define BRCMF_RAMSIZE_MAGIC …
#define BRCMF_RAMSIZE_OFFSET …
struct brcmf_pcie_console { … };
struct brcmf_pcie_shared_info { … };
#define BRCMF_OTP_MAX_PARAM_LEN …
struct brcmf_otp_params { … };
struct brcmf_pciedev_info { … };
struct brcmf_pcie_ringbuf { … };
struct brcmf_pcie_dhi_ringinfo { … };
static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = …;
static const u32 brcmf_ring_itemsize_pre_v7[BRCMF_NROF_COMMON_MSGRINGS] = …;
static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = …;
struct brcmf_pcie_reginfo { … };
static const struct brcmf_pcie_reginfo brcmf_reginfo_default = …;
static const struct brcmf_pcie_reginfo brcmf_reginfo_64 = …;
static void brcmf_pcie_setup(struct device *dev, int ret,
struct brcmf_fw_request *fwreq);
static struct brcmf_fw_request *
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
static void
brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active);
static void brcmf_pcie_debugfs_create(struct device *dev);
static u16
brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
{ … }
static u32
brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
{ … }
static void
brcmf_pcie_write_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset,
u32 value)
{ … }
static u8
brcmf_pcie_read_tcm8(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{ … }
static u16
brcmf_pcie_read_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{ … }
static void
brcmf_pcie_write_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u16 value)
{ … }
static u16
brcmf_pcie_read_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{ … }
static void
brcmf_pcie_write_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u16 value)
{ … }
static u32
brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{ … }
static void
brcmf_pcie_write_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u32 value)
{ … }
static u32
brcmf_pcie_read_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{ … }
static void
brcmf_pcie_write_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u32 value)
{ … }
static void
brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
void *dstaddr, u32 len)
{ … }
#define READCC32(devinfo, reg) …
#define WRITECC32(devinfo, reg, value) …
static void
brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
{ … }
static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo)
{ … }
static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
{ … }
static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
u32 resetintr)
{ … }
static int
brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
{ … }
static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo,
bool error)
{ … }
static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo)
{ … }
static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
{ … }
static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
{ … }
static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
{ … }
static int brcmf_pcie_ring_mb_write_rptr(void *ctx)
{ … }
static int brcmf_pcie_ring_mb_write_wptr(void *ctx)
{ … }
static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
{ … }
static int brcmf_pcie_ring_mb_update_rptr(void *ctx)
{ … }
static int brcmf_pcie_ring_mb_update_wptr(void *ctx)
{ … }
static void *
brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
u32 size, u32 tcm_dma_phys_addr,
dma_addr_t *dma_handle)
{ … }
static struct brcmf_pcie_ringbuf *
brcmf_pcie_alloc_dma_and_ring(struct brcmf_pciedev_info *devinfo, u32 ring_id,
u32 tcm_ring_phys_addr)
{ … }
static void brcmf_pcie_release_ringbuffer(struct device *dev,
struct brcmf_pcie_ringbuf *ring)
{ … }
static void brcmf_pcie_release_ringbuffers(struct brcmf_pciedev_info *devinfo)
{ … }
static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
{ … }
static void
brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo)
{ … }
static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_down(struct device *dev)
{ … }
static int brcmf_pcie_preinit(struct device *dev)
{ … }
static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb)
{ … }
static int brcmf_pcie_tx_ctlpkt(struct device *dev, unsigned char *msg,
uint len)
{ … }
static int brcmf_pcie_rx_ctlpkt(struct device *dev, unsigned char *msg,
uint len)
{ … }
static void brcmf_pcie_wowl_config(struct device *dev, bool enabled)
{ … }
static size_t brcmf_pcie_get_ramsize(struct device *dev)
{ … }
static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
{ … }
static int brcmf_pcie_get_blob(struct device *dev, const struct firmware **fw,
enum brcmf_blob_type type)
{ … }
static int brcmf_pcie_reset(struct device *dev)
{ … }
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = …;
static void
brcmf_pcie_adjust_ramsize(struct brcmf_pciedev_info *devinfo, u8 *data,
u32 data_len)
{ … }
static int
brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
u32 sharedram_addr)
{ … }
struct brcmf_random_seed_footer { … };
#define BRCMF_RANDOM_SEED_MAGIC …
#define BRCMF_RANDOM_SEED_LENGTH …
static noinline_for_stack void
brcmf_pcie_provide_random_bytes(struct brcmf_pciedev_info *devinfo, u32 address)
{ … }
static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
const struct firmware *fw, void *nvram,
u32 nvram_len)
{ … }
static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
{ … }
static void brcmf_pcie_release_resource(struct brcmf_pciedev_info *devinfo)
{ … }
static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr)
{ … }
static u32 brcmf_pcie_buscore_read32(void *ctx, u32 addr)
{ … }
static void brcmf_pcie_buscore_write32(void *ctx, u32 addr, u32 value)
{ … }
static int brcmf_pcie_buscoreprep(void *ctx)
{ … }
static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
{ … }
static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
u32 rstvec)
{ … }
static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = …;
#define BRCMF_OTP_SYS_VENDOR …
#define BRCMF_OTP_BRCM_CIS …
#define BRCMF_OTP_VENDOR_HDR …
static int
brcmf_pcie_parse_otp_sys_vendor(struct brcmf_pciedev_info *devinfo,
u8 *data, size_t size)
{ … }
static int
brcmf_pcie_parse_otp(struct brcmf_pciedev_info *devinfo, u8 *otp, size_t size)
{ … }
static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
{ … }
#define BRCMF_PCIE_FW_CODE …
#define BRCMF_PCIE_FW_NVRAM …
#define BRCMF_PCIE_FW_CLM …
#define BRCMF_PCIE_FW_TXCAP …
static void brcmf_pcie_setup(struct device *dev, int ret,
struct brcmf_fw_request *fwreq)
{ … }
static struct brcmf_fw_request *
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
{ … }
#ifdef DEBUG
static void
brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
{ … }
static void
brcmf_pcie_fwcon(struct timer_list *t)
{ … }
static int brcmf_pcie_console_interval_get(void *data, u64 *val)
{ … }
static int brcmf_pcie_console_interval_set(void *data, u64 val)
{ … }
DEFINE_SIMPLE_ATTRIBUTE(…);
static void brcmf_pcie_debugfs_create(struct device *dev)
{ … }
#else
void brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
{
}
static void brcmf_pcie_debugfs_create(struct device *dev)
{
}
#endif
static const struct pci_device_id brcmf_pcie_devid_table[];
static int
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ … }
static void
brcmf_pcie_remove(struct pci_dev *pdev)
{ … }
#ifdef CONFIG_PM
static int brcmf_pcie_pm_enter_D3(struct device *dev)
{ … }
static int brcmf_pcie_pm_leave_D3(struct device *dev)
{ … }
static const struct dev_pm_ops brcmf_pciedrvr_pm = …;
#endif
#define BRCMF_PCIE_DEVICE(dev_id, fw_vend) …
#define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev, fw_vend) …
static const struct pci_device_id brcmf_pcie_devid_table[] = …;
MODULE_DEVICE_TABLE(pci, brcmf_pcie_devid_table);
static struct pci_driver brcmf_pciedrvr = …;
int brcmf_pcie_register(void)
{ … }
void brcmf_pcie_exit(void)
{ … }