diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c')
-rw-r--r-- | kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c index ab0c89833..7e74ac3ad 100644 --- a/kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +++ b/kernel/drivers/net/wireless/brcm80211/brcmfmac/sdio.c @@ -15,6 +15,7 @@ */ #include <linux/types.h> +#include <linux/atomic.h> #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/printk.h> @@ -123,6 +124,7 @@ struct rte_console { #define BRCMF_FIRSTREAD (1 << 6) +#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */ /* SBSDIO_DEVICE_CTL */ @@ -601,6 +603,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { #define BCM43241B0_NVRAM_NAME "brcm/brcmfmac43241b0-sdio.txt" #define BCM43241B4_FIRMWARE_NAME "brcm/brcmfmac43241b4-sdio.bin" #define BCM43241B4_NVRAM_NAME "brcm/brcmfmac43241b4-sdio.txt" +#define BCM43241B5_FIRMWARE_NAME "brcm/brcmfmac43241b5-sdio.bin" +#define BCM43241B5_NVRAM_NAME "brcm/brcmfmac43241b5-sdio.txt" #define BCM4329_FIRMWARE_NAME "brcm/brcmfmac4329-sdio.bin" #define BCM4329_NVRAM_NAME "brcm/brcmfmac4329-sdio.txt" #define BCM4330_FIRMWARE_NAME "brcm/brcmfmac4330-sdio.bin" @@ -628,6 +632,8 @@ MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME); MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME); MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME); MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME); +MODULE_FIRMWARE(BCM43241B5_FIRMWARE_NAME); +MODULE_FIRMWARE(BCM43241B5_NVRAM_NAME); MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4329_NVRAM_NAME); MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME); @@ -667,7 +673,8 @@ enum brcmf_firmware_type { static const struct brcmf_firmware_names brcmf_fwname_data[] = { { BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) }, { BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) }, - { BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, + { BRCM_CC_43241_CHIP_ID, 0x00000020, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, + { BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43241B5) }, { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, @@ -2559,15 +2566,6 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) } } -static void atomic_orr(int val, atomic_t *v) -{ - int old_val; - - old_val = atomic_read(v); - while (atomic_cmpxchg(v, old_val, val | old_val) != old_val) - old_val = atomic_read(v); -} - static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) { struct brcmf_core *buscore; @@ -2590,7 +2588,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) if (val) { brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); bus->sdcnt.f1regdata++; - atomic_orr(val, &bus->intstatus); + atomic_or(val, &bus->intstatus); } return ret; @@ -2707,7 +2705,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) /* Keep still-pending events for next scheduling */ if (intstatus) - atomic_orr(intstatus, &bus->intstatus); + atomic_or(intstatus, &bus->intstatus); brcmf_sdio_clrintr(bus); @@ -2815,6 +2813,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); + if (sdiodev->state != BRCMF_SDIOD_DATA) + return -EIO; /* Add space for the header */ skb_push(pkt, bus->tx_hdrlen); @@ -2943,6 +2943,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) int ret; brcmf_dbg(TRACE, "Enter\n"); + if (sdiodev->state != BRCMF_SDIOD_DATA) + return -EIO; /* Send from dpc */ bus->ctrl_frame_buf = msg; @@ -3204,6 +3206,8 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) if (IS_ERR_OR_NULL(dentry)) return; + bus->console_interval = BRCMF_CONSOLE; + brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read); brcmf_debugfs_add_entry(drvr, "counters", brcmf_debugfs_sdio_count_read); @@ -3233,6 +3237,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter\n"); + if (sdiodev->state != BRCMF_SDIOD_DATA) + return -EIO; /* Wait until control frame is available */ timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); @@ -3533,6 +3539,51 @@ done: return err; } +static size_t brcmf_sdio_bus_get_ramsize(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; + + return bus->ci->ramsize - bus->ci->srsize; +} + +static int brcmf_sdio_bus_get_memdump(struct device *dev, void *data, + size_t mem_size) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; + int err; + int address; + int offset; + int len; + + brcmf_dbg(INFO, "dump at 0x%08x: size=%zu\n", bus->ci->rambase, + mem_size); + + address = bus->ci->rambase; + offset = err = 0; + sdio_claim_host(sdiodev->func[1]); + while (offset < mem_size) { + len = ((offset + MEMBLOCK) < mem_size) ? MEMBLOCK : + mem_size - offset; + err = brcmf_sdiod_ramrw(sdiodev, false, address, data, len); + if (err) { + brcmf_err("error %d on reading %d membytes at 0x%08x\n", + err, len, address); + goto done; + } + data += len; + offset += len; + address += len; + } + +done: + sdio_release_host(sdiodev->func[1]); + return err; +} + void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus) { if (!bus->dpc_triggered) { @@ -3550,10 +3601,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) return; } - if (bus->sdiodev->state != BRCMF_SDIOD_DATA) { - brcmf_err("bus is down. we have nothing to do\n"); - return; - } /* Count the interrupt call */ bus->sdcnt.intrcount++; if (in_interrupt()) @@ -3615,7 +3662,7 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) } #ifdef DEBUG /* Poll for console output periodically */ - if (bus->sdiodev->state == BRCMF_SDIOD_DATA && + if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() && bus->console_interval != 0) { bus->console.count += BRCMF_WD_POLL_MS; if (bus->console.count >= bus->console_interval) { @@ -3985,7 +4032,9 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .txctl = brcmf_sdio_bus_txctl, .rxctl = brcmf_sdio_bus_rxctl, .gettxq = brcmf_sdio_bus_gettxq, - .wowl_config = brcmf_sdio_wowl_config + .wowl_config = brcmf_sdio_wowl_config, + .get_ramsize = brcmf_sdio_bus_get_ramsize, + .get_memdump = brcmf_sdio_bus_get_memdump, }; static void brcmf_sdio_firmware_callback(struct device *dev, |