From d99cdd4fef9054a705dac3e66f3b9c4945fbd8e1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Feb 2016 17:10:10 +0000 Subject: [PATCH] mac80211: add first brcmfmac patches for 14e4:4365 BCM4366 support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It's not really supported yet as it still fails with: brcmfmac: brcmf_pcie_download_fw_nvram: FW failed to initialize Signed-off-by: Rafał Miłecki SVN-Revision: 48640 --- ...-descriptors-of-current-component-on.patch | 51 ++++++ ...toring-PMU-core-without-wrapper-addr.patch | 28 ++++ ...tended-capabilities-of-ChipCommon-co.patch | 43 +++++ ...PMU-registers-using-standalone-PMU-c.patch | 148 ++++++++++++++++++ ...port-for-14e4-4365-PCI-ID-with-BCM43.patch | 38 +++++ ...NULL-character-in-NVRAM-as-separator.patch | 32 ++++ ...-Increase-the-default-timeouts-a-bit.patch | 41 +++++ 7 files changed, 381 insertions(+) create mode 100644 package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch create mode 100644 package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch create mode 100644 package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch create mode 100644 package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch create mode 100644 package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch create mode 100644 package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch create mode 100644 package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch diff --git a/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch b/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch new file mode 100644 index 0000000000..d7018dab3d --- /dev/null +++ b/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch @@ -0,0 +1,51 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Jan 2016 17:57:01 +0100 +Subject: [PATCH] brcmfmac: analyze descriptors of current component only +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far we were looking for address descriptors without a check for +crossing current component border. In case of dealing with unsupported +descriptor or descriptor missing at all the code would incorrectly get +data from another component. + +Consider this binary-described component from BCM4366 EROM: +4bf83b01 TAG==CI CID==0x83b +20080201 TAG==CI PORTS==0+1 WRAPPERS==0+1 +18400035 TAG==ADDR SZ_SZD TYPE_SLAVE +00050000 +18107085 TAG==ADDR SZ_4K TYPE_SWRAP + +Driver was assigning invalid base address to this core: +brcmfmac: [6 ] core 0x83b:32 base 0x18109000 wrap 0x18107000 +which came from totally different component defined in EROM: +43b36701 TAG==CI CID==0x367 +00000201 TAG==CI PORTS==0+1 WRAPPERS==0+0 +18109005 TAG==ADDR SZ_4K TYPE_SLAVE + +This change will also allow us to support components without wrapper +address in the future. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -803,7 +803,14 @@ static int brcmf_chip_dmp_get_regaddr(st + *eromaddr -= 4; + return -EFAULT; + } +- } while (desc != DMP_DESC_ADDRESS); ++ } while (desc != DMP_DESC_ADDRESS && ++ desc != DMP_DESC_COMPONENT); ++ ++ /* stop if we crossed current component border */ ++ if (desc == DMP_DESC_COMPONENT) { ++ *eromaddr -= 4; ++ return 0; ++ } + + /* skip upper 32-bit address descriptor */ + if (val & DMP_DESC_ADDRSIZE_GT32) diff --git a/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch b/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch new file mode 100644 index 0000000000..045ab4953b --- /dev/null +++ b/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch @@ -0,0 +1,28 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Jan 2016 17:57:02 +0100 +Subject: [PATCH] brcmfmac: allow storing PMU core without wrapper address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Separated PMU core can be found in new devices and should be used for +accessing PMU registers (which were routed through ChipCommon so far). +This core is one of exceptions that doesn't have or need wrapper address +to be still safely accessible. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -883,7 +883,8 @@ int brcmf_chip_dmp_erom_scan(struct brcm + rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S; + + /* need core with ports */ +- if (nmw + nsw == 0) ++ if (nmw + nsw == 0 && ++ id != BCMA_CORE_PMU) + continue; + + /* try to obtain register address info */ diff --git a/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch b/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch new file mode 100644 index 0000000000..7b7ba4f743 --- /dev/null +++ b/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch @@ -0,0 +1,43 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Jan 2016 17:57:03 +0100 +Subject: [PATCH] brcmfmac: read extended capabilities of ChipCommon core +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is an extra bitfield with info about some present hardware. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -1025,6 +1025,9 @@ static int brcmf_chip_setup(struct brcmf + /* get chipcommon capabilites */ + pub->cc_caps = chip->ops->read32(chip->ctx, + CORE_CC_REG(base, capabilities)); ++ pub->cc_caps_ext = chip->ops->read32(chip->ctx, ++ CORE_CC_REG(base, ++ capabilities_ext)); + + /* get pmu caps & rev */ + if (pub->cc_caps & CC_CAP_PMU) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -27,6 +27,7 @@ + * @chip: chip identifier. + * @chiprev: chip revision. + * @cc_caps: chipcommon core capabilities. ++ * @cc_caps_ext: chipcommon core extended capabilities. + * @pmucaps: PMU capabilities. + * @pmurev: PMU revision. + * @rambase: RAM base address (only applicable for ARM CR4 chips). +@@ -38,6 +39,7 @@ struct brcmf_chip { + u32 chip; + u32 chiprev; + u32 cc_caps; ++ u32 cc_caps_ext; + u32 pmucaps; + u32 pmurev; + u32 rambase; diff --git a/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch b/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch new file mode 100644 index 0000000000..2af6fd93bc --- /dev/null +++ b/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch @@ -0,0 +1,148 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Jan 2016 17:57:04 +0100 +Subject: [PATCH] brcmfmac: access PMU registers using standalone PMU core if + available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On recent Broadcom chipsets PMU is present as separated core and it +can't be accessed using ChipCommon anymore as it fails with e.g.: +[ 18.198412] Unhandled fault: imprecise external abort (0x1406) at 0xb6da200f + +Add a new helper function that will return a proper core that should be +used for accessing PMU registers. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -1014,6 +1014,7 @@ static int brcmf_chip_setup(struct brcmf + { + struct brcmf_chip *pub; + struct brcmf_core_priv *cc; ++ struct brcmf_core *pmu; + u32 base; + u32 val; + int ret = 0; +@@ -1030,9 +1031,10 @@ static int brcmf_chip_setup(struct brcmf + capabilities_ext)); + + /* get pmu caps & rev */ ++ pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */ + if (pub->cc_caps & CC_CAP_PMU) { + val = chip->ops->read32(chip->ctx, +- CORE_CC_REG(base, pmucapabilities)); ++ CORE_CC_REG(pmu->base, pmucapabilities)); + pub->pmurev = val & PCAP_REV_MASK; + pub->pmucaps = val; + } +@@ -1131,6 +1133,23 @@ struct brcmf_core *brcmf_chip_get_chipco + return &cc->pub; + } + ++struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub) ++{ ++ struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub); ++ struct brcmf_core *pmu; ++ ++ /* See if there is separated PMU core available */ ++ if (cc->rev >= 35 && ++ pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) { ++ pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU); ++ if (pmu) ++ return pmu; ++ } ++ ++ /* Fallback to ChipCommon core for older hardware */ ++ return cc; ++} ++ + bool brcmf_chip_iscoreup(struct brcmf_core *pub) + { + struct brcmf_core_priv *core; +@@ -1301,6 +1320,7 @@ bool brcmf_chip_sr_capable(struct brcmf_ + { + u32 base, addr, reg, pmu_cc3_mask = ~0; + struct brcmf_chip_priv *chip; ++ struct brcmf_core *pmu = brcmf_chip_get_pmu(pub); + + brcmf_dbg(TRACE, "Enter\n"); + +@@ -1320,9 +1340,9 @@ bool brcmf_chip_sr_capable(struct brcmf_ + case BRCM_CC_4335_CHIP_ID: + case BRCM_CC_4339_CHIP_ID: + /* read PMU chipcontrol register 3 */ +- addr = CORE_CC_REG(base, chipcontrol_addr); ++ addr = CORE_CC_REG(pmu->base, chipcontrol_addr); + chip->ops->write32(chip->ctx, addr, 3); +- addr = CORE_CC_REG(base, chipcontrol_data); ++ addr = CORE_CC_REG(pmu->base, chipcontrol_data); + reg = chip->ops->read32(chip->ctx, addr); + return (reg & pmu_cc3_mask) != 0; + case BRCM_CC_43430_CHIP_ID: +@@ -1330,12 +1350,12 @@ bool brcmf_chip_sr_capable(struct brcmf_ + reg = chip->ops->read32(chip->ctx, addr); + return reg != 0; + default: +- addr = CORE_CC_REG(base, pmucapabilities_ext); ++ addr = CORE_CC_REG(pmu->base, pmucapabilities_ext); + reg = chip->ops->read32(chip->ctx, addr); + if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0) + return false; + +- addr = CORE_CC_REG(base, retention_ctl); ++ addr = CORE_CC_REG(pmu->base, retention_ctl); + reg = chip->ops->read32(chip->ctx, addr); + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -85,6 +85,7 @@ struct brcmf_chip *brcmf_chip_attach(voi + void brcmf_chip_detach(struct brcmf_chip *chip); + struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid); + struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip); ++struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub); + bool brcmf_chip_iscoreup(struct brcmf_core *core); + void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset); + void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3615,7 +3615,6 @@ brcmf_sdio_drivestrengthinit(struct brcm + const struct sdiod_drive_str *str_tab = NULL; + u32 str_mask; + u32 str_shift; +- u32 base; + u32 i; + u32 drivestrength_sel = 0; + u32 cc_data_temp; +@@ -3658,14 +3657,15 @@ brcmf_sdio_drivestrengthinit(struct brcm + } + + if (str_tab != NULL) { ++ struct brcmf_core *pmu = brcmf_chip_get_pmu(ci); ++ + for (i = 0; str_tab[i].strength != 0; i++) { + if (drivestrength >= str_tab[i].strength) { + drivestrength_sel = str_tab[i].sel; + break; + } + } +- base = brcmf_chip_get_chipcommon(ci)->base; +- addr = CORE_CC_REG(base, chipcontrol_addr); ++ addr = CORE_CC_REG(pmu->base, chipcontrol_addr); + brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); + cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); + cc_data_temp &= ~str_mask; +@@ -3835,8 +3835,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + goto fail; + + /* set PMUControl so a backplane reset does PMU state reload */ +- reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base, +- pmucontrol); ++ reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); + reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); + if (err) + goto fail; diff --git a/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch b/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch new file mode 100644 index 0000000000..35887fcb59 --- /dev/null +++ b/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch @@ -0,0 +1,38 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Jan 2016 17:57:05 +0100 +Subject: [PATCH] brcmfmac: add support for 14e4:4365 PCI ID with BCM4366 + chipset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On Broadcom ARM routers BCM4366 cards are available with 14e4:4365 ID. +Unfortunately this ID was already used by Broadcom for cards with +BCM43142, a totally different chipset requiring SoftMAC driver. To avoid +a conflict between brcmfmac and bcma use more specific ID entry with +subvendor and subdevice specified. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1951,6 +1951,9 @@ static const struct dev_pm_ops brcmf_pci + + #define BRCMF_PCIE_DEVICE(dev_id) { BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } ++#define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev) { \ ++ BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ ++ subvend, subdev, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } + + static struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), +@@ -1966,6 +1969,7 @@ static struct pci_device_id brcmf_pcie_d + BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID), ++ BRCMF_PCIE_DEVICE_SUB(0x4365, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4365), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID), diff --git a/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch b/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch new file mode 100644 index 0000000000..6ce60f1960 --- /dev/null +++ b/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch @@ -0,0 +1,32 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 31 Jan 2016 12:14:34 +0100 +Subject: [PATCH] brcmfmac: treat NULL character in NVRAM as separator +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Platform NVRAM (stored on a flash partition) has entries separated by a +NULL (\0) char. Our parsing code switches from VALUE state to IDLE +whenever it meets a NULL (\0). When that happens our IDLE handler should +simply consume it and analyze whatever is placed ahead. + +This fixes harmless warnings spamming debugging output: +[ 155.165624] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=20: ignoring invalid character +[ 155.180806] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=44: ignoring invalid character +[ 155.195971] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=63: ignoring invalid character + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -93,7 +93,7 @@ static enum nvram_parser_state brcmf_nvr + c = nvp->data[nvp->pos]; + if (c == '\n') + return COMMENT; +- if (is_whitespace(c)) ++ if (is_whitespace(c) || c == '\0') + goto proceed; + if (c == '#') + return COMMENT; diff --git a/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch b/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch new file mode 100644 index 0000000000..012dea1e3a --- /dev/null +++ b/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch @@ -0,0 +1,41 @@ +From: Sjoerd Simons +Date: Mon, 25 Jan 2016 11:47:29 +0100 +Subject: [PATCH] brcmfmac: sdio: Increase the default timeouts a bit + +On a Radxa Rock2 board with a Ampak AP6335 (Broadcom 4339 core) it seems +the card responds very quickly most of the time, unfortunately during +initialisation it sometimes seems to take just a bit over 2 seconds to +respond. + +This results intialization failing with message like: + brcmf_c_preinit_dcmds: Retreiving cur_etheraddr failed, -52 + brcmf_bus_start: failed: -52 + brcmf_sdio_firmware_callback: dongle is not responding + +Increasing the timeout to allow for a bit more headroom allows the +card to initialize reliably. + +A quick search online after diagnosing/fixing this showed that Google +has a similar patch in their ChromeOS tree, so this doesn't seem +specific to the board I'm using. + +Signed-off-by: Sjoerd Simons +Reviewed-by: Julian Calaby +Acked-by: Arend van Spriel +Reviewed-by: Douglas Anderson +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -45,8 +45,8 @@ + #include "chip.h" + #include "firmware.h" + +-#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2000) +-#define CTL_DONE_TIMEOUT msecs_to_jiffies(2000) ++#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) ++#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) + + #ifdef DEBUG + -- 2.30.2