diff --git a/package/kernel/mac80211/patches/brcm/060-v6.13-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch b/package/kernel/mac80211/patches/brcm/060-v6.13-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch new file mode 100644 index 0000000000..9c18ce606c --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/060-v6.13-wifi-brcmfmac-Add-optional-lpo-clock-enable-support.patch @@ -0,0 +1,272 @@ +From 0ff0843310b74e565901d85f849fb308c3b1f220 Mon Sep 17 00:00:00 2001 +From: Jacobe Zang +Date: Tue, 10 Sep 2024 11:04:13 +0800 +Subject: [PATCH] wifi: brcmfmac: Add optional lpo clock enable support + +WiFi modules often require 32kHz clock to function. Add support to +enable the clock to PCIe driver and move "brcm,bcm4329-fmac" check +to the top of brcmf_of_probe. Change function prototypes from void +to int and add appropriate errno's for return values that will be +send to bus when error occurred. + +Co-developed-by: Ondrej Jirman +Signed-off-by: Ondrej Jirman +Co-developed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Reviewed-by: Sai Krishna +Signed-off-by: Jacobe Zang +Reviewed-by: Sebastian Reichel +Tested-by: Sebastian Reichel # On RK3588 EVB1 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240910-wireless-mainline-v14-3-9d80fea5326d@wesion.com +--- + .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +-- + .../broadcom/brcm80211/brcmfmac/common.c | 3 ++- + .../wireless/broadcom/brcm80211/brcmfmac/of.c | 25 +++++++++++++------ + .../wireless/broadcom/brcm80211/brcmfmac/of.h | 9 ++++--- + .../broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ + .../broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++------ + .../broadcom/brcm80211/brcmfmac/usb.c | 3 +++ + 7 files changed, 47 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -947,8 +947,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_ + + /* try to attach to the target device */ + sdiodev->bus = brcmf_sdio_probe(sdiodev); +- if (!sdiodev->bus) { +- ret = -ENODEV; ++ if (IS_ERR(sdiodev->bus)) { ++ ret = PTR_ERR(sdiodev->bus); + goto out; + } + brcmf_sdiod_host_fixup(sdiodev->func2->card->host); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -561,7 +561,8 @@ struct brcmf_mp_device *brcmf_get_module + if (!found) { + /* No platform data for this device, try OF and DMI data */ + brcmf_dmi_probe(settings, chip, chiprev); +- brcmf_of_probe(dev, bus_type, settings); ++ if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER) ++ return ERR_PTR(-EPROBE_DEFER); + brcmf_acpi_probe(dev, bus_type, settings); + } + return settings; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include + #include "debug.h" +@@ -65,12 +66,13 @@ static int brcmf_of_get_country_codes(st + return 0; + } + +-void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, +- struct brcmf_mp_device *settings) ++int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, ++ struct brcmf_mp_device *settings) + { + struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; + struct device_node *root, *np = dev->of_node; + struct of_phandle_args oirq; ++ struct clk *clk; + const char *prop; + int irq; + int err; +@@ -106,15 +108,22 @@ void brcmf_of_probe(struct device *dev, + board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); + if (!board_type) { + of_node_put(root); +- return; ++ return 0; + } + strreplace(board_type, '/', '-'); + settings->board_type = board_type; + } + of_node_put(root); + ++ clk = devm_clk_get_optional_enabled(dev, "lpo"); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no"); ++ clk_set_rate(clk, 32768); ++ + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) +- return; ++ return 0; + + err = brcmf_of_get_country_codes(dev, settings); + if (err) +@@ -123,23 +132,25 @@ void brcmf_of_probe(struct device *dev, + of_get_mac_address(np, settings->mac); + + if (bus_type != BRCMF_BUSTYPE_SDIO) +- return; ++ return 0; + + if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) + sdio->drive_strength = val; + + /* make sure there are interrupts defined in the node */ + if (of_irq_parse_one(np, 0, &oirq)) +- return; ++ return 0; + + irq = irq_create_of_mapping(&oirq); + if (!irq) { + brcmf_err("interrupt could not be mapped\n"); +- return; ++ return 0; + } + irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); + + sdio->oob_irq_supported = true; + sdio->oob_irq_nr = irq; + sdio->oob_irq_flags = irqf; ++ ++ return 0; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +@@ -3,11 +3,12 @@ + * Copyright (c) 2014 Broadcom Corporation + */ + #ifdef CONFIG_OF +-void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, +- struct brcmf_mp_device *settings); ++int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, ++ struct brcmf_mp_device *settings); + #else +-static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, +- struct brcmf_mp_device *settings) ++static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, ++ struct brcmf_mp_device *settings) + { ++ return 0; + } + #endif /* CONFIG_OF */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -2452,6 +2452,9 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + ret = -ENOMEM; + goto fail; + } ++ ret = PTR_ERR_OR_ZERO(devinfo->settings); ++ if (ret < 0) ++ goto fail; + + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3943,7 +3943,7 @@ static const struct brcmf_buscore_ops br + .write32 = brcmf_sdio_buscore_write32, + }; + +-static bool ++static int + brcmf_sdio_probe_attach(struct brcmf_sdio *bus) + { + struct brcmf_sdio_dev *sdiodev; +@@ -3953,6 +3953,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + u32 reg_val; + u32 drivestrength; + u32 enum_base; ++ int ret = -EBADE; + + sdiodev = bus->sdiodev; + sdio_claim_host(sdiodev->func1); +@@ -4001,8 +4002,9 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, + bus->ci->chiprev); +- if (!sdiodev->settings) { ++ if (IS_ERR_OR_NULL(sdiodev->settings)) { + brcmf_err("Failed to get device parameters\n"); ++ ret = PTR_ERR_OR_ZERO(sdiodev->settings); + goto fail; + } + /* platform specific configuration: +@@ -4071,7 +4073,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + /* allocate header buffer */ + bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL); + if (!bus->hdrbuf) +- return false; ++ return -ENOMEM; + /* Locate an appropriately-aligned portion of hdrbuf */ + bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], + bus->head_align); +@@ -4082,11 +4084,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + if (bus->poll) + bus->pollrate = 1; + +- return true; ++ return 0; + + fail: + sdio_release_host(sdiodev->func1); +- return false; ++ return ret; + } + + static int +@@ -4451,8 +4453,10 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + + /* Allocate private bus interface state */ + bus = kzalloc(sizeof(*bus), GFP_ATOMIC); +- if (!bus) ++ if (!bus) { ++ ret = -ENOMEM; + goto fail; ++ } + + bus->sdiodev = sdiodev; + sdiodev->bus = bus; +@@ -4467,6 +4471,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + dev_name(&sdiodev->func1->dev)); + if (!wq) { + brcmf_err("insufficient memory to create txworkqueue\n"); ++ ret = -ENOMEM; + goto fail; + } + brcmf_sdiod_freezer_count(sdiodev); +@@ -4474,7 +4479,8 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->brcmf_wq = wq; + + /* attempt to attach to the dongle */ +- if (!(brcmf_sdio_probe_attach(bus))) { ++ ret = brcmf_sdio_probe_attach(bus); ++ if (ret < 0) { + brcmf_err("brcmf_sdio_probe_attach failed\n"); + goto fail; + } +@@ -4546,7 +4552,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + + fail: + brcmf_sdio_remove(bus); +- return NULL; ++ return ERR_PTR(ret); + } + + /* Detach and free everything */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1272,6 +1272,9 @@ static int brcmf_usb_probe_cb(struct brc + ret = -ENOMEM; + goto fail; + } ++ ret = PTR_ERR_OR_ZERO(devinfo->settings); ++ if (ret < 0) ++ goto fail; + + if (!brcmf_usb_dlneeded(devinfo)) { + ret = brcmf_alloc(devinfo->dev, devinfo->settings); diff --git a/package/kernel/mac80211/patches/brcm/061-v6.13-wifi-brcmfmac-add-flag-for-random-seed-during-firmware.patch b/package/kernel/mac80211/patches/brcm/061-v6.13-wifi-brcmfmac-add-flag-for-random-seed-during-firmware.patch new file mode 100644 index 0000000000..63455ba4b3 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/061-v6.13-wifi-brcmfmac-add-flag-for-random-seed-during-firmware.patch @@ -0,0 +1,170 @@ +From ea11a89c3ac64ada9d8b7f7de279cb6385ed194f Mon Sep 17 00:00:00 2001 +From: Jacobe Zang +Date: Tue, 10 Sep 2024 11:04:14 +0800 +Subject: [PATCH] wifi: brcmfmac: add flag for random seed during firmware + download + +Providing the random seed to firmware was tied to the fact that the +device has a valid OTP, which worked for some Apple chips. However, +it turns out the BCM43752 device also needs the random seed in order +to get firmware running. Suspect it is simply tied to the firmware +branch used for the device. Introducing a mechanism to allow setting +it for a device through the device table. + +Co-developed-by: Ondrej Jirman +Signed-off-by: Ondrej Jirman +Co-developed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Jacobe Zang +Reviewed-by: Sebastian Reichel +Tested-by: Sebastian Reichel # On RK3588 EVB1 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240910-wireless-mainline-v14-4-9d80fea5326d@wesion.com +--- + .../broadcom/brcm80211/brcmfmac/pcie.c | 52 ++++++++++++++++--- + .../broadcom/brcm80211/include/brcm_hw_ids.h | 2 + + 2 files changed, 46 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -66,6 +66,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie" + BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); ++BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-pcie"); + BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie"); + BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie"); + BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie"); +@@ -104,6 +105,7 @@ static const struct brcmf_firmware_mappi + BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), ++ BRCMF_FW_ENTRY(BRCM_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752), + BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */ + BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */ + BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */ +@@ -353,6 +355,7 @@ struct brcmf_pciedev_info { + u16 value); + struct brcmf_mp_device *settings; + struct brcmf_otp_params otp; ++ bool fwseed; + #ifdef DEBUG + u32 console_interval; + bool console_active; +@@ -1715,14 +1718,14 @@ static int brcmf_pcie_download_fw_nvram( + memcpy_toio(devinfo->tcm + address, nvram, nvram_len); + brcmf_fw_nvram_free(nvram); + +- if (devinfo->otp.valid) { ++ if (devinfo->fwseed) { + size_t rand_len = BRCMF_RANDOM_SEED_LENGTH; + struct brcmf_random_seed_footer footer = { + .length = cpu_to_le32(rand_len), + .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), + }; + +- /* Some Apple chips/firmwares expect a buffer of random ++ /* Some chips/firmwares expect a buffer of random + * data to be present before NVRAM + */ + brcmf_dbg(PCIE, "Download random seed\n"); +@@ -2394,6 +2397,37 @@ static void brcmf_pcie_debugfs_create(st + } + #endif + ++struct brcmf_pcie_drvdata { ++ enum brcmf_fwvendor vendor; ++ bool fw_seed; ++}; ++ ++enum { ++ BRCMF_DRVDATA_CYW, ++ BRCMF_DRVDATA_BCA, ++ BRCMF_DRVDATA_WCC, ++ BRCMF_DRVDATA_WCC_SEED, ++}; ++ ++static const struct brcmf_pcie_drvdata drvdata[] = { ++ [BRCMF_DRVDATA_CYW] = { ++ .vendor = BRCMF_FWVENDOR_CYW, ++ .fw_seed = false, ++ }, ++ [BRCMF_DRVDATA_BCA] = { ++ .vendor = BRCMF_FWVENDOR_BCA, ++ .fw_seed = false, ++ }, ++ [BRCMF_DRVDATA_WCC] = { ++ .vendor = BRCMF_FWVENDOR_WCC, ++ .fw_seed = false, ++ }, ++ [BRCMF_DRVDATA_WCC_SEED] = { ++ .vendor = BRCMF_FWVENDOR_WCC, ++ .fw_seed = true, ++ }, ++}; ++ + /* Forward declaration for pci_match_id() call */ + static const struct pci_device_id brcmf_pcie_devid_table[]; + +@@ -2475,9 +2509,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + bus->bus_priv.pcie = pcie_bus_dev; + bus->ops = &brcmf_pcie_bus_ops; + bus->proto_type = BRCMF_PROTO_MSGBUF; +- bus->fwvid = id->driver_data; + bus->chip = devinfo->coreid; + bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); ++ bus->fwvid = drvdata[id->driver_data].vendor; ++ devinfo->fwseed = drvdata[id->driver_data].fw_seed; + dev_set_drvdata(&pdev->dev, bus); + + ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); +@@ -2663,14 +2698,14 @@ static const struct dev_pm_ops brcmf_pci + BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ + PCI_ANY_ID, PCI_ANY_ID, \ + PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ +- BRCMF_FWVENDOR_ ## fw_vend \ ++ BRCMF_DRVDATA_ ## fw_vend \ + } + #define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev, fw_vend) \ + { \ + BRCM_PCIE_VENDOR_ID_BROADCOM, (dev_id), \ + (subvend), (subdev), \ + PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, \ +- BRCMF_FWVENDOR_ ## fw_vend \ ++ BRCMF_DRVDATA_ ## fw_vend \ + } + + static const struct pci_device_id brcmf_pcie_devid_table[] = { +@@ -2698,9 +2733,10 @@ static const struct pci_device_id brcmf_ + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW), +- BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC), +- BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC), +- BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC_SEED), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC_SEED), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC_SEED), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC_SEED), + + { /* end: all zeroes */ } + }; +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -52,6 +52,7 @@ + #define BRCM_CC_43664_CHIP_ID 43664 + #define BRCM_CC_43666_CHIP_ID 43666 + #define BRCM_CC_4371_CHIP_ID 0x4371 ++#define BRCM_CC_43752_CHIP_ID 43752 + #define BRCM_CC_4377_CHIP_ID 0x4377 + #define BRCM_CC_4378_CHIP_ID 0x4378 + #define BRCM_CC_4387_CHIP_ID 0x4387 +@@ -94,6 +95,7 @@ + #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 + #define BRCM_PCIE_4371_DEVICE_ID 0x440d + #define BRCM_PCIE_43596_DEVICE_ID 0x4415 ++#define BRCM_PCIE_43752_DEVICE_ID 0x449d + #define BRCM_PCIE_4377_DEVICE_ID 0x4488 + #define BRCM_PCIE_4378_DEVICE_ID 0x4425 + #define BRCM_PCIE_4387_DEVICE_ID 0x4433 diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch index 1f0609e348..143542dd73 100644 --- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -12,7 +12,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -@@ -65,6 +65,36 @@ static int brcmf_of_get_country_codes(st +@@ -66,6 +66,36 @@ static int brcmf_of_get_country_codes(st return 0; } @@ -46,15 +46,15 @@ Signed-off-by: Rafał Miłecki + } +} + - void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, - struct brcmf_mp_device *settings) + int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { -@@ -113,6 +143,8 @@ void brcmf_of_probe(struct device *dev, - } - of_node_put(root); +@@ -122,6 +152,8 @@ int brcmf_of_probe(struct device *dev, e + brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no"); + clk_set_rate(clk, 32768); + brcmf_of_probe_cc(dev, settings); + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) - return; + return 0;