From f5317ed5d2e06765982b44fb4f42b80686790b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 7 Mar 2016 22:37:09 +0000 Subject: mac80211: backport brcmfmac patchset with driver setting concept MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prepares brcmfmac for better country handling and fixes BCM4360 support which was always failing with: [ 13.249195] brcmfmac: brcmf_pcie_download_fw_nvram: FW failed to initialize Signed-off-by: Rafał Miłecki SVN-Revision: 48959 --- ...merge-platform-data-and-module-paramaters.patch | 607 +++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch (limited to 'package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch') diff --git a/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch b/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch new file mode 100644 index 0000000000..34341d7f18 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch @@ -0,0 +1,607 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:08 +0100 +Subject: [PATCH] brcmfmac: merge platform data and module paramaters + +Merge module parameters and platform data in one struct. This is the +last step to move to the new platform data per device. Now parameters +of platform data will be merged with module parameters per device. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -109,8 +109,8 @@ int brcmf_sdiod_intr_register(struct brc + u32 addr, gpiocontrol; + unsigned long flags; + +- pdata = sdiodev->pdata; +- if ((pdata) && (pdata->oob_irq_supported)) { ++ pdata = &sdiodev->settings->bus.sdio; ++ if (pdata->oob_irq_supported) { + brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", + pdata->oob_irq_nr); + ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, +@@ -177,8 +177,8 @@ int brcmf_sdiod_intr_unregister(struct b + + brcmf_dbg(SDIO, "Entering\n"); + +- pdata = sdiodev->pdata; +- if ((pdata) && (pdata->oob_irq_supported)) { ++ pdata = &sdiodev->settings->bus.sdio; ++ if (pdata->oob_irq_supported) { + sdio_claim_host(sdiodev->func[1]); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); +@@ -522,7 +522,7 @@ static int brcmf_sdiod_sglist_rw(struct + target_list = pktlist; + /* for host with broken sg support, prepare a page aligned list */ + __skb_queue_head_init(&local_list); +- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { ++ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { + req_sz = 0; + skb_queue_walk(pktlist, pkt_next) + req_sz += pkt_next->len; +@@ -629,7 +629,7 @@ static int brcmf_sdiod_sglist_rw(struct + } + } + +- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { ++ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { + local_pkt_next = local_list.next; + orig_offset = 0; + skb_queue_walk(pktlist, pkt_next) { +@@ -900,7 +900,7 @@ void brcmf_sdiod_sgtable_alloc(struct br + return; + + nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, +- sdiodev->bus_if->drvr->settings->sdiod_txglomsz); ++ sdiodev->settings->bus.sdio.txglomsz); + nents += (nents >> 4) + 1; + + WARN_ON(nents > sdiodev->max_segment_count); +@@ -912,7 +912,7 @@ void brcmf_sdiod_sgtable_alloc(struct br + sdiodev->sg_support = false; + } + +- sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz; ++ sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz; + } + + #ifdef CONFIG_PM_SLEEP +@@ -1246,8 +1246,8 @@ static int brcmf_ops_sdio_suspend(struct + + sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->wowl_enabled) { +- if (sdiodev->pdata->oob_irq_supported) +- enable_irq_wake(sdiodev->pdata->oob_irq_nr); ++ if (sdiodev->settings->bus.sdio.oob_irq_supported) ++ enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); + else + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -43,6 +43,8 @@ enum brcmf_bus_protocol_type { + BRCMF_PROTO_MSGBUF + }; + ++struct brcmf_mp_device; ++ + struct brcmf_bus_dcmd { + char *name; + char *param; +@@ -217,7 +219,7 @@ bool brcmf_c_prec_enq(struct device *dev + void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); + + /* Indication from bus module regarding presence/insertion of dongle. */ +-int brcmf_attach(struct device *dev); ++int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); + /* Indication from bus module regarding removal/absence of dongle */ + void brcmf_detach(struct device *dev); + /* Indication from bus module that dongle should be reset */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -243,14 +243,35 @@ static void brcmf_mp_attach(void) + } + } + +-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, +- enum brcmf_bus_type bus_type, +- u32 chip, u32 chiprev) ++struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev) + { +- struct brcmfmac_sdio_pd *pdata; ++ struct brcmf_mp_device *settings; + struct brcmfmac_pd_device *device_pd; ++ bool found; + int i; + ++ brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip, ++ chiprev); ++ settings = kzalloc(sizeof(*settings), GFP_ATOMIC); ++ if (!settings) ++ return NULL; ++ ++ /* start by using the module paramaters */ ++ settings->p2p_enable = !!brcmf_p2p_enable; ++ settings->feature_disable = brcmf_feature_disable; ++ settings->fcmode = brcmf_fcmode; ++ settings->roamoff = !!brcmf_roamoff; ++#ifdef DEBUG ++ settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; ++#endif ++ ++ if (bus_type == BRCMF_BUSTYPE_SDIO) ++ settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; ++ ++ /* See if there is any device specific platform data configured */ ++ found = false; + if (brcmfmac_pdata) { + for (i = 0; i < brcmfmac_pdata->device_count; i++) { + device_pd = &brcmfmac_pdata->devices[i]; +@@ -259,38 +280,29 @@ struct brcmfmac_sdio_pd *brcmf_get_modul + ((device_pd->rev == chiprev) || + (device_pd->rev == -1))) { + brcmf_dbg(INFO, "Platform data for device found\n"); ++ settings->country_codes = ++ device_pd->country_codes; + if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) +- return &device_pd->bus.sdio; ++ memcpy(&settings->bus.sdio, ++ &device_pd->bus.sdio, ++ sizeof(settings->bus.sdio)); ++ found = true; + break; + } + } + } +- pdata = NULL; +- brcmf_of_probe(dev, &pdata); +- +- return pdata; +-} +- +-int brcmf_mp_device_attach(struct brcmf_pub *drvr) +-{ +- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); +- if (!drvr->settings) +- return -ENOMEM; +- +- drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; +- drvr->settings->p2p_enable = !!brcmf_p2p_enable; +- drvr->settings->feature_disable = brcmf_feature_disable; +- drvr->settings->fcmode = brcmf_fcmode; +- drvr->settings->roamoff = !!brcmf_roamoff; +-#ifdef DEBUG +- drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; +-#endif +- return 0; ++ if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) { ++ /* No platform data for this device. In case of SDIO try OF ++ * (Open Firwmare) Device Tree. ++ */ ++ brcmf_of_probe(dev, &settings->bus.sdio); ++ } ++ return settings; + } + +-void brcmf_mp_device_detach(struct brcmf_pub *drvr) ++void brcmf_release_module_param(struct brcmf_mp_device *module_param) + { +- kfree(drvr->settings); ++ kfree(module_param); + } + + static int __init brcmf_common_pd_probe(struct platform_device *pdev) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -45,41 +45,30 @@ extern struct brcmf_mp_global_t brcmf_mp + /** + * struct brcmf_mp_device - Device module paramaters. + * +- * @sdiod_txglomsz: SDIO txglom size. +- * @joinboost_5g_rssi: 5g rssi booost for preferred join selection. + * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). + * @feature_disable: Feature_disable bitmask. + * @fcmode: FWS flow control. + * @roamoff: Firmware roaming off? ++ * @ignore_probe_fail: Ignore probe failure. + * @country_codes: If available, pointer to struct for translating country codes ++ * @bus: Bus specific platform data. Only SDIO at the mmoment. + */ + struct brcmf_mp_device { +- int sdiod_txglomsz; +- int joinboost_5g_rssi; +- bool p2p_enable; +- int feature_disable; +- int fcmode; +- bool roamoff; +- bool ignore_probe_fail; ++ bool p2p_enable; ++ unsigned int feature_disable; ++ int fcmode; ++ bool roamoff; ++ bool ignore_probe_fail; + struct brcmfmac_pd_cc *country_codes; ++ union { ++ struct brcmfmac_sdio_pd sdio; ++ } bus; + }; + +-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, +- enum brcmf_bus_type bus_type, +- u32 chip, u32 chiprev); +-int brcmf_mp_device_attach(struct brcmf_pub *drvr); +-void brcmf_mp_device_detach(struct brcmf_pub *drvr); +-#ifdef DEBUG +-static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) +-{ +- return drvr->settings->ignore_probe_fail; +-} +-#else +-static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) +-{ +- return false; +-} +-#endif ++struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev); ++void brcmf_release_module_param(struct brcmf_mp_device *module_param); + + /* Sets dongle media info (drv_version, mac address). */ + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1104,7 +1104,7 @@ static int brcmf_inet6addr_changed(struc + } + #endif + +-int brcmf_attach(struct device *dev) ++int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) + { + struct brcmf_pub *drvr = NULL; + int ret = 0; +@@ -1126,10 +1126,7 @@ int brcmf_attach(struct device *dev) + drvr->hdrlen = 0; + drvr->bus_if = dev_get_drvdata(dev); + drvr->bus_if->drvr = drvr; +- +- /* Initialize device specific settings */ +- if (brcmf_mp_device_attach(drvr)) +- goto fail; ++ drvr->settings = settings; + + /* attach debug facilities */ + brcmf_debug_attach(drvr); +@@ -1274,7 +1271,7 @@ fail: + brcmf_net_detach(p2p_ifp->ndev); + drvr->iflist[0] = NULL; + drvr->iflist[1] = NULL; +- if (brcmf_ignoring_probe_fail(drvr)) ++ if (drvr->settings->ignore_probe_fail) + ret = 0; + + return ret; +@@ -1350,8 +1347,6 @@ void brcmf_detach(struct device *dev) + + brcmf_proto_detach(drvr); + +- brcmf_mp_device_detach(drvr); +- + brcmf_debug_detach(drvr); + bus_if->drvr = NULL; + kfree(drvr); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -23,7 +23,7 @@ + #include "common.h" + #include "of.h" + +-void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) ++void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) + { + struct device_node *np = dev->of_node; + int irq; +@@ -33,12 +33,8 @@ void brcmf_of_probe(struct device *dev, + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; + +- *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL); +- if (!(*sdio)) +- return; +- + if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) +- (*sdio)->drive_strength = val; ++ sdio->drive_strength = val; + + /* make sure there are interrupts defined in the node */ + if (!of_find_property(np, "interrupts", NULL)) +@@ -51,7 +47,7 @@ void brcmf_of_probe(struct device *dev, + } + 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; ++ sdio->oob_irq_supported = true; ++ sdio->oob_irq_nr = irq; ++ sdio->oob_irq_flags = irqf; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +@@ -14,10 +14,9 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #ifdef CONFIG_OF +-void +-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); ++void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio); + #else +-static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) ++static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) + { + } + #endif /* CONFIG_OF */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -37,6 +37,8 @@ + #include "pcie.h" + #include "firmware.h" + #include "chip.h" ++#include "core.h" ++#include "common.h" + + + enum brcmf_pcie_state { +@@ -266,6 +268,7 @@ struct brcmf_pciedev_info { + u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset); + void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + u16 value); ++ struct brcmf_mp_device *settings; + }; + + struct brcmf_pcie_ringbuf { +@@ -1525,16 +1528,16 @@ static void brcmf_pcie_release_resource( + } + + +-static int brcmf_pcie_attach_bus(struct device *dev) ++static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) + { + int ret; + + /* Attach to the common driver interface */ +- ret = brcmf_attach(dev); ++ ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings); + if (ret) { + brcmf_err("brcmf_attach failed\n"); + } else { +- ret = brcmf_bus_start(dev); ++ ret = brcmf_bus_start(&devinfo->pdev->dev); + if (ret) + brcmf_err("dongle is not responding\n"); + } +@@ -1672,7 +1675,7 @@ static void brcmf_pcie_setup(struct devi + init_waitqueue_head(&devinfo->mbdata_resp_wait); + + brcmf_pcie_intr_enable(devinfo); +- if (brcmf_pcie_attach_bus(bus->dev) == 0) ++ if (brcmf_pcie_attach_bus(devinfo) == 0) + return; + + brcmf_pcie_bus_console_read(devinfo); +@@ -1716,6 +1719,15 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + goto fail; + } + ++ devinfo->settings = brcmf_get_module_param(&devinfo->pdev->dev, ++ BRCMF_BUSTYPE_PCIE, ++ devinfo->ci->chip, ++ devinfo->ci->chiprev); ++ if (!devinfo->settings) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + ret = -ENOMEM; +@@ -1760,6 +1772,8 @@ fail: + brcmf_pcie_release_resource(devinfo); + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + kfree(pcie_bus_dev); + kfree(devinfo); + return ret; +@@ -1799,6 +1813,8 @@ brcmf_pcie_remove(struct pci_dev *pdev) + + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + + kfree(devinfo); + dev_set_drvdata(&pdev->dev, NULL); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -2442,15 +2442,17 @@ static void brcmf_sdio_bus_stop(struct d + + static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) + { ++ struct brcmf_sdio_dev *sdiodev; + unsigned long flags; + +- if (bus->sdiodev->oob_irq_requested) { +- spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); +- if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { +- enable_irq(bus->sdiodev->pdata->oob_irq_nr); +- bus->sdiodev->irq_en = true; ++ sdiodev = bus->sdiodev; ++ if (sdiodev->oob_irq_requested) { ++ spin_lock_irqsave(&sdiodev->irq_en_lock, flags); ++ if (!sdiodev->irq_en && !atomic_read(&bus->ipend)) { ++ enable_irq(sdiodev->settings->bus.sdio.oob_irq_nr); ++ sdiodev->irq_en = true; + } +- spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); ++ spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); + } + } + +@@ -3394,9 +3396,7 @@ static int brcmf_sdio_bus_preinit(struct + sizeof(u32)); + } else { + /* otherwise, set txglomalign */ +- value = 4; +- if (sdiodev->pdata) +- value = sdiodev->pdata->sd_sgentry_align; ++ value = sdiodev->settings->bus.sdio.sd_sgentry_align; + /* SDIO ADMA requires at least 32 bit alignment */ + value = max_t(u32, value, 4); + err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, +@@ -3811,21 +3811,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + bus->ci = NULL; + goto fail; + } +- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, ++ sdiodev->settings = brcmf_get_module_param(sdiodev->dev, + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, + bus->ci->chiprev); ++ if (!sdiodev->settings) { ++ brcmf_err("Failed to get device parameters\n"); ++ goto fail; ++ } + /* platform specific configuration: + * alignments must be at least 4 bytes for ADMA + */ + bus->head_align = ALIGNMENT; + bus->sgentry_align = ALIGNMENT; +- if (sdiodev->pdata) { +- if (sdiodev->pdata->sd_head_align > ALIGNMENT) +- bus->head_align = sdiodev->pdata->sd_head_align; +- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) +- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; +- } ++ if (sdiodev->settings->bus.sdio.sd_head_align > ALIGNMENT) ++ bus->head_align = sdiodev->settings->bus.sdio.sd_head_align; ++ if (sdiodev->settings->bus.sdio.sd_sgentry_align > ALIGNMENT) ++ bus->sgentry_align = ++ sdiodev->settings->bus.sdio.sd_sgentry_align; ++ + /* allocate scatter-gather table. sg support + * will be disabled upon allocation failure. + */ +@@ -3837,7 +3841,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + */ + if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && + ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || +- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) ++ (sdiodev->settings->bus.sdio.oob_irq_supported))) + sdiodev->bus_if->wowl_supported = true; + #endif + +@@ -3846,8 +3850,8 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + goto fail; + } + +- if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) +- drivestrength = sdiodev->pdata->drive_strength; ++ if (sdiodev->settings->bus.sdio.drive_strength) ++ drivestrength = sdiodev->settings->bus.sdio.drive_strength; + else + drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; + brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); +@@ -4124,7 +4128,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; + + /* Attach to the common layer, reserve hdr space */ +- ret = brcmf_attach(bus->sdiodev->dev); ++ ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings); + if (ret != 0) { + brcmf_err("brcmf_attach failed\n"); + goto fail; +@@ -4228,6 +4232,8 @@ void brcmf_sdio_remove(struct brcmf_sdio + } + brcmf_chip_detach(bus->ci); + } ++ if (bus->sdiodev->settings) ++ brcmf_release_module_param(bus->sdiodev->settings); + + kfree(bus->rxbuf); + kfree(bus->hdrbuf); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -184,7 +184,7 @@ struct brcmf_sdio_dev { + struct brcmf_sdio *bus; + struct device *dev; + struct brcmf_bus *bus_if; +- struct brcmfmac_sdio_pd *pdata; ++ struct brcmf_mp_device *settings; + bool oob_irq_requested; + bool irq_en; /* irq enable flags */ + spinlock_t irq_en_lock; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -27,6 +27,8 @@ + #include "debug.h" + #include "firmware.h" + #include "usb.h" ++#include "core.h" ++#include "common.h" + + + #define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000) +@@ -171,6 +173,7 @@ struct brcmf_usbdev_info { + struct urb *bulk_urb; /* used for FW download */ + + bool wowl_enabled; ++ struct brcmf_mp_device *settings; + }; + + static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, +@@ -1027,6 +1030,9 @@ static void brcmf_usb_detach(struct brcm + + kfree(devinfo->tx_reqs); + kfree(devinfo->rx_reqs); ++ ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + } + + +@@ -1136,7 +1142,7 @@ static int brcmf_usb_bus_setup(struct br + int ret; + + /* Attach to the common driver interface */ +- ret = brcmf_attach(devinfo->dev); ++ ret = brcmf_attach(devinfo->dev, devinfo->settings); + if (ret) { + brcmf_err("brcmf_attach failed\n"); + return ret; +@@ -1223,6 +1229,14 @@ static int brcmf_usb_probe_cb(struct brc + bus->wowl_supported = true; + #endif + ++ devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB, ++ bus_pub->devid, ++ bus_pub->chiprev); ++ if (!devinfo->settings) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ + if (!brcmf_usb_dlneeded(devinfo)) { + ret = brcmf_usb_bus_setup(devinfo); + if (ret) -- cgit v1.2.3