From c3a0d829681948746f2838eef80621e19a56dc3d Mon Sep 17 00:00:00 2001 From: Wright Feng Date: Tue, 19 Apr 2022 05:51:42 +0000 Subject: [PATCH 150/296] brcmfmac: get chip info from SDIOD if chip common space is protected --- .../broadcom/brcm80211/brcmfmac/chip.c | 25 ++++++-- .../broadcom/brcm80211/brcmfmac/chip.h | 11 +++- .../broadcom/brcm80211/brcmfmac/pcie.c | 7 ++- .../broadcom/brcm80211/brcmfmac/sdio.c | 62 ++++++++++++++++--- .../broadcom/brcm80211/brcmfmac/sdio.h | 7 ++- 5 files changed, 94 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c index 1ee07c25c844..71addd8957ba 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c @@ -976,7 +976,10 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci) u32 base, wrap; int err; - eromaddr = ci->ops->read32(ci->ctx, + if (ci->pub.ccsec) + eromaddr = ci->pub.ccsec->erombase; + else + eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(ci->pub.enum_base, eromptr)); while (desc_type != DMP_DESC_EOT) { @@ -1178,11 +1181,15 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) const u32 READ_FAILED = 0xFFFFFFFF; /* Get CC core rev - * Chipid is assume to be at offset 0 from SI_ENUM_BASE + * Chipid is in bus core if CC space is protected or + * it is assume to be at offset 0 from SI_ENUM_BASE * For different chiptypes or old sdio hosts w/o chipcommon, * other ways of recognition should be added here. */ - regdata = ci->ops->read32(ci->ctx, + if (ci->pub.ccsec) + regdata = ci->pub.ccsec->chipid; + else + regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(ci->pub.enum_base, chipid)); if (regdata == READ_FAILED) { brcmf_err("MMIO read failed: 0x%08x\n", regdata); @@ -1292,6 +1299,9 @@ static int brcmf_chip_setup(struct brcmf_chip_priv *chip) u32 val; int ret = 0; + if (chip->pub.ccsec) + return 0; + pub = &chip->pub; cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list); base = cc->pub.base; @@ -1327,6 +1337,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, { struct brcmf_chip_priv *chip; struct brcmf_blhs *blhs; + struct brcmf_ccsec *ccsec; int err = 0; if (WARN_ON(!ops->read32)) @@ -1355,8 +1366,9 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, goto fail; blhs = NULL; - if (chip->ops->blhs_attach) { - err = chip->ops->blhs_attach(chip->ctx, &blhs, + ccsec = NULL; + if (chip->ops->sec_attach) { + err = chip->ops->sec_attach(chip->ctx, &blhs, &ccsec, BRCMF_BLHS_D2H_READY, BRCMF_BLHS_D2H_READY_TIMEOUT, BRCMF_BLHS_POLL_INTERVAL); @@ -1373,6 +1385,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, } } chip->pub.blhs = blhs; + chip->pub.ccsec = ccsec; err = brcmf_chip_recognition(chip); if (err < 0) @@ -1400,7 +1413,9 @@ void brcmf_chip_detach(struct brcmf_chip *pub) list_del(&core->list); kfree(core); } + kfree(pub->blhs); + kfree(pub->ccsec); kfree(chip); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h index 4629201de715..3d1bf44f2d14 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h @@ -44,6 +44,7 @@ struct brcmf_chip { u32 srsize; char name[12]; struct brcmf_blhs *blhs; + struct brcmf_ccsec *ccsec; }; /** @@ -77,8 +78,8 @@ struct brcmf_buscore_ops { int (*reset)(void *ctx, struct brcmf_chip *chip); int (*setup)(void *ctx, struct brcmf_chip *chip); void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); - int (*blhs_attach)(void *ctx, struct brcmf_blhs **blhs, u32 flag, - uint timeout, uint interval); + int (*sec_attach)(void *ctx, struct brcmf_blhs **blhs, struct brcmf_ccsec **ccsec, + u32 flag, uint timeout, uint interval); }; /** @@ -108,6 +109,12 @@ struct brcmf_blhs { void (*write)(void *ctx, u32 addr, u32 value); }; +struct brcmf_ccsec { + u32 bus_corebase; + u32 erombase; + u32 chipid; +}; + int brcmf_chip_get_raminfo(struct brcmf_chip *pub); struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, const struct brcmf_buscore_ops *ops); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 032593d99fec..1a1726d63528 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -2399,8 +2399,9 @@ static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, } -static int brcmf_pcie_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, - u32 flag, uint timeout, uint interval) +static int +brcmf_pcie_buscore_sec_attach(void *ctx, struct brcmf_blhs **blhs, struct brcmf_ccsec **ccsec, + u32 flag, uint timeout, uint interval) { struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); @@ -2455,7 +2456,7 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { .activate = brcmf_pcie_buscore_activate, .read32 = brcmf_pcie_buscore_read32, .write32 = brcmf_pcie_buscore_write32, - .blhs_attach = brcmf_pcie_buscore_blhs_attach, + .sec_attach = brcmf_pcie_buscore_sec_attach, }; #define BRCMF_OTP_SYS_VENDOR 0x15 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 0be1d60b5eb9..464e55e89062 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -173,6 +173,8 @@ struct rte_console { #define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force no backplane reset */ #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 +/* Reset SB Address to default value */ +#define SBSDIO_DEVCTL_ADDR_RESET 0x40 /* direct(mapped) cis space */ @@ -551,6 +553,7 @@ struct brcmf_sdio { u16 head_align; /* buffer pointer alignment */ u16 sgentry_align; /* scatter-gather buffer alignment */ struct mutex sdsem; + bool chipid_preset; }; /* clkstate */ @@ -4229,6 +4232,33 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } } +static u32 +brcmf_sdio_ccsec_get_buscorebase(struct brcmf_sdio_dev *sdiodev) +{ + u8 devctl = 0; + u32 addr = 0; + int err = 0; + + devctl = brcmf_sdiod_readb(sdiodev, SBSDIO_DEVICE_CTL, NULL); + brcmf_sdiod_writeb(sdiodev, SBSDIO_DEVICE_CTL, devctl | SBSDIO_DEVCTL_ADDR_RESET, &err); + if (err) + goto exit; + + addr |= (brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_SBADDRLOW, NULL) << 8) | + (brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_SBADDRMID, NULL) << 16) | + (brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_SBADDRHIGH, NULL) << 24); + + brcmf_dbg(INFO, "sdiod core address is 0x%x\n", addr); +exit: + if (err) { + brcmf_err("Get SDIO core base address failed, err=%d", err); + addr = 0; + } + brcmf_sdiod_writeb(sdiodev, SBSDIO_DEVICE_CTL, devctl, &err); + + return addr; +} + static u32 brcmf_sdio_buscore_blhs_read(void *ctx, u32 reg_offset) { struct brcmf_sdio_dev *sdiodev = (struct brcmf_sdio_dev *)ctx; @@ -4339,11 +4369,14 @@ static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val) brcmf_sdiod_writel(sdiodev, addr, val, NULL); } -static int brcmf_sdio_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, - u32 flag, uint timeout, uint interval) +static int +brcmf_sdio_buscore_sec_attach(void *ctx, struct brcmf_blhs **blhs, struct brcmf_ccsec **ccsec, + u32 flag, uint timeout, uint interval) { struct brcmf_sdio_dev *sdiodev = (struct brcmf_sdio_dev *)ctx; - struct brcmf_blhs *blhsh; + struct brcmf_blhs *blhsh = NULL; + struct brcmf_ccsec *ccsech = NULL; + u32 reg_addr; u8 cardcap; if (sdiodev->func1->vendor != SDIO_VENDOR_ID_CYPRESS) @@ -4363,6 +4396,20 @@ static int brcmf_sdio_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, *blhs = blhsh; } + if (cardcap & SDIO_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) { + ccsech = kzalloc(sizeof(*ccsech), GFP_KERNEL); + if (!ccsech) { + kfree(blhsh); + return -ENOMEM; + } + ccsech->bus_corebase = brcmf_sdio_ccsec_get_buscorebase(sdiodev); + reg_addr = ccsech->bus_corebase + SD_REG(eromptr); + ccsech->erombase = brcmf_sdio_buscore_read32(ctx, reg_addr); + reg_addr = ccsech->bus_corebase + SD_REG(chipid); + ccsech->chipid = brcmf_sdio_buscore_read32(ctx, reg_addr); + *ccsec = ccsech; + } + return 0; } @@ -4371,7 +4418,7 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { .activate = brcmf_sdio_buscore_activate, .read32 = brcmf_sdio_buscore_read32, .write32 = brcmf_sdio_buscore_write32, - .blhs_attach = brcmf_sdio_buscore_blhs_attach, + .sec_attach = brcmf_sdio_buscore_sec_attach, }; static bool @@ -4390,9 +4437,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) enum_base = brcmf_chip_enum_base(sdiodev->func1->device); - pr_debug("F1 signature read @0x%08x=0x%4x\n", enum_base, - brcmf_sdiod_readl(sdiodev, enum_base, NULL)); - /* * Force PLL off until brcmf_chip_attach() * programs PLL control regs @@ -4418,6 +4462,10 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) goto fail; } + if (!bus->ci->ccsec) + pr_debug("F1 signature read @0x18000000=0x%4x\n", + brcmf_sdiod_readl(sdiodev, enum_base, NULL)); + /* Pick up the SDIO core info struct from chip.c */ bus->sdio_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); if (!bus->sdio_core) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 330c8cdfcae7..67c962045a36 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -37,6 +37,7 @@ #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT BIT(1) #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2) #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3) +#define SDIO_CCCR_BRCM_CARDCAP_CHIPID_PRESENT BIT(6) #define SDIO_CCCR_BRCM_CARDCAP_SECURE_MODE BIT(7) /* Interrupt enable bits for each function */ @@ -301,7 +302,11 @@ struct sdpcmd_regs { u32 clockctlstatus; /* rev8 */ u32 PAD[7]; - u32 PAD[128]; /* DMA engines */ + u32 PAD[76]; /* DMA engines */ + + u32 chipid; /* SDIO ChipID Register, 0x330, rev31 */ + u32 eromptr; /* SDIO EromPtrOffset Register, 0x334, rev31 */ + u32 PAD[50]; /* SDIO/PCMCIA CIS region */ char cis[512]; /* 0x400-0x5ff, rev6 */ -- 2.25.1