diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211')
8 files changed, 97 insertions, 87 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 25cd71229c95..bb4aece9ad2c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -103,7 +103,7 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func) int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) { - struct brcmfmac_sdio_platform_data *pdata; + struct brcmfmac_sdio_pd *pdata; int ret = 0; u8 data; u32 addr, gpiocontrol; @@ -173,7 +173,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) { - struct brcmfmac_sdio_platform_data *pdata; + struct brcmfmac_sdio_pd *pdata; brcmf_dbg(SDIO, "Entering\n"); @@ -1164,17 +1164,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, dev_set_drvdata(&func->dev, bus_if); dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); sdiodev->dev = &sdiodev->func[1]->dev; - sdiodev->pdata = brcmf_get_module_param(sdiodev->dev); - -#ifdef CONFIG_PM_SLEEP - /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ - * is true or when platform data OOB irq is true). - */ - 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))) - bus_if->wowl_supported = true; -#endif brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 5609a79df1c1..5e3acaca7231 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -6459,8 +6459,8 @@ int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg, static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], struct brcmf_fil_country_le *ccreq) { - struct cc_translate *country_codes; - struct cc_entry *cc; + struct brcmfmac_pd_cc *country_codes; + struct brcmfmac_pd_cc_entry *cc; s32 found_index; int i; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 020901c2e0ca..4bd3225cdea6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -80,7 +80,7 @@ module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0); MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); #endif -static struct brcmfmac_sdio_platform_data *brcmfmac_pdata; +static struct brcmfmac_platform_data *brcmfmac_pdata; struct brcmf_mp_global_t brcmf_mp_global; int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) @@ -229,15 +229,46 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...) static void brcmf_mp_attach(void) { + /* If module param firmware path is set then this will always be used, + * if not set then if available use the platform data version. To make + * sure it gets initialized at all, always copy the module param version + */ strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, BRCMF_FW_ALTPATH_LEN); + if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) && + (brcmf_mp_global.firmware_path[0] == '\0')) { + strlcpy(brcmf_mp_global.firmware_path, + brcmfmac_pdata->fw_alternative_path, + BRCMF_FW_ALTPATH_LEN); + } } -struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev) +struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, + enum brcmf_bus_type bus_type, + u32 chip, u32 chiprev) { - if (!brcmfmac_pdata) - brcmf_of_probe(dev, &brcmfmac_pdata); - return brcmfmac_pdata; + struct brcmfmac_sdio_pd *pdata; + struct brcmfmac_pd_device *device_pd; + int i; + + if (brcmfmac_pdata) { + for (i = 0; i < brcmfmac_pdata->device_count; i++) { + device_pd = &brcmfmac_pdata->devices[i]; + if ((device_pd->bus_type == bus_type) && + (device_pd->id == chip) && + ((device_pd->rev == chiprev) || + (device_pd->rev == -1))) { + brcmf_dbg(INFO, "Platform data for device found\n"); + if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) + return &device_pd->bus.sdio; + break; + } + } + } + pdata = NULL; + brcmf_of_probe(dev, &pdata); + + return pdata; } int brcmf_mp_device_attach(struct brcmf_pub *drvr) @@ -287,7 +318,7 @@ static int brcmf_common_pd_remove(struct platform_device *pdev) static struct platform_driver brcmf_pd = { .remove = brcmf_common_pd_remove, .driver = { - .name = BRCMFMAC_SDIO_PDATA_NAME, + .name = BRCMFMAC_PDATA_NAME, } }; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h index 54a26ede808d..a64e40e8bfda 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h @@ -16,7 +16,7 @@ #define BRCMFMAC_COMMON_H #include <linux/platform_device.h> -#include <linux/platform_data/brcmfmac-sdio.h> +#include <linux/platform_data/brcmfmac.h> #include "fwil_types.h" extern const u8 ALLFFMAC[ETH_ALEN]; @@ -43,33 +43,6 @@ struct brcmf_mp_global_t { extern struct brcmf_mp_global_t brcmf_mp_global; /** - * struct cc_entry - Struct for translating user space country code (iso3166) to - * firmware country code and revision. - * - * @iso3166: iso3166 alpha 2 country code string. - * @cc: firmware country code string. - * @rev: firmware country code revision. - */ -struct cc_entry { - char iso3166[BRCMF_COUNTRY_BUF_SZ]; - char cc[BRCMF_COUNTRY_BUF_SZ]; - s32 rev; -}; - -/** - * struct cc_translate - Struct for translating country codes as set by user - * space to a country code and rev which can be used by - * firmware. - * - * @table_size: number of entries in table (> 0) - * @table: dynamic array of 1 or more elements with translation information. - */ -struct cc_translate { - int table_size; - struct cc_entry table[0]; -}; - -/** * struct brcmf_mp_device - Device module paramaters. * * @sdiod_txglomsz: SDIO txglom size. @@ -88,10 +61,12 @@ struct brcmf_mp_device { int fcmode; bool roamoff; bool ignore_probe_fail; - struct cc_translate *country_codes; + struct brcmfmac_pd_cc *country_codes; }; -struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev); +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 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index 8201d937b826..ece0b65dd039 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -23,8 +23,7 @@ #include "common.h" #include "of.h" -void -brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio) +void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) { struct device_node *np = dev->of_node; int irq; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h index 84b474484cea..1ba951f9b542 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h @@ -15,10 +15,9 @@ */ #ifdef CONFIG_OF void -brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio); +brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); #else -static void brcmf_of_probe(struct device *dev, - struct brcmfmac_sdio_platform_data **sdio) +static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) { } #endif /* CONFIG_OF */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index c790fa89db05..6e367041f691 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -33,8 +33,6 @@ #include <linux/bcma/bcma.h> #include <linux/debugfs.h> #include <linux/vmalloc.h> -#include <linux/platform_data/brcmfmac-sdio.h> -#include <linux/moduleparam.h> #include <asm/unaligned.h> #include <defs.h> #include <brcmu_wifi.h> @@ -44,6 +42,8 @@ #include "sdio.h" #include "chip.h" #include "firmware.h" +#include "core.h" +#include "common.h" #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) @@ -3775,26 +3775,28 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { static bool brcmf_sdio_probe_attach(struct brcmf_sdio *bus) { + struct brcmf_sdio_dev *sdiodev; u8 clkctl = 0; int err = 0; int reg_addr; u32 reg_val; u32 drivestrength; - sdio_claim_host(bus->sdiodev->func[1]); + sdiodev = bus->sdiodev; + sdio_claim_host(sdiodev->func[1]); pr_debug("F1 signature read @0x18000000=0x%4x\n", - brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); + brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); /* * Force PLL off until brcmf_chip_attach() * programs PLL control regs */ - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1, &err); if (!err) - clkctl = brcmf_sdiod_regrb(bus->sdiodev, + clkctl = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { @@ -3803,50 +3805,77 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) goto fail; } - bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); + bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops); if (IS_ERR(bus->ci)) { brcmf_err("brcmf_chip_attach failed!\n"); bus->ci = NULL; goto fail; } + sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, + bus->ci->chiprev); + /* 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; + } + /* allocate scatter-gather table. sg support + * will be disabled upon allocation failure. + */ + brcmf_sdiod_sgtable_alloc(sdiodev); + +#ifdef CONFIG_PM_SLEEP + /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ + * is true or when platform data OOB irq is true). + */ + 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->bus_if->wowl_supported = true; +#endif if (brcmf_sdio_kso_init(bus)) { brcmf_err("error enabling KSO\n"); goto fail; } - if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) - drivestrength = bus->sdiodev->pdata->drive_strength; + if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) + drivestrength = sdiodev->pdata->drive_strength; else drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; - brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); + brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); /* Set card control so an SDIO card reset does a WLAN backplane reset */ - reg_val = brcmf_sdiod_regrb(bus->sdiodev, - SDIO_CCCR_BRCM_CARDCTRL, &err); + reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); if (err) goto fail; reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; - brcmf_sdiod_regwb(bus->sdiodev, - SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); if (err) goto fail; /* set PMUControl so a backplane reset does PMU state reload */ reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); - reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); + reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); if (err) goto fail; reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); - brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err); + brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); if (err) goto fail; - sdio_release_host(bus->sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); @@ -3867,7 +3896,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) return true; fail: - sdio_release_host(bus->sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); return false; } @@ -4045,18 +4074,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) bus->txminmax = BRCMF_TXMINMAX; bus->tx_seq = SDPCM_SEQ_WRAP - 1; - /* 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; - } - /* single-threaded workqueue */ wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM, dev_name(&sdiodev->func[1]->dev)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 23f223150cef..50df9cb21af2 100644 --- 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_platform_data *pdata; + struct brcmfmac_sdio_pd *pdata; bool oob_irq_requested; bool irq_en; /* irq enable flags */ spinlock_t irq_en_lock; |