From: Rafał Miłecki Date: Sat, 9 Jan 2016 18:37:55 +0000 (+0000) Subject: mac80211: group brcmfmac patches into sets as they were sent X-Git-Url: http://207.154.207.93/?a=commitdiff_plain;h=437dd4cacf0e424048022c45ba4721534872e6b4;p=15.05%2Fopenwrt.git mac80211: group brcmfmac patches into sets as they were sent It doesn't change any single patch (or order), it only renames files. This creates some place for more backports, as we were already using 398 prefix which left only 1 slot. Signed-off-by: Rafał Miłecki git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@48163 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- diff --git a/package/kernel/mac80211/patches/335-0001-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch b/package/kernel/mac80211/patches/335-0001-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch new file mode 100644 index 0000000000..5e63a803b0 --- /dev/null +++ b/package/kernel/mac80211/patches/335-0001-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch @@ -0,0 +1,44 @@ +From: Hante Meuleman +Date: Fri, 6 Mar 2015 18:40:38 +0100 +Subject: [PATCH] brcmfmac: Fix oops when SDIO device is removed. + +On removal of SDIO card both functions of card will be getting +a remove call. When the first is hanging in ctrl frame xmit then +the second will cause oops. This patch fixes the xmit ctrl +handling in case of serious errors and also limits the handling +for remove to function 1 only. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1194,7 +1194,7 @@ static void brcmf_ops_sdio_remove(struct + brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); + brcmf_dbg(SDIO, "Function: %d\n", func->num); + +- if (func->num != 1 && func->num != 2) ++ if (func->num != 1) + return; + + bus_if = dev_get_drvdata(&func->dev); +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -2740,6 +2740,11 @@ static void brcmf_sdio_dpc(struct brcmf_ + if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) { + brcmf_err("failed backplane access over SDIO, halting operation\n"); + atomic_set(&bus->intstatus, 0); ++ if (bus->ctrl_frame_stat) { ++ bus->ctrl_frame_err = -ENODEV; ++ bus->ctrl_frame_stat = false; ++ brcmf_sdio_wait_event_wakeup(bus); ++ } + } else if (atomic_read(&bus->intstatus) || + atomic_read(&bus->ipend) > 0 || + (!atomic_read(&bus->fcstate) && diff --git a/package/kernel/mac80211/patches/335-0002-brcmfmac-Simplify-watchdog-sleep.patch b/package/kernel/mac80211/patches/335-0002-brcmfmac-Simplify-watchdog-sleep.patch new file mode 100644 index 0000000000..201da75bfc --- /dev/null +++ b/package/kernel/mac80211/patches/335-0002-brcmfmac-Simplify-watchdog-sleep.patch @@ -0,0 +1,157 @@ +From: Hante Meuleman +Date: Fri, 6 Mar 2015 18:40:39 +0100 +Subject: [PATCH] brcmfmac: Simplify watchdog sleep. + +The watchdog thread is used to put the SDIO bus to sleep when the +system is idling. This patch simplifies the way it is determined +when sleep can be entered. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -485,10 +485,9 @@ struct brcmf_sdio { + #endif /* DEBUG */ + + uint clkstate; /* State of sd and backplane clock(s) */ +- bool activity; /* Activity flag for clock down */ + s32 idletime; /* Control for activity timeout */ +- s32 idlecount; /* Activity timeout counter */ +- s32 idleclock; /* How to set bus driver when idle */ ++ s32 idlecount; /* Activity timeout counter */ ++ s32 idleclock; /* How to set bus driver when idle */ + bool rxflow_mode; /* Rx flow control mode */ + bool rxflow; /* Is rx flow control on */ + bool alp_only; /* Don't use HT clock (ALP only) */ +@@ -511,6 +510,7 @@ struct brcmf_sdio { + struct workqueue_struct *brcmf_wq; + struct work_struct datawork; + atomic_t dpc_tskcnt; ++ atomic_t dpc_running; + + bool txoff; /* Transmit flow-controlled */ + struct brcmf_sdio_count sdcnt; +@@ -959,13 +959,8 @@ static int brcmf_sdio_clkctl(struct brcm + brcmf_dbg(SDIO, "Enter\n"); + + /* Early exit if we're already there */ +- if (bus->clkstate == target) { +- if (target == CLK_AVAIL) { +- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); +- bus->activity = true; +- } ++ if (bus->clkstate == target) + return 0; +- } + + switch (target) { + case CLK_AVAIL: +@@ -975,7 +970,6 @@ static int brcmf_sdio_clkctl(struct brcm + /* Now request HT Avail on the backplane */ + brcmf_sdio_htclk(bus, true, pendok); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); +- bus->activity = true; + break; + + case CLK_SDONLY: +@@ -1024,17 +1018,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * + + /* Going to sleep */ + if (sleep) { +- /* Don't sleep if something is pending */ +- if (atomic_read(&bus->intstatus) || +- atomic_read(&bus->ipend) > 0 || +- bus->ctrl_frame_stat || +- (!atomic_read(&bus->fcstate) && +- brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && +- data_ok(bus))) { +- err = -EBUSY; +- goto done; +- } +- + clkcsr = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); +@@ -1045,11 +1028,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * + SBSDIO_ALP_AVAIL_REQ, &err); + } + err = brcmf_sdio_kso_control(bus, false); +- /* disable watchdog */ +- if (!err) +- brcmf_sdio_wd_timer(bus, 0); + } else { +- bus->idlecount = 0; + err = brcmf_sdio_kso_control(bus, true); + } + if (err) { +@@ -3566,7 +3545,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b + queue_work(bus->brcmf_wq, &bus->datawork); + } + +-static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) ++static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) + { + brcmf_dbg(TIMER, "Enter\n"); + +@@ -3627,22 +3606,21 @@ static bool brcmf_sdio_bus_watchdog(stru + #endif /* DEBUG */ + + /* On idle timeout clear activity flag and/or turn off clock */ +- if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { +- if (++bus->idlecount >= bus->idletime) { ++ if ((atomic_read(&bus->dpc_tskcnt) == 0) && ++ (atomic_read(&bus->dpc_running) == 0) && ++ (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { ++ bus->idlecount++; ++ if (bus->idlecount > bus->idletime) { ++ brcmf_dbg(SDIO, "idle\n"); ++ sdio_claim_host(bus->sdiodev->func[1]); ++ brcmf_sdio_wd_timer(bus, 0); + bus->idlecount = 0; +- if (bus->activity) { +- bus->activity = false; +- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); +- } else { +- brcmf_dbg(SDIO, "idle\n"); +- sdio_claim_host(bus->sdiodev->func[1]); +- brcmf_sdio_bus_sleep(bus, true, false); +- sdio_release_host(bus->sdiodev->func[1]); +- } ++ brcmf_sdio_bus_sleep(bus, true, false); ++ sdio_release_host(bus->sdiodev->func[1]); + } ++ } else { ++ bus->idlecount = 0; + } +- +- return (atomic_read(&bus->ipend) > 0); + } + + static void brcmf_sdio_dataworker(struct work_struct *work) +@@ -3651,8 +3629,11 @@ static void brcmf_sdio_dataworker(struct + datawork); + + while (atomic_read(&bus->dpc_tskcnt)) { ++ atomic_set(&bus->dpc_running, 1); + atomic_set(&bus->dpc_tskcnt, 0); + brcmf_sdio_dpc(bus); ++ bus->idlecount = 0; ++ atomic_set(&bus->dpc_running, 0); + } + if (brcmf_sdiod_freezing(bus->sdiodev)) { + brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); +@@ -4154,6 +4135,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + } + /* Initialize DPC thread */ + atomic_set(&bus->dpc_tskcnt, 0); ++ atomic_set(&bus->dpc_running, 0); + + /* Assign bus interface call back */ + bus->sdiodev->bus_if->dev = bus->sdiodev->dev; diff --git a/package/kernel/mac80211/patches/335-0003-brcmfmac-Fix-possible-race-condition.patch b/package/kernel/mac80211/patches/335-0003-brcmfmac-Fix-possible-race-condition.patch new file mode 100644 index 0000000000..3a2de7a944 --- /dev/null +++ b/package/kernel/mac80211/patches/335-0003-brcmfmac-Fix-possible-race-condition.patch @@ -0,0 +1,83 @@ +From: Hante Meuleman +Date: Fri, 6 Mar 2015 18:40:40 +0100 +Subject: [PATCH] brcmfmac: Fix possible race-condition. + +SDIO is using a "shared" variable to handoff ctl frames to DPC +and to see when they are done. In a timeout situation this can +lead to erroneous situation where DPC started to handle the ctl +frame while the timeout expired. This patch will fix this by +adding locking around the shared variable. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -2700,11 +2700,13 @@ static void brcmf_sdio_dpc(struct brcmf_ + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && + data_ok(bus)) { + sdio_claim_host(bus->sdiodev->func[1]); +- err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, +- bus->ctrl_frame_len); ++ if (bus->ctrl_frame_stat) { ++ err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, ++ bus->ctrl_frame_len); ++ bus->ctrl_frame_err = err; ++ bus->ctrl_frame_stat = false; ++ } + sdio_release_host(bus->sdiodev->func[1]); +- bus->ctrl_frame_err = err; +- bus->ctrl_frame_stat = false; + brcmf_sdio_wait_event_wakeup(bus); + } + /* Send queued frames (limit 1 if rx may still be pending) */ +@@ -2720,9 +2722,13 @@ static void brcmf_sdio_dpc(struct brcmf_ + brcmf_err("failed backplane access over SDIO, halting operation\n"); + atomic_set(&bus->intstatus, 0); + if (bus->ctrl_frame_stat) { +- bus->ctrl_frame_err = -ENODEV; +- bus->ctrl_frame_stat = false; +- brcmf_sdio_wait_event_wakeup(bus); ++ sdio_claim_host(bus->sdiodev->func[1]); ++ if (bus->ctrl_frame_stat) { ++ bus->ctrl_frame_err = -ENODEV; ++ bus->ctrl_frame_stat = false; ++ brcmf_sdio_wait_event_wakeup(bus); ++ } ++ sdio_release_host(bus->sdiodev->func[1]); + } + } else if (atomic_read(&bus->intstatus) || + atomic_read(&bus->ipend) > 0 || +@@ -2930,15 +2936,20 @@ brcmf_sdio_bus_txctl(struct device *dev, + brcmf_sdio_trigger_dpc(bus); + wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, + msecs_to_jiffies(CTL_DONE_TIMEOUT)); +- +- if (!bus->ctrl_frame_stat) { ++ ret = 0; ++ if (bus->ctrl_frame_stat) { ++ sdio_claim_host(bus->sdiodev->func[1]); ++ if (bus->ctrl_frame_stat) { ++ brcmf_dbg(SDIO, "ctrl_frame timeout\n"); ++ bus->ctrl_frame_stat = false; ++ ret = -ETIMEDOUT; ++ } ++ sdio_release_host(bus->sdiodev->func[1]); ++ } ++ if (!ret) { + brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", + bus->ctrl_frame_err); + ret = bus->ctrl_frame_err; +- } else { +- brcmf_dbg(SDIO, "ctrl_frame timeout\n"); +- bus->ctrl_frame_stat = false; +- ret = -ETIMEDOUT; + } + + if (ret) diff --git a/package/kernel/mac80211/patches/335-0004-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch b/package/kernel/mac80211/patches/335-0004-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch new file mode 100644 index 0000000000..c9eb9008a6 --- /dev/null +++ b/package/kernel/mac80211/patches/335-0004-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch @@ -0,0 +1,86 @@ +From: Syed Asifful Dayyan +Date: Fri, 6 Mar 2015 18:40:42 +0100 +Subject: [PATCH] brcmfmac: Add support for BCM4345 SDIO chipset. + +These changes add support for BCM4345 SDIO chipset. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Arend Van Spriel +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Syed Asifful Dayyan +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1096,6 +1096,7 @@ static const struct sdio_device_id brcmf + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), + { /* end: all zeroes */ } + }; +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -491,6 +491,10 @@ static void brcmf_chip_get_raminfo(struc + case BRCM_CC_43362_CHIP_ID: + ci->pub.ramsize = 0x3c000; + break; ++ case BRCM_CC_4345_CHIP_ID: ++ ci->pub.ramsize = 0xc8000; ++ ci->pub.rambase = 0x198000; ++ break; + case BRCM_CC_4339_CHIP_ID: + case BRCM_CC_4354_CHIP_ID: + case BRCM_CC_4356_CHIP_ID: +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -617,6 +617,8 @@ static const struct sdiod_drive_str sdio + #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" + #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" + #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" ++#define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" ++#define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" + #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" + #define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt" + +@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM43362_NVRAM_NAME); + MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4339_NVRAM_NAME); ++MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); ++MODULE_FIRMWARE(BCM4345_NVRAM_NAME); + MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4354_NVRAM_NAME); + +@@ -669,6 +673,7 @@ static const struct brcmf_firmware_names + { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, + { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, ++ { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, + { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } + }; + +--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +@@ -37,6 +37,7 @@ + #define BRCM_CC_43362_CHIP_ID 43362 + #define BRCM_CC_4335_CHIP_ID 0x4335 + #define BRCM_CC_4339_CHIP_ID 0x4339 ++#define BRCM_CC_4345_CHIP_ID 0x4345 + #define BRCM_CC_4354_CHIP_ID 0x4354 + #define BRCM_CC_4356_CHIP_ID 0x4356 + #define BRCM_CC_43566_CHIP_ID 43566 +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -33,6 +33,7 @@ + #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d + #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 + #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 ++#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 + #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 + + #define SDIO_VENDOR_ID_INTEL 0x0089 diff --git a/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch b/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch deleted file mode 100644 index 5e63a803b0..0000000000 --- a/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Hante Meuleman -Date: Fri, 6 Mar 2015 18:40:38 +0100 -Subject: [PATCH] brcmfmac: Fix oops when SDIO device is removed. - -On removal of SDIO card both functions of card will be getting -a remove call. When the first is hanging in ctrl frame xmit then -the second will cause oops. This patch fixes the xmit ctrl -handling in case of serious errors and also limits the handling -for remove to function 1 only. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -1194,7 +1194,7 @@ static void brcmf_ops_sdio_remove(struct - brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(SDIO, "Function: %d\n", func->num); - -- if (func->num != 1 && func->num != 2) -+ if (func->num != 1) - return; - - bus_if = dev_get_drvdata(&func->dev); ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -2740,6 +2740,11 @@ static void brcmf_sdio_dpc(struct brcmf_ - if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) { - brcmf_err("failed backplane access over SDIO, halting operation\n"); - atomic_set(&bus->intstatus, 0); -+ if (bus->ctrl_frame_stat) { -+ bus->ctrl_frame_err = -ENODEV; -+ bus->ctrl_frame_stat = false; -+ brcmf_sdio_wait_event_wakeup(bus); -+ } - } else if (atomic_read(&bus->intstatus) || - atomic_read(&bus->ipend) > 0 || - (!atomic_read(&bus->fcstate) && diff --git a/package/kernel/mac80211/patches/336-0001-brcmfmac-remove-duplication-of-ramsize-info.patch b/package/kernel/mac80211/patches/336-0001-brcmfmac-remove-duplication-of-ramsize-info.patch new file mode 100644 index 0000000000..7a688c4be6 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0001-brcmfmac-remove-duplication-of-ramsize-info.patch @@ -0,0 +1,48 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:27 +0100 +Subject: [PATCH] brcmfmac: remove duplication of ramsize info + +Removing the ramsize from the brcmf_sdio structure to avoid +duplication. The information is available in brcmf_chip +structure. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -432,8 +432,6 @@ struct brcmf_sdio { + struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ + struct brcmf_chip *ci; /* Chip info struct */ + +- u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ +- + u32 hostintmask; /* Copy of Host Interrupt Mask */ + atomic_t intstatus; /* Intstatus bits (events) pending */ + atomic_t fcstate; /* State of dongle flow-control */ +@@ -1075,7 +1073,7 @@ static int brcmf_sdio_readshared(struct + struct sdpcm_shared_le sh_le; + __le32 addr_le; + +- shaddr = bus->ci->rambase + bus->ramsize - 4; ++ shaddr = bus->ci->rambase + bus->ci->ramsize - 4; + + /* + * Read last word in socram to determine +@@ -3871,13 +3869,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; + brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); + +- /* Get info on the SOCRAM cores... */ +- bus->ramsize = bus->ci->ramsize; +- if (!(bus->ramsize)) { +- brcmf_err("failed to find SOCRAM memory!\n"); +- goto fail; +- } +- + /* 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); diff --git a/package/kernel/mac80211/patches/336-0002-brcmfmac-always-perform-cores-checks.patch b/package/kernel/mac80211/patches/336-0002-brcmfmac-always-perform-cores-checks.patch new file mode 100644 index 0000000000..e2a2074247 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0002-brcmfmac-always-perform-cores-checks.patch @@ -0,0 +1,74 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:28 +0100 +Subject: [PATCH] brcmfmac: always perform cores checks + +Instead of checking the cores in the chip only if CONFIG_BRCMDBG +is selected perform the check always and extend it with more sanity +checking. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -419,13 +419,13 @@ static struct brcmf_core *brcmf_chip_add + return &core->pub; + } + +-#ifdef DEBUG + /* safety check for chipinfo */ + static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) + { + struct brcmf_core_priv *core; + bool need_socram = false; + bool has_socram = false; ++ bool cpu_found = false; + int idx = 1; + + list_for_each_entry(core, &ci->cores, list) { +@@ -435,12 +435,14 @@ static int brcmf_chip_cores_check(struct + + switch (core->pub.id) { + case BCMA_CORE_ARM_CM3: ++ cpu_found = true; + need_socram = true; + break; + case BCMA_CORE_INTERNAL_MEM: + has_socram = true; + break; + case BCMA_CORE_ARM_CR4: ++ cpu_found = true; + if (ci->pub.rambase == 0) { + brcmf_err("RAM base not provided with ARM CR4 core\n"); + return -ENOMEM; +@@ -451,19 +453,21 @@ static int brcmf_chip_cores_check(struct + } + } + ++ if (!cpu_found) { ++ brcmf_err("CPU core not detected\n"); ++ return -ENXIO; ++ } + /* check RAM core presence for ARM CM3 core */ + if (need_socram && !has_socram) { + brcmf_err("RAM core not provided with ARM CM3 core\n"); + return -ENODEV; + } ++ if (!ci->pub.ramsize) { ++ brcmf_err("RAM size is undetermined\n"); ++ return -ENOMEM; ++ } + return 0; + } +-#else /* DEBUG */ +-static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) +-{ +- return 0; +-} +-#endif + + static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) + { diff --git a/package/kernel/mac80211/patches/336-0003-brcmfmac-rename-chip-download-functions.patch b/package/kernel/mac80211/patches/336-0003-brcmfmac-rename-chip-download-functions.patch new file mode 100644 index 0000000000..a272800577 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0003-brcmfmac-rename-chip-download-functions.patch @@ -0,0 +1,240 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:29 +0100 +Subject: [PATCH] brcmfmac: rename chip download functions + +The functions brcmf_chip_[enter/exit]_download() are not exclusively +used for firmware download so rename these more appropriate. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -807,7 +807,7 @@ struct brcmf_chip *brcmf_chip_attach(voi + err = -EINVAL; + if (WARN_ON(!ops->prepare)) + err = -EINVAL; +- if (WARN_ON(!ops->exit_dl)) ++ if (WARN_ON(!ops->activate)) + err = -EINVAL; + if (err < 0) + return ERR_PTR(-EINVAL); +@@ -905,7 +905,7 @@ void brcmf_chip_resetcore(struct brcmf_c + } + + static void +-brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip) ++brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip) + { + struct brcmf_core *core; + +@@ -919,7 +919,7 @@ brcmf_chip_cm3_enterdl(struct brcmf_chip + brcmf_chip_resetcore(core, 0, 0, 0); + } + +-static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip) ++static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip) + { + struct brcmf_core *core; + +@@ -929,7 +929,7 @@ static bool brcmf_chip_cm3_exitdl(struct + return false; + } + +- chip->ops->exit_dl(chip->ctx, &chip->pub, 0); ++ chip->ops->activate(chip->ctx, &chip->pub, 0); + + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3); + brcmf_chip_resetcore(core, 0, 0, 0); +@@ -938,7 +938,7 @@ static bool brcmf_chip_cm3_exitdl(struct + } + + static inline void +-brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip) ++brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip) + { + struct brcmf_core *core; + +@@ -951,11 +951,11 @@ brcmf_chip_cr4_enterdl(struct brcmf_chip + D11_BCMA_IOCTL_PHYCLOCKEN); + } + +-static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec) ++static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec) + { + struct brcmf_core *core; + +- chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec); ++ chip->ops->activate(chip->ctx, &chip->pub, rstvec); + + /* restore ARM */ + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4); +@@ -964,7 +964,7 @@ static bool brcmf_chip_cr4_exitdl(struct + return true; + } + +-void brcmf_chip_enter_download(struct brcmf_chip *pub) ++void brcmf_chip_set_passive(struct brcmf_chip *pub) + { + struct brcmf_chip_priv *chip; + struct brcmf_core *arm; +@@ -974,14 +974,14 @@ void brcmf_chip_enter_download(struct br + chip = container_of(pub, struct brcmf_chip_priv, pub); + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); + if (arm) { +- brcmf_chip_cr4_enterdl(chip); ++ brcmf_chip_cr4_set_passive(chip); + return; + } + +- brcmf_chip_cm3_enterdl(chip); ++ brcmf_chip_cm3_set_passive(chip); + } + +-bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec) ++bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec) + { + struct brcmf_chip_priv *chip; + struct brcmf_core *arm; +@@ -991,9 +991,9 @@ bool brcmf_chip_exit_download(struct brc + chip = container_of(pub, struct brcmf_chip_priv, pub); + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); + if (arm) +- return brcmf_chip_cr4_exitdl(chip, rstvec); ++ return brcmf_chip_cr4_set_active(chip, rstvec); + +- return brcmf_chip_cm3_exitdl(chip); ++ return brcmf_chip_cm3_set_active(chip); + } + + bool brcmf_chip_sr_capable(struct brcmf_chip *pub) +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h +@@ -64,7 +64,7 @@ struct brcmf_core { + * @write32: write 32-bit value over bus. + * @prepare: prepare bus for core configuration. + * @setup: bus-specific core setup. +- * @exit_dl: exit download state. ++ * @active: chip becomes active. + * The callback should use the provided @rstvec when non-zero. + */ + struct brcmf_buscore_ops { +@@ -72,7 +72,7 @@ struct brcmf_buscore_ops { + void (*write32)(void *ctx, u32 addr, u32 value); + int (*prepare)(void *ctx); + int (*setup)(void *ctx, struct brcmf_chip *chip); +- void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec); ++ void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); + }; + + struct brcmf_chip *brcmf_chip_attach(void *ctx, +@@ -84,8 +84,8 @@ bool brcmf_chip_iscoreup(struct brcmf_co + void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset); + void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, + u32 postreset); +-void brcmf_chip_enter_download(struct brcmf_chip *ci); +-bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec); ++void brcmf_chip_set_passive(struct brcmf_chip *ci); ++bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); + bool brcmf_chip_sr_capable(struct brcmf_chip *pub); + + #endif /* BRCMF_AXIDMP_H */ +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -509,7 +509,7 @@ static void brcmf_pcie_attach(struct brc + + static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + { +- brcmf_chip_enter_download(devinfo->ci); ++ brcmf_chip_set_passive(devinfo->ci); + + if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { + brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); +@@ -536,7 +536,7 @@ static int brcmf_pcie_exit_download_stat + brcmf_chip_resetcore(core, 0, 0, 0); + } + +- return !brcmf_chip_exit_download(devinfo->ci, resetintr); ++ return !brcmf_chip_set_active(devinfo->ci, resetintr); + } + + +@@ -1566,8 +1566,8 @@ static int brcmf_pcie_buscoreprep(void * + } + + +-static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip, +- u32 rstvec) ++static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, ++ u32 rstvec) + { + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; + +@@ -1577,7 +1577,7 @@ static void brcmf_pcie_buscore_exitdl(vo + + static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { + .prepare = brcmf_pcie_buscoreprep, +- .exit_dl = brcmf_pcie_buscore_exitdl, ++ .activate = brcmf_pcie_buscore_activate, + .read32 = brcmf_pcie_buscore_read32, + .write32 = brcmf_pcie_buscore_write32, + }; +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -3357,7 +3357,7 @@ static int brcmf_sdio_download_firmware( + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + + /* Keep arm in reset */ +- brcmf_chip_enter_download(bus->ci); ++ brcmf_chip_set_passive(bus->ci); + + rstvec = get_unaligned_le32(fw->data); + brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); +@@ -3378,7 +3378,7 @@ static int brcmf_sdio_download_firmware( + } + + /* Take arm out of reset */ +- if (!brcmf_chip_exit_download(bus->ci, rstvec)) { ++ if (!brcmf_chip_set_active(bus->ci, rstvec)) { + brcmf_err("error getting out of ARM core reset\n"); + goto err; + } +@@ -3771,8 +3771,8 @@ static int brcmf_sdio_buscoreprep(void * + return 0; + } + +-static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip, +- u32 rstvec) ++static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip, ++ u32 rstvec) + { + struct brcmf_sdio_dev *sdiodev = ctx; + struct brcmf_core *core; +@@ -3815,7 +3815,7 @@ static void brcmf_sdio_buscore_write32(v + + static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { + .prepare = brcmf_sdio_buscoreprep, +- .exit_dl = brcmf_sdio_buscore_exitdl, ++ .activate = brcmf_sdio_buscore_activate, + .read32 = brcmf_sdio_buscore_read32, + .write32 = brcmf_sdio_buscore_write32, + }; +@@ -4239,12 +4239,11 @@ void brcmf_sdio_remove(struct brcmf_sdio + sdio_claim_host(bus->sdiodev->func[1]); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + /* Leave the device in state where it is +- * 'quiet'. This is done by putting it in +- * download_state which essentially resets +- * all necessary cores. ++ * 'passive'. This is done by resetting all ++ * necessary cores. + */ + msleep(20); +- brcmf_chip_enter_download(bus->ci); ++ brcmf_chip_set_passive(bus->ci); + brcmf_sdio_clkctl(bus, CLK_NONE, false); + sdio_release_host(bus->sdiodev->func[1]); + } diff --git a/package/kernel/mac80211/patches/336-0004-brcmfmac-assure-device-is-ready-for-download-after-b.patch b/package/kernel/mac80211/patches/336-0004-brcmfmac-assure-device-is-ready-for-download-after-b.patch new file mode 100644 index 0000000000..6b1dd8144f --- /dev/null +++ b/package/kernel/mac80211/patches/336-0004-brcmfmac-assure-device-is-ready-for-download-after-b.patch @@ -0,0 +1,61 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:30 +0100 +Subject: [PATCH] brcmfmac: assure device is ready for download after + brcmf_chip_attach() + +Make the brcmf_chip_attach() function responsible for putting the +device in a state where it is accessible for firmware download. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -786,12 +786,6 @@ static int brcmf_chip_setup(struct brcmf + if (chip->ops->setup) + ret = chip->ops->setup(chip->ctx, pub); + +- /* +- * Make sure any on-chip ARM is off (in case strapping is wrong), +- * or downloaded code was already running. +- */ +- brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3); +- brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4); + return ret; + } + +@@ -833,6 +827,8 @@ struct brcmf_chip *brcmf_chip_attach(voi + if (err < 0) + goto fail; + ++ /* assure chip is passive for download */ ++ brcmf_chip_set_passive(&chip->pub); + return &chip->pub; + + fail: +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -509,8 +509,6 @@ static void brcmf_pcie_attach(struct brc + + static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + { +- brcmf_chip_set_passive(devinfo->ci); +- + if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { + brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -3356,9 +3356,6 @@ static int brcmf_sdio_download_firmware( + sdio_claim_host(bus->sdiodev->func[1]); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + +- /* Keep arm in reset */ +- brcmf_chip_set_passive(bus->ci); +- + rstvec = get_unaligned_le32(fw->data); + brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); + diff --git a/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch b/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch new file mode 100644 index 0000000000..bcc2ed4868 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch @@ -0,0 +1,367 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:31 +0100 +Subject: [PATCH] brcmfmac: extract ram size info from internal memory + registers + +Instead of hard-coded memory sizes it is possible to obtain that +information from the internal memory registers. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -100,9 +100,6 @@ + #define BCM4329_CORE_SOCRAM_BASE 0x18003000 + /* ARM Cortex M3 core, ID 0x82a */ + #define BCM4329_CORE_ARM_BASE 0x18002000 +-#define BCM4329_RAMSIZE 0x48000 +-/* bcm43143 */ +-#define BCM43143_RAMSIZE 0x70000 + + #define CORE_SB(base, field) \ + (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) +@@ -150,6 +147,78 @@ struct sbconfig { + u32 sbidhigh; /* identification */ + }; + ++/* bankidx and bankinfo reg defines corerev >= 8 */ ++#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 ++#define SOCRAM_BANKINFO_SZMASK 0x0000007f ++#define SOCRAM_BANKIDX_ROM_MASK 0x00000100 ++ ++#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 ++/* socram bankinfo memtype */ ++#define SOCRAM_MEMTYPE_RAM 0 ++#define SOCRAM_MEMTYPE_R0M 1 ++#define SOCRAM_MEMTYPE_DEVRAM 2 ++ ++#define SOCRAM_BANKINFO_SZBASE 8192 ++#define SRCI_LSS_MASK 0x00f00000 ++#define SRCI_LSS_SHIFT 20 ++#define SRCI_SRNB_MASK 0xf0 ++#define SRCI_SRNB_SHIFT 4 ++#define SRCI_SRBSZ_MASK 0xf ++#define SRCI_SRBSZ_SHIFT 0 ++#define SR_BSZ_BASE 14 ++ ++struct sbsocramregs { ++ u32 coreinfo; ++ u32 bwalloc; ++ u32 extracoreinfo; ++ u32 biststat; ++ u32 bankidx; ++ u32 standbyctrl; ++ ++ u32 errlogstatus; /* rev 6 */ ++ u32 errlogaddr; /* rev 6 */ ++ /* used for patching rev 3 & 5 */ ++ u32 cambankidx; ++ u32 cambankstandbyctrl; ++ u32 cambankpatchctrl; ++ u32 cambankpatchtblbaseaddr; ++ u32 cambankcmdreg; ++ u32 cambankdatareg; ++ u32 cambankmaskreg; ++ u32 PAD[1]; ++ u32 bankinfo; /* corev 8 */ ++ u32 bankpda; ++ u32 PAD[14]; ++ u32 extmemconfig; ++ u32 extmemparitycsr; ++ u32 extmemparityerrdata; ++ u32 extmemparityerrcnt; ++ u32 extmemwrctrlandsize; ++ u32 PAD[84]; ++ u32 workaround; ++ u32 pwrctl; /* corerev >= 2 */ ++ u32 PAD[133]; ++ u32 sr_control; /* corerev >= 15 */ ++ u32 sr_status; /* corerev >= 15 */ ++ u32 sr_address; /* corerev >= 15 */ ++ u32 sr_data; /* corerev >= 15 */ ++}; ++ ++#define SOCRAMREGOFFS(_f) offsetof(struct sbsocramregs, _f) ++ ++#define ARMCR4_CAP (0x04) ++#define ARMCR4_BANKIDX (0x40) ++#define ARMCR4_BANKINFO (0x44) ++#define ARMCR4_BANKPDA (0x4C) ++ ++#define ARMCR4_TCBBNB_MASK 0xf0 ++#define ARMCR4_TCBBNB_SHIFT 4 ++#define ARMCR4_TCBANB_MASK 0xf ++#define ARMCR4_TCBANB_SHIFT 0 ++ ++#define ARMCR4_BSZ_MASK 0x3f ++#define ARMCR4_BSZ_MULT 8192 ++ + struct brcmf_core_priv { + struct brcmf_core pub; + u32 wrapbase; +@@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct + break; + case BCMA_CORE_ARM_CR4: + cpu_found = true; +- if (ci->pub.rambase == 0) { +- brcmf_err("RAM base not provided with ARM CR4 core\n"); +- return -ENOMEM; +- } + break; + default: + break; +@@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct + brcmf_err("RAM core not provided with ARM CM3 core\n"); + return -ENODEV; + } +- if (!ci->pub.ramsize) { +- brcmf_err("RAM size is undetermined\n"); +- return -ENOMEM; +- } + return 0; + } + +-static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) ++static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg) + { +- switch (ci->pub.chip) { +- case BRCM_CC_4329_CHIP_ID: +- ci->pub.ramsize = BCM4329_RAMSIZE; +- break; +- case BRCM_CC_43143_CHIP_ID: +- ci->pub.ramsize = BCM43143_RAMSIZE; +- break; +- case BRCM_CC_43241_CHIP_ID: +- ci->pub.ramsize = 0x90000; +- break; +- case BRCM_CC_4330_CHIP_ID: +- ci->pub.ramsize = 0x48000; +- break; ++ return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg); ++} ++ ++static void brcmf_chip_core_write32(struct brcmf_core_priv *core, ++ u16 reg, u32 val) ++{ ++ core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val); ++} ++ ++static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx, ++ u32 *banksize) ++{ ++ u32 bankinfo; ++ u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); ++ ++ bankidx |= idx; ++ brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx); ++ bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo)); ++ *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1; ++ *banksize *= SOCRAM_BANKINFO_SZBASE; ++ return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK); ++} ++ ++static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize, ++ u32 *srsize) ++{ ++ u32 coreinfo; ++ uint nb, banksize, lss; ++ bool retent; ++ int i; ++ ++ *ramsize = 0; ++ *srsize = 0; ++ ++ if (WARN_ON(sr->pub.rev < 4)) ++ return; ++ ++ if (!brcmf_chip_iscoreup(&sr->pub)) ++ brcmf_chip_resetcore(&sr->pub, 0, 0, 0); ++ ++ /* Get info for determining size */ ++ coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo)); ++ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; ++ ++ if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) { ++ banksize = (coreinfo & SRCI_SRBSZ_MASK); ++ lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; ++ if (lss != 0) ++ nb--; ++ *ramsize = nb * (1 << (banksize + SR_BSZ_BASE)); ++ if (lss != 0) ++ *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE)); ++ } else { ++ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; ++ for (i = 0; i < nb; i++) { ++ retent = brcmf_chip_socram_banksize(sr, i, &banksize); ++ *ramsize += banksize; ++ if (retent) ++ *srsize += banksize; ++ } ++ } ++ ++ /* hardcoded save&restore memory sizes */ ++ switch (sr->chip->pub.chip) { + case BRCM_CC_4334_CHIP_ID: +- case BRCM_CC_43340_CHIP_ID: +- ci->pub.ramsize = 0x80000; ++ if (sr->chip->pub.chiprev < 2) ++ *srsize = (32 * 1024); + break; +- case BRCM_CC_4335_CHIP_ID: +- ci->pub.ramsize = 0xc0000; +- ci->pub.rambase = 0x180000; +- break; +- case BRCM_CC_43362_CHIP_ID: +- ci->pub.ramsize = 0x3c000; ++ default: + break; ++ } ++} ++ ++/** Return the TCM-RAM size of the ARMCR4 core. */ ++static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4) ++{ ++ u32 corecap; ++ u32 memsize = 0; ++ u32 nab; ++ u32 nbb; ++ u32 totb; ++ u32 bxinfo; ++ u32 idx; ++ ++ corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP); ++ ++ nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT; ++ nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT; ++ totb = nab + nbb; ++ ++ for (idx = 0; idx < totb; idx++) { ++ brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx); ++ bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO); ++ memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT; ++ } ++ ++ return memsize; ++} ++ ++static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) ++{ ++ switch (ci->pub.chip) { + case BRCM_CC_4345_CHIP_ID: +- ci->pub.ramsize = 0xc8000; +- ci->pub.rambase = 0x198000; +- break; ++ return 0x198000; ++ case BRCM_CC_4335_CHIP_ID: + case BRCM_CC_4339_CHIP_ID: + case BRCM_CC_4354_CHIP_ID: + case BRCM_CC_4356_CHIP_ID: + case BRCM_CC_43567_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: + case BRCM_CC_43570_CHIP_ID: +- ci->pub.ramsize = 0xc0000; +- ci->pub.rambase = 0x180000; +- break; + case BRCM_CC_43602_CHIP_ID: +- ci->pub.ramsize = 0xf0000; +- ci->pub.rambase = 0x180000; +- break; ++ return 0x180000; + default: + brcmf_err("unknown chip: %s\n", ci->pub.name); + break; + } ++ return 0; ++} ++ ++static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) ++{ ++ struct brcmf_core_priv *mem_core; ++ struct brcmf_core *mem; ++ ++ mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4); ++ if (mem) { ++ mem_core = container_of(mem, struct brcmf_core_priv, pub); ++ ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core); ++ ci->pub.rambase = brcmf_chip_tcm_rambase(ci); ++ if (!ci->pub.rambase) { ++ brcmf_err("RAM base not provided with ARM CR4 core\n"); ++ return -EINVAL; ++ } ++ } else { ++ mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM); ++ mem_core = container_of(mem, struct brcmf_core_priv, pub); ++ brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize, ++ &ci->pub.srsize); ++ } ++ brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n", ++ ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize, ++ ci->pub.srsize, ci->pub.srsize); ++ ++ if (!ci->pub.ramsize) { ++ brcmf_err("RAM size is undetermined\n"); ++ return -ENOMEM; ++ } ++ return 0; + } + + static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr, +@@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct + struct brcmf_core *core; + u32 regdata; + u32 socitype; ++ int ret; + + /* Get CC core rev + * Chipid is assume to be at offset 0 from SI_ENUM_BASE +@@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct + return -ENODEV; + } + +- brcmf_chip_get_raminfo(ci); +- +- return brcmf_chip_cores_check(ci); ++ ret = brcmf_chip_cores_check(ci); ++ if (ret) ++ return ret; ++ ++ /* assure chip is passive for core access */ ++ brcmf_chip_set_passive(&ci->pub); ++ return brcmf_chip_get_raminfo(ci); + } + + static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) +@@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(voi + if (err < 0) + goto fail; + +- /* assure chip is passive for download */ +- brcmf_chip_set_passive(&chip->pub); + return &chip->pub; + + fail: +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h +@@ -30,7 +30,8 @@ + * @pmucaps: PMU capabilities. + * @pmurev: PMU revision. + * @rambase: RAM base address (only applicable for ARM CR4 chips). +- * @ramsize: amount of RAM on chip. ++ * @ramsize: amount of RAM on chip including retention. ++ * @srsize: amount of retention RAM on chip. + * @name: string representation of the chip identifier. + */ + struct brcmf_chip { +@@ -41,6 +42,7 @@ struct brcmf_chip { + u32 pmurev; + u32 rambase; + u32 ramsize; ++ u32 srsize; + char name[8]; + }; + diff --git a/package/kernel/mac80211/patches/336-0006-brcmfmac-take-save-restore-memory-into-account-for-S.patch b/package/kernel/mac80211/patches/336-0006-brcmfmac-take-save-restore-memory-into-account-for-S.patch new file mode 100644 index 0000000000..69618a7aa7 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0006-brcmfmac-take-save-restore-memory-into-account-for-S.patch @@ -0,0 +1,96 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:32 +0100 +Subject: [PATCH] brcmfmac: take save&restore memory into account for SDIO + shared info + +The firmware provides pointer to SDIO shared information at end of +RAM during firmware initialization. End of RAM is obviously determined +by the actual ram size, but part of that may be used for save&restore +memory. In that case another location in RAM will hold the pointer. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shar + static int brcmf_sdio_readshared(struct brcmf_sdio *bus, + struct sdpcm_shared *sh) + { +- u32 addr; ++ u32 addr = 0; + int rv; + u32 shaddr = 0; + struct sdpcm_shared_le sh_le; + __le32 addr_le; + +- shaddr = bus->ci->rambase + bus->ci->ramsize - 4; ++ sdio_claim_host(bus->sdiodev->func[1]); ++ brcmf_sdio_bus_sleep(bus, false, false); + + /* + * Read last word in socram to determine + * address of sdpcm_shared structure + */ +- sdio_claim_host(bus->sdiodev->func[1]); +- brcmf_sdio_bus_sleep(bus, false, false); +- rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); +- sdio_release_host(bus->sdiodev->func[1]); ++ shaddr = bus->ci->rambase + bus->ci->ramsize - 4; ++ if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci)) ++ shaddr -= bus->ci->srsize; ++ rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, ++ (u8 *)&addr_le, 4); + if (rv < 0) +- return rv; +- +- addr = le32_to_cpu(addr_le); +- +- brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr); ++ goto fail; + + /* + * Check if addr is valid. + * NVRAM length at the end of memory should have been overwritten. + */ ++ addr = le32_to_cpu(addr_le); + if (!brcmf_sdio_valid_shared_address(addr)) { +- brcmf_err("invalid sdpcm_shared address 0x%08X\n", +- addr); +- return -EINVAL; ++ brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr); ++ rv = -EINVAL; ++ goto fail; + } + ++ brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); ++ + /* Read hndrte_shared structure */ + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, + sizeof(struct sdpcm_shared_le)); + if (rv < 0) +- return rv; ++ goto fail; ++ ++ sdio_release_host(bus->sdiodev->func[1]); + + /* Endianness */ + sh->flags = le32_to_cpu(sh_le.flags); +@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct + sh->flags & SDPCM_SHARED_VERSION_MASK); + return -EPROTO; + } +- + return 0; ++ ++fail: ++ brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n", ++ rv, addr); ++ sdio_release_host(bus->sdiodev->func[1]); ++ return rv; + } + + static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus) diff --git a/package/kernel/mac80211/patches/336-0007-brcmfmac-fix-watchdog-timer-regression.patch b/package/kernel/mac80211/patches/336-0007-brcmfmac-fix-watchdog-timer-regression.patch new file mode 100644 index 0000000000..1b10dbb800 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0007-brcmfmac-fix-watchdog-timer-regression.patch @@ -0,0 +1,59 @@ +From: Arend van Spriel +Date: Wed, 11 Mar 2015 16:11:33 +0100 +Subject: [PATCH] brcmfmac: fix watchdog timer regression + +The watchdog timer is used to put the device in a low-power mode when +it is idle for some time. This timer is stopped during that mode and +should be restarted upon activity. This has been broken by commit +d4150fced0365 ("brcmfmac: Simplify watchdog sleep."). This patch +restores the behaviour as it was before that commit. + +Reported-by: Pontus Fuchs +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -972,7 +972,6 @@ static int brcmf_sdio_clkctl(struct brcm + brcmf_sdio_sdclk(bus, true); + /* Now request HT Avail on the backplane */ + brcmf_sdio_htclk(bus, true, pendok); +- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); + break; + + case CLK_SDONLY: +@@ -984,7 +983,6 @@ static int brcmf_sdio_clkctl(struct brcm + else + brcmf_err("request for %d -> %d\n", + bus->clkstate, target); +- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); + break; + + case CLK_NONE: +@@ -993,7 +991,6 @@ static int brcmf_sdio_clkctl(struct brcm + brcmf_sdio_htclk(bus, false, false); + /* Now remove the SD clock */ + brcmf_sdio_sdclk(bus, false); +- brcmf_sdio_wd_timer(bus, 0); + break; + } + #ifdef DEBUG +@@ -1048,6 +1045,7 @@ end: + brcmf_sdio_clkctl(bus, CLK_NONE, pendok); + } else { + brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); ++ brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); + } + bus->sleeping = sleep; + brcmf_dbg(SDIO, "new state %s\n", +@@ -4242,6 +4240,7 @@ void brcmf_sdio_remove(struct brcmf_sdio + if (bus->ci) { + if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { + sdio_claim_host(bus->sdiodev->func[1]); ++ brcmf_sdio_wd_timer(bus, 0); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + /* Leave the device in state where it is + * 'passive'. This is done by resetting all diff --git a/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch b/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch deleted file mode 100644 index 201da75bfc..0000000000 --- a/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch +++ /dev/null @@ -1,157 +0,0 @@ -From: Hante Meuleman -Date: Fri, 6 Mar 2015 18:40:39 +0100 -Subject: [PATCH] brcmfmac: Simplify watchdog sleep. - -The watchdog thread is used to put the SDIO bus to sleep when the -system is idling. This patch simplifies the way it is determined -when sleep can be entered. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -485,10 +485,9 @@ struct brcmf_sdio { - #endif /* DEBUG */ - - uint clkstate; /* State of sd and backplane clock(s) */ -- bool activity; /* Activity flag for clock down */ - s32 idletime; /* Control for activity timeout */ -- s32 idlecount; /* Activity timeout counter */ -- s32 idleclock; /* How to set bus driver when idle */ -+ s32 idlecount; /* Activity timeout counter */ -+ s32 idleclock; /* How to set bus driver when idle */ - bool rxflow_mode; /* Rx flow control mode */ - bool rxflow; /* Is rx flow control on */ - bool alp_only; /* Don't use HT clock (ALP only) */ -@@ -511,6 +510,7 @@ struct brcmf_sdio { - struct workqueue_struct *brcmf_wq; - struct work_struct datawork; - atomic_t dpc_tskcnt; -+ atomic_t dpc_running; - - bool txoff; /* Transmit flow-controlled */ - struct brcmf_sdio_count sdcnt; -@@ -959,13 +959,8 @@ static int brcmf_sdio_clkctl(struct brcm - brcmf_dbg(SDIO, "Enter\n"); - - /* Early exit if we're already there */ -- if (bus->clkstate == target) { -- if (target == CLK_AVAIL) { -- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); -- bus->activity = true; -- } -+ if (bus->clkstate == target) - return 0; -- } - - switch (target) { - case CLK_AVAIL: -@@ -975,7 +970,6 @@ static int brcmf_sdio_clkctl(struct brcm - /* Now request HT Avail on the backplane */ - brcmf_sdio_htclk(bus, true, pendok); - brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); -- bus->activity = true; - break; - - case CLK_SDONLY: -@@ -1024,17 +1018,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * - - /* Going to sleep */ - if (sleep) { -- /* Don't sleep if something is pending */ -- if (atomic_read(&bus->intstatus) || -- atomic_read(&bus->ipend) > 0 || -- bus->ctrl_frame_stat || -- (!atomic_read(&bus->fcstate) && -- brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && -- data_ok(bus))) { -- err = -EBUSY; -- goto done; -- } -- - clkcsr = brcmf_sdiod_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, - &err); -@@ -1045,11 +1028,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * - SBSDIO_ALP_AVAIL_REQ, &err); - } - err = brcmf_sdio_kso_control(bus, false); -- /* disable watchdog */ -- if (!err) -- brcmf_sdio_wd_timer(bus, 0); - } else { -- bus->idlecount = 0; - err = brcmf_sdio_kso_control(bus, true); - } - if (err) { -@@ -3566,7 +3545,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b - queue_work(bus->brcmf_wq, &bus->datawork); - } - --static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) -+static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) - { - brcmf_dbg(TIMER, "Enter\n"); - -@@ -3627,22 +3606,21 @@ static bool brcmf_sdio_bus_watchdog(stru - #endif /* DEBUG */ - - /* On idle timeout clear activity flag and/or turn off clock */ -- if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { -- if (++bus->idlecount >= bus->idletime) { -+ if ((atomic_read(&bus->dpc_tskcnt) == 0) && -+ (atomic_read(&bus->dpc_running) == 0) && -+ (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { -+ bus->idlecount++; -+ if (bus->idlecount > bus->idletime) { -+ brcmf_dbg(SDIO, "idle\n"); -+ sdio_claim_host(bus->sdiodev->func[1]); -+ brcmf_sdio_wd_timer(bus, 0); - bus->idlecount = 0; -- if (bus->activity) { -- bus->activity = false; -- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); -- } else { -- brcmf_dbg(SDIO, "idle\n"); -- sdio_claim_host(bus->sdiodev->func[1]); -- brcmf_sdio_bus_sleep(bus, true, false); -- sdio_release_host(bus->sdiodev->func[1]); -- } -+ brcmf_sdio_bus_sleep(bus, true, false); -+ sdio_release_host(bus->sdiodev->func[1]); - } -+ } else { -+ bus->idlecount = 0; - } -- -- return (atomic_read(&bus->ipend) > 0); - } - - static void brcmf_sdio_dataworker(struct work_struct *work) -@@ -3651,8 +3629,11 @@ static void brcmf_sdio_dataworker(struct - datawork); - - while (atomic_read(&bus->dpc_tskcnt)) { -+ atomic_set(&bus->dpc_running, 1); - atomic_set(&bus->dpc_tskcnt, 0); - brcmf_sdio_dpc(bus); -+ bus->idlecount = 0; -+ atomic_set(&bus->dpc_running, 0); - } - if (brcmf_sdiod_freezing(bus->sdiodev)) { - brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); -@@ -4154,6 +4135,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru - } - /* Initialize DPC thread */ - atomic_set(&bus->dpc_tskcnt, 0); -+ atomic_set(&bus->dpc_running, 0); - - /* Assign bus interface call back */ - bus->sdiodev->bus_if->dev = bus->sdiodev->dev; diff --git a/package/kernel/mac80211/patches/337-0001-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch b/package/kernel/mac80211/patches/337-0001-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch new file mode 100644 index 0000000000..af76f13ecd --- /dev/null +++ b/package/kernel/mac80211/patches/337-0001-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch @@ -0,0 +1,44 @@ +From: Arend van Spriel +Date: Wed, 18 Mar 2015 13:25:21 +0100 +Subject: [PATCH] brcmfmac: avoid runtime-pm for sdio host controller + +Several host controllers supporting runtime-pm are causing issues +with our sdio wireless cards because they disable the sdio interrupt +upon going into runtime suspend. This patch avoids that by doing +a pm_runtime_forbid() call during the probe. Tested with Sony Vaio +Duo 13 which uses sdhci-acpi host controller. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1006,6 +1007,7 @@ static int brcmf_sdiod_remove(struct brc + sg_free_table(&sdiodev->sgtable); + sdiodev->sbwad = 0; + ++ pm_runtime_allow(sdiodev->func[1]->card->host->parent); + return 0; + } + +@@ -1074,7 +1076,7 @@ static int brcmf_sdiod_probe(struct brcm + ret = -ENODEV; + goto out; + } +- ++ pm_runtime_forbid(host->parent); + out: + if (ret) + brcmf_sdiod_remove(sdiodev); diff --git a/package/kernel/mac80211/patches/337-0002-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch b/package/kernel/mac80211/patches/337-0002-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch new file mode 100644 index 0000000000..c419cc68f5 --- /dev/null +++ b/package/kernel/mac80211/patches/337-0002-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch @@ -0,0 +1,171 @@ +From: Hante Meuleman +Date: Wed, 18 Mar 2015 13:25:22 +0100 +Subject: [PATCH] brcmfmac: Add necessary memory barriers for SDIO. + +SDIO uses a thread to handle all communication with the device, +for this data is exchanged between threads. This data needs proper +memory barriers to make sure that data "exchange" is going correct. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -507,8 +507,8 @@ struct brcmf_sdio { + + struct workqueue_struct *brcmf_wq; + struct work_struct datawork; +- atomic_t dpc_tskcnt; +- atomic_t dpc_running; ++ bool dpc_triggered; ++ bool dpc_running; + + bool txoff; /* Transmit flow-controlled */ + struct brcmf_sdio_count sdcnt; +@@ -2713,6 +2713,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, + bus->ctrl_frame_len); + bus->ctrl_frame_err = err; ++ wmb(); + bus->ctrl_frame_stat = false; + } + sdio_release_host(bus->sdiodev->func[1]); +@@ -2734,6 +2735,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + sdio_claim_host(bus->sdiodev->func[1]); + if (bus->ctrl_frame_stat) { + bus->ctrl_frame_err = -ENODEV; ++ wmb(); + bus->ctrl_frame_stat = false; + brcmf_sdio_wait_event_wakeup(bus); + } +@@ -2744,7 +2746,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + (!atomic_read(&bus->fcstate) && + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && + data_ok(bus))) { +- atomic_inc(&bus->dpc_tskcnt); ++ bus->dpc_triggered = true; + } + } + +@@ -2940,6 +2942,7 @@ brcmf_sdio_bus_txctl(struct device *dev, + /* Send from dpc */ + bus->ctrl_frame_buf = msg; + bus->ctrl_frame_len = msglen; ++ wmb(); + bus->ctrl_frame_stat = true; + + brcmf_sdio_trigger_dpc(bus); +@@ -2958,6 +2961,7 @@ brcmf_sdio_bus_txctl(struct device *dev, + if (!ret) { + brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", + bus->ctrl_frame_err); ++ rmb(); + ret = bus->ctrl_frame_err; + } + +@@ -3526,8 +3530,8 @@ done: + + void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus) + { +- if (atomic_read(&bus->dpc_tskcnt) == 0) { +- atomic_inc(&bus->dpc_tskcnt); ++ if (!bus->dpc_triggered) { ++ bus->dpc_triggered = true; + queue_work(bus->brcmf_wq, &bus->datawork); + } + } +@@ -3558,7 +3562,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b + if (!bus->intr) + brcmf_err("isr w/o interrupt configured!\n"); + +- atomic_inc(&bus->dpc_tskcnt); ++ bus->dpc_triggered = true; + queue_work(bus->brcmf_wq, &bus->datawork); + } + +@@ -3578,7 +3582,7 @@ static void brcmf_sdio_bus_watchdog(stru + if (!bus->intr || + (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { + +- if (atomic_read(&bus->dpc_tskcnt) == 0) { ++ if (!bus->dpc_triggered) { + u8 devpend; + + sdio_claim_host(bus->sdiodev->func[1]); +@@ -3596,7 +3600,7 @@ static void brcmf_sdio_bus_watchdog(stru + bus->sdcnt.pollcnt++; + atomic_set(&bus->ipend, 1); + +- atomic_inc(&bus->dpc_tskcnt); ++ bus->dpc_triggered = true; + queue_work(bus->brcmf_wq, &bus->datawork); + } + } +@@ -3623,17 +3627,21 @@ static void brcmf_sdio_bus_watchdog(stru + #endif /* DEBUG */ + + /* On idle timeout clear activity flag and/or turn off clock */ +- if ((atomic_read(&bus->dpc_tskcnt) == 0) && +- (atomic_read(&bus->dpc_running) == 0) && +- (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { +- bus->idlecount++; +- if (bus->idlecount > bus->idletime) { +- brcmf_dbg(SDIO, "idle\n"); +- sdio_claim_host(bus->sdiodev->func[1]); +- brcmf_sdio_wd_timer(bus, 0); ++ if (!bus->dpc_triggered) { ++ rmb(); ++ if ((!bus->dpc_running) && (bus->idletime > 0) && ++ (bus->clkstate == CLK_AVAIL)) { ++ bus->idlecount++; ++ if (bus->idlecount > bus->idletime) { ++ brcmf_dbg(SDIO, "idle\n"); ++ sdio_claim_host(bus->sdiodev->func[1]); ++ brcmf_sdio_wd_timer(bus, 0); ++ bus->idlecount = 0; ++ brcmf_sdio_bus_sleep(bus, true, false); ++ sdio_release_host(bus->sdiodev->func[1]); ++ } ++ } else { + bus->idlecount = 0; +- brcmf_sdio_bus_sleep(bus, true, false); +- sdio_release_host(bus->sdiodev->func[1]); + } + } else { + bus->idlecount = 0; +@@ -3645,13 +3653,14 @@ static void brcmf_sdio_dataworker(struct + struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio, + datawork); + +- while (atomic_read(&bus->dpc_tskcnt)) { +- atomic_set(&bus->dpc_running, 1); +- atomic_set(&bus->dpc_tskcnt, 0); ++ bus->dpc_running = true; ++ wmb(); ++ while (ACCESS_ONCE(bus->dpc_triggered)) { ++ bus->dpc_triggered = false; + brcmf_sdio_dpc(bus); + bus->idlecount = 0; +- atomic_set(&bus->dpc_running, 0); + } ++ bus->dpc_running = false; + if (brcmf_sdiod_freezing(bus->sdiodev)) { + brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); + brcmf_sdiod_try_freeze(bus->sdiodev); +@@ -4144,8 +4153,8 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->watchdog_tsk = NULL; + } + /* Initialize DPC thread */ +- atomic_set(&bus->dpc_tskcnt, 0); +- atomic_set(&bus->dpc_running, 0); ++ bus->dpc_triggered = false; ++ bus->dpc_running = false; + + /* Assign bus interface call back */ + bus->sdiodev->bus_if->dev = bus->sdiodev->dev; diff --git a/package/kernel/mac80211/patches/337-0003-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch b/package/kernel/mac80211/patches/337-0003-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch new file mode 100644 index 0000000000..1bc98a053e --- /dev/null +++ b/package/kernel/mac80211/patches/337-0003-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch @@ -0,0 +1,26 @@ +From: Hante Meuleman +Date: Wed, 18 Mar 2015 13:25:24 +0100 +Subject: [PATCH] brcmfmac: Remove unnecessary new-line in pcie console + logging. + +Reviewed-by: Arend Van Spriel +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/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -651,10 +651,9 @@ static void brcmf_pcie_bus_console_read( + console->log_str[console->log_idx] = ch; + console->log_idx++; + } +- + if (ch == '\n') { + console->log_str[console->log_idx] = 0; +- brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str); ++ brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str); + console->log_idx = 0; + } + } diff --git a/package/kernel/mac80211/patches/337-0004-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch b/package/kernel/mac80211/patches/337-0004-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch new file mode 100644 index 0000000000..fcf0bf34f0 --- /dev/null +++ b/package/kernel/mac80211/patches/337-0004-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch @@ -0,0 +1,26 @@ +From: Arend van Spriel +Date: Wed, 18 Mar 2015 13:25:25 +0100 +Subject: [PATCH] brcmfmac: add MODULE_FIRMWARE() macros for bcm4356 PCIe + device + +The BCM4356 PCIe wireless device was added recently but overlooked +the fact that the MODULE_FIRMWARE() macros were missing for the +firmwares needed by this device. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -189,6 +189,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME + MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); ++MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME); ++MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); + diff --git a/package/kernel/mac80211/patches/337-0005-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch b/package/kernel/mac80211/patches/337-0005-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch new file mode 100644 index 0000000000..b3e9bc9a07 --- /dev/null +++ b/package/kernel/mac80211/patches/337-0005-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch @@ -0,0 +1,138 @@ +From: Arend van Spriel +Date: Wed, 18 Mar 2015 13:25:26 +0100 +Subject: [PATCH] brcmfmac: add support for BCM43430 SDIO chipset + +This patch added support for the BCM43430 802.11n SDIO chipset. + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1098,6 +1098,7 @@ static const struct sdio_device_id brcmf + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), + { /* end: all zeroes */ } +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -600,6 +600,12 @@ static void brcmf_chip_socram_ramsize(st + if (sr->chip->pub.chiprev < 2) + *srsize = (32 * 1024); + break; ++ case BRCM_CC_43430_CHIP_ID: ++ /* assume sr for now as we can not check ++ * firmware sr capability at this point. ++ */ ++ *srsize = (64 * 1024); ++ break; + default: + break; + } +@@ -1072,6 +1078,7 @@ static void + brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip) + { + struct brcmf_core *core; ++ struct brcmf_core_priv *sr; + + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3); + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211); +@@ -1081,6 +1088,13 @@ brcmf_chip_cm3_set_passive(struct brcmf_ + D11_BCMA_IOCTL_PHYCLOCKEN); + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM); + brcmf_chip_resetcore(core, 0, 0, 0); ++ ++ /* disable bank #3 remap for this device */ ++ if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) { ++ sr = container_of(core, struct brcmf_core_priv, pub); ++ brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3); ++ brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0); ++ } + } + + static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip) +@@ -1188,6 +1202,10 @@ bool brcmf_chip_sr_capable(struct brcmf_ + addr = CORE_CC_REG(base, chipcontrol_data); + reg = chip->ops->read32(chip->ctx, addr); + return (reg & pmu_cc3_mask) != 0; ++ case BRCM_CC_43430_CHIP_ID: ++ addr = CORE_CC_REG(base, sr_control1); ++ reg = chip->ops->read32(chip->ctx, addr); ++ return reg != 0; + default: + addr = CORE_CC_REG(base, pmucapabilities_ext); + reg = chip->ops->read32(chip->ctx, addr); +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -615,6 +615,8 @@ static const struct sdiod_drive_str sdio + #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" + #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" + #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" ++#define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin" ++#define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt" + #define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" + #define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" + #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" +@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM43362_NVRAM_NAME); + MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4339_NVRAM_NAME); ++MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME); ++MODULE_FIRMWARE(BCM43430_NVRAM_NAME); + MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4345_NVRAM_NAME); + MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); +@@ -671,6 +675,7 @@ static const struct brcmf_firmware_names + { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, + { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, ++ { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) }, + { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, + { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } + }; +--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +@@ -37,6 +37,7 @@ + #define BRCM_CC_43362_CHIP_ID 43362 + #define BRCM_CC_4335_CHIP_ID 0x4335 + #define BRCM_CC_4339_CHIP_ID 0x4339 ++#define BRCM_CC_43430_CHIP_ID 43430 + #define BRCM_CC_4345_CHIP_ID 0x4345 + #define BRCM_CC_4354_CHIP_ID 0x4354 + #define BRCM_CC_4356_CHIP_ID 0x4356 +--- a/drivers/net/wireless/brcm80211/include/chipcommon.h ++++ b/drivers/net/wireless/brcm80211/include/chipcommon.h +@@ -183,7 +183,14 @@ struct chipcregs { + u8 uart1lsr; + u8 uart1msr; + u8 uart1scratch; +- u32 PAD[126]; ++ u32 PAD[62]; ++ ++ /* save/restore, corerev >= 48 */ ++ u32 sr_capability; /* 0x500 */ ++ u32 sr_control0; /* 0x504 */ ++ u32 sr_control1; /* 0x508 */ ++ u32 gpio_control; /* 0x50C */ ++ u32 PAD[60]; + + /* PMU registers (corerev >= 20) */ + u32 pmucontrol; /* 0x600 */ +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -33,6 +33,7 @@ + #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d + #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 + #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 ++#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 + #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 + #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 + diff --git a/package/kernel/mac80211/patches/337-0006-brcmfmac-only-support-the-BCM43455-7-device.patch b/package/kernel/mac80211/patches/337-0006-brcmfmac-only-support-the-BCM43455-7-device.patch new file mode 100644 index 0000000000..c3d7bc2cbf --- /dev/null +++ b/package/kernel/mac80211/patches/337-0006-brcmfmac-only-support-the-BCM43455-7-device.patch @@ -0,0 +1,50 @@ +From: Arend van Spriel +Date: Wed, 18 Mar 2015 13:25:27 +0100 +Subject: [PATCH] brcmfmac: only support the BCM43455/7 device + +Recently support was added for the BCM4345 SDIO chipset by +commit 9c51026509d7 ("brcmfmac: Add support for BCM4345 SDIO chipset") +however this was verified using a BCM43455 device, which is +a more recent revision of the chip. This patch assure that +older revisions are not probed as they would fail. + +Reviewed-by: Hante Meuleman +Reviewed-by: Syed Asifful Dayyan +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -617,8 +617,8 @@ static const struct sdiod_drive_str sdio + #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" + #define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin" + #define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt" +-#define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" +-#define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" ++#define BCM43455_FIRMWARE_NAME "brcm/brcmfmac43455-sdio.bin" ++#define BCM43455_NVRAM_NAME "brcm/brcmfmac43455-sdio.txt" + #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" + #define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt" + +@@ -644,8 +644,8 @@ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4339_NVRAM_NAME); + MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM43430_NVRAM_NAME); +-MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); +-MODULE_FIRMWARE(BCM4345_NVRAM_NAME); ++MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME); ++MODULE_FIRMWARE(BCM43455_NVRAM_NAME); + MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4354_NVRAM_NAME); + +@@ -676,7 +676,7 @@ static const struct brcmf_firmware_names + { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, + { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, + { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) }, +- { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, ++ { BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) }, + { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } + }; + diff --git a/package/kernel/mac80211/patches/337-0007-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch b/package/kernel/mac80211/patches/337-0007-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch new file mode 100644 index 0000000000..a62cfdfc4c --- /dev/null +++ b/package/kernel/mac80211/patches/337-0007-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch @@ -0,0 +1,52 @@ +From: Arend van Spriel +Date: Wed, 18 Mar 2015 13:25:28 +0100 +Subject: [PATCH] brcmfmac: remove support for unreleased BCM4354 PCIe + +There are no known BCM4354 PCIe devices released so removing +support from the driver until proven otherwise. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -47,8 +47,6 @@ enum brcmf_pcie_state { + + #define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin" + #define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt" +-#define BRCMF_PCIE_4354_FW_NAME "brcm/brcmfmac4354-pcie.bin" +-#define BRCMF_PCIE_4354_NVRAM_NAME "brcm/brcmfmac4354-pcie.txt" + #define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin" + #define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" + #define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" +@@ -187,8 +185,6 @@ enum brcmf_pcie_state { + + MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); +-MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); +-MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); +@@ -1327,10 +1323,6 @@ static int brcmf_pcie_get_fwnames(struct + fw_name = BRCMF_PCIE_43602_FW_NAME; + nvram_name = BRCMF_PCIE_43602_NVRAM_NAME; + break; +- case BRCM_CC_4354_CHIP_ID: +- fw_name = BRCMF_PCIE_4354_FW_NAME; +- nvram_name = BRCMF_PCIE_4354_NVRAM_NAME; +- break; + case BRCM_CC_4356_CHIP_ID: + fw_name = BRCMF_PCIE_4356_FW_NAME; + nvram_name = BRCMF_PCIE_4356_NVRAM_NAME; +@@ -1855,7 +1847,6 @@ cleanup: + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } + + static struct pci_device_id brcmf_pcie_devid_table[] = { +- BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), diff --git a/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch b/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch deleted file mode 100644 index 3a2de7a944..0000000000 --- a/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Hante Meuleman -Date: Fri, 6 Mar 2015 18:40:40 +0100 -Subject: [PATCH] brcmfmac: Fix possible race-condition. - -SDIO is using a "shared" variable to handoff ctl frames to DPC -and to see when they are done. In a timeout situation this can -lead to erroneous situation where DPC started to handle the ctl -frame while the timeout expired. This patch will fix this by -adding locking around the shared variable. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -2700,11 +2700,13 @@ static void brcmf_sdio_dpc(struct brcmf_ - if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && - data_ok(bus)) { - sdio_claim_host(bus->sdiodev->func[1]); -- err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, -- bus->ctrl_frame_len); -+ if (bus->ctrl_frame_stat) { -+ err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, -+ bus->ctrl_frame_len); -+ bus->ctrl_frame_err = err; -+ bus->ctrl_frame_stat = false; -+ } - sdio_release_host(bus->sdiodev->func[1]); -- bus->ctrl_frame_err = err; -- bus->ctrl_frame_stat = false; - brcmf_sdio_wait_event_wakeup(bus); - } - /* Send queued frames (limit 1 if rx may still be pending) */ -@@ -2720,9 +2722,13 @@ static void brcmf_sdio_dpc(struct brcmf_ - brcmf_err("failed backplane access over SDIO, halting operation\n"); - atomic_set(&bus->intstatus, 0); - if (bus->ctrl_frame_stat) { -- bus->ctrl_frame_err = -ENODEV; -- bus->ctrl_frame_stat = false; -- brcmf_sdio_wait_event_wakeup(bus); -+ sdio_claim_host(bus->sdiodev->func[1]); -+ if (bus->ctrl_frame_stat) { -+ bus->ctrl_frame_err = -ENODEV; -+ bus->ctrl_frame_stat = false; -+ brcmf_sdio_wait_event_wakeup(bus); -+ } -+ sdio_release_host(bus->sdiodev->func[1]); - } - } else if (atomic_read(&bus->intstatus) || - atomic_read(&bus->ipend) > 0 || -@@ -2930,15 +2936,20 @@ brcmf_sdio_bus_txctl(struct device *dev, - brcmf_sdio_trigger_dpc(bus); - wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, - msecs_to_jiffies(CTL_DONE_TIMEOUT)); -- -- if (!bus->ctrl_frame_stat) { -+ ret = 0; -+ if (bus->ctrl_frame_stat) { -+ sdio_claim_host(bus->sdiodev->func[1]); -+ if (bus->ctrl_frame_stat) { -+ brcmf_dbg(SDIO, "ctrl_frame timeout\n"); -+ bus->ctrl_frame_stat = false; -+ ret = -ETIMEDOUT; -+ } -+ sdio_release_host(bus->sdiodev->func[1]); -+ } -+ if (!ret) { - brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", - bus->ctrl_frame_err); - ret = bus->ctrl_frame_err; -- } else { -- brcmf_dbg(SDIO, "ctrl_frame timeout\n"); -- bus->ctrl_frame_stat = false; -- ret = -ETIMEDOUT; - } - - if (ret) diff --git a/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch b/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch deleted file mode 100644 index c9eb9008a6..0000000000 --- a/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Syed Asifful Dayyan -Date: Fri, 6 Mar 2015 18:40:42 +0100 -Subject: [PATCH] brcmfmac: Add support for BCM4345 SDIO chipset. - -These changes add support for BCM4345 SDIO chipset. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Arend Van Spriel -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Syed Asifful Dayyan -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -1096,6 +1096,7 @@ static const struct sdio_device_id brcmf - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), -+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), - { /* end: all zeroes */ } - }; ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -491,6 +491,10 @@ static void brcmf_chip_get_raminfo(struc - case BRCM_CC_43362_CHIP_ID: - ci->pub.ramsize = 0x3c000; - break; -+ case BRCM_CC_4345_CHIP_ID: -+ ci->pub.ramsize = 0xc8000; -+ ci->pub.rambase = 0x198000; -+ break; - case BRCM_CC_4339_CHIP_ID: - case BRCM_CC_4354_CHIP_ID: - case BRCM_CC_4356_CHIP_ID: ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -617,6 +617,8 @@ static const struct sdiod_drive_str sdio - #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" - #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" - #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" -+#define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" -+#define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" - #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" - #define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt" - -@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM43362_NVRAM_NAME); - MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4339_NVRAM_NAME); -+MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); -+MODULE_FIRMWARE(BCM4345_NVRAM_NAME); - MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4354_NVRAM_NAME); - -@@ -669,6 +673,7 @@ static const struct brcmf_firmware_names - { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, - { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, -+ { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, - { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } - }; - ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -37,6 +37,7 @@ - #define BRCM_CC_43362_CHIP_ID 43362 - #define BRCM_CC_4335_CHIP_ID 0x4335 - #define BRCM_CC_4339_CHIP_ID 0x4339 -+#define BRCM_CC_4345_CHIP_ID 0x4345 - #define BRCM_CC_4354_CHIP_ID 0x4354 - #define BRCM_CC_4356_CHIP_ID 0x4356 - #define BRCM_CC_43566_CHIP_ID 43566 ---- a/include/linux/mmc/sdio_ids.h -+++ b/include/linux/mmc/sdio_ids.h -@@ -33,6 +33,7 @@ - #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d - #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 - #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 -+#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 - #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 - - #define SDIO_VENDOR_ID_INTEL 0x0089 diff --git a/package/kernel/mac80211/patches/338-brcmfmac-disable-MBSS-feature-for-BCM43362.patch b/package/kernel/mac80211/patches/338-brcmfmac-disable-MBSS-feature-for-BCM43362.patch new file mode 100644 index 0000000000..366ff85d03 --- /dev/null +++ b/package/kernel/mac80211/patches/338-brcmfmac-disable-MBSS-feature-for-BCM43362.patch @@ -0,0 +1,28 @@ +From: Arend van Spriel +Date: Fri, 20 Mar 2015 22:18:17 +0100 +Subject: [PATCH] brcmfmac: disable MBSS feature for BCM43362 + +The BCM43362 firmware falsely reports it is capable of providing +MBSS. As a result AP mode no longer works for this device. Therefor +disable MBSS in the driver for this chipset. + +Cc: stable@vger.kernel.org # 3.19.y +Reported-by: Jorg Krause +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c +@@ -126,7 +126,8 @@ void brcmf_feat_attach(struct brcmf_pub + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); + if (drvr->bus_if->wowl_supported) + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); +- brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); ++ if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) ++ brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); + + /* set chip related quirks */ + switch (drvr->bus_if->chip) { diff --git a/package/kernel/mac80211/patches/339-0001-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch b/package/kernel/mac80211/patches/339-0001-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch new file mode 100644 index 0000000000..6e461f617f --- /dev/null +++ b/package/kernel/mac80211/patches/339-0001-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch @@ -0,0 +1,300 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:24 +0200 +Subject: [PATCH] brcmfmac: use static superset of channels for wiphy + bands + +The driver was constructing a list of channels per wiphy band +by querying the device. This list is not what the hardware is +able to do as it is already filtered by the country setting in +the device. As user-space may change the country this would +require updating the channel list which is not recommended [1]. +This patch introduces a superset of channels. The individual +channels are disabled appropriately by querying the device. + +[1] http://mid.gmane.org/1426706320.3001.21.camel@sipsolutions.net + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -129,13 +129,47 @@ static struct ieee80211_rate __wl_rates[ + RATETAB_ENT(BRCM_RATE_54M, 0), + }; + +-#define wl_a_rates (__wl_rates + 4) +-#define wl_a_rates_size 8 + #define wl_g_rates (__wl_rates + 0) +-#define wl_g_rates_size 12 ++#define wl_g_rates_size ARRAY_SIZE(__wl_rates) ++#define wl_a_rates (__wl_rates + 4) ++#define wl_a_rates_size (wl_g_rates_size - 4) ++ ++#define CHAN2G(_channel, _freq) { \ ++ .band = IEEE80211_BAND_2GHZ, \ ++ .center_freq = (_freq), \ ++ .hw_value = (_channel), \ ++ .flags = IEEE80211_CHAN_DISABLED, \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++#define CHAN5G(_channel) { \ ++ .band = IEEE80211_BAND_5GHZ, \ ++ .center_freq = 5000 + (5 * (_channel)), \ ++ .hw_value = (_channel), \ ++ .flags = IEEE80211_CHAN_DISABLED, \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++static struct ieee80211_channel __wl_2ghz_channels[] = { ++ CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427), ++ CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447), ++ CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467), ++ CHAN2G(13, 2472), CHAN2G(14, 2484) ++}; ++ ++static struct ieee80211_channel __wl_5ghz_channels[] = { ++ CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42), ++ CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56), ++ CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108), ++ CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128), ++ CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149), ++ CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165) ++}; + + /* Band templates duplicated per wiphy. The channel info +- * is filled in after querying the device. ++ * above is added to the band during setup. + */ + static const struct ieee80211_supported_band __wl_band_2ghz = { + .band = IEEE80211_BAND_2GHZ, +@@ -143,7 +177,7 @@ static const struct ieee80211_supported_ + .n_bitrates = wl_g_rates_size, + }; + +-static const struct ieee80211_supported_band __wl_band_5ghz_a = { ++static const struct ieee80211_supported_band __wl_band_5ghz = { + .band = IEEE80211_BAND_5GHZ, + .bitrates = wl_a_rates, + .n_bitrates = wl_a_rates_size, +@@ -5252,40 +5286,6 @@ dongle_scantime_out: + return err; + } + +-/* Filter the list of channels received from firmware counting only +- * the 20MHz channels. The wiphy band data only needs those which get +- * flagged to indicate if they can take part in higher bandwidth. +- */ +-static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg, +- struct brcmf_chanspec_list *chlist, +- u32 chcnt[]) +-{ +- u32 total = le32_to_cpu(chlist->count); +- struct brcmu_chan ch; +- int i; +- +- for (i = 0; i < total; i++) { +- ch.chspec = (u16)le32_to_cpu(chlist->element[i]); +- cfg->d11inf.decchspec(&ch); +- +- /* Firmware gives a ordered list. We skip non-20MHz +- * channels is 2G. For 5G we can abort upon reaching +- * a non-20MHz channel in the list. +- */ +- if (ch.bw != BRCMU_CHAN_BW_20) { +- if (ch.band == BRCMU_CHAN_BAND_5G) +- break; +- else +- continue; +- } +- +- if (ch.band == BRCMU_CHAN_BAND_2G) +- chcnt[0] += 1; +- else if (ch.band == BRCMU_CHAN_BAND_5G) +- chcnt[1] += 1; +- } +-} +- + static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel, + struct brcmu_chan *ch) + { +@@ -5321,7 +5321,6 @@ static int brcmf_construct_chaninfo(stru + u32 i, j; + u32 total; + u32 chaninfo; +- u32 chcnt[2] = { 0, 0 }; + u32 index; + + pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); +@@ -5338,42 +5337,15 @@ static int brcmf_construct_chaninfo(stru + goto fail_pbuf; + } + +- brcmf_count_20mhz_channels(cfg, list, chcnt); + wiphy = cfg_to_wiphy(cfg); +- if (chcnt[0]) { +- band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz), +- GFP_KERNEL); +- if (band == NULL) { +- err = -ENOMEM; +- goto fail_pbuf; +- } +- band->channels = kcalloc(chcnt[0], sizeof(*channel), +- GFP_KERNEL); +- if (band->channels == NULL) { +- kfree(band); +- err = -ENOMEM; +- goto fail_pbuf; +- } +- band->n_channels = 0; +- wiphy->bands[IEEE80211_BAND_2GHZ] = band; +- } +- if (chcnt[1]) { +- band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a), +- GFP_KERNEL); +- if (band == NULL) { +- err = -ENOMEM; +- goto fail_band2g; +- } +- band->channels = kcalloc(chcnt[1], sizeof(*channel), +- GFP_KERNEL); +- if (band->channels == NULL) { +- kfree(band); +- err = -ENOMEM; +- goto fail_band2g; +- } +- band->n_channels = 0; +- wiphy->bands[IEEE80211_BAND_5GHZ] = band; +- } ++ band = wiphy->bands[IEEE80211_BAND_2GHZ]; ++ if (band) ++ for (i = 0; i < band->n_channels; i++) ++ band->channels[i].flags = IEEE80211_CHAN_DISABLED; ++ band = wiphy->bands[IEEE80211_BAND_5GHZ]; ++ if (band) ++ for (i = 0; i < band->n_channels; i++) ++ band->channels[i].flags = IEEE80211_CHAN_DISABLED; + + total = le32_to_cpu(list->count); + for (i = 0; i < total; i++) { +@@ -5388,6 +5360,8 @@ static int brcmf_construct_chaninfo(stru + brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); + continue; + } ++ if (!band) ++ continue; + if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) && + ch.bw == BRCMU_CHAN_BW_40) + continue; +@@ -5415,9 +5389,9 @@ static int brcmf_construct_chaninfo(stru + } else if (ch.bw == BRCMU_CHAN_BW_40) { + brcmf_update_bw40_channel_flag(&channel[index], &ch); + } else { +- /* disable other bandwidths for now as mentioned +- * order assure they are enabled for subsequent +- * chanspecs. ++ /* enable the channel and disable other bandwidths ++ * for now as mentioned order assure they are enabled ++ * for subsequent chanspecs. + */ + channel[index].flags = IEEE80211_CHAN_NO_HT40 | + IEEE80211_CHAN_NO_80MHZ; +@@ -5436,16 +5410,8 @@ static int brcmf_construct_chaninfo(stru + IEEE80211_CHAN_NO_IR; + } + } +- if (index == band->n_channels) +- band->n_channels++; + } +- kfree(pbuf); +- return 0; + +-fail_band2g: +- kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); +- kfree(wiphy->bands[IEEE80211_BAND_2GHZ]); +- wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; + fail_pbuf: + kfree(pbuf); + return err; +@@ -5778,7 +5744,12 @@ static void brcmf_wiphy_wowl_params(stru + + static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + { ++ struct ieee80211_supported_band *band; + struct ieee80211_iface_combination ifc_combo; ++ __le32 bandlist[3]; ++ u32 n_bands; ++ int err, i; ++ + wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; + wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; +@@ -5820,7 +5791,52 @@ static int brcmf_setup_wiphy(struct wiph + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) + brcmf_wiphy_wowl_params(wiphy); + +- return brcmf_setup_wiphybands(wiphy); ++ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist, ++ sizeof(bandlist)); ++ if (err) { ++ brcmf_err("could not obtain band info: err=%d\n", err); ++ return err; ++ } ++ /* first entry in bandlist is number of bands */ ++ n_bands = le32_to_cpu(bandlist[0]); ++ for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) { ++ if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) { ++ band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz), ++ GFP_KERNEL); ++ if (!band) ++ return -ENOMEM; ++ ++ band->channels = kmemdup(&__wl_2ghz_channels, ++ sizeof(__wl_2ghz_channels), ++ GFP_KERNEL); ++ if (!band->channels) { ++ kfree(band); ++ return -ENOMEM; ++ } ++ ++ band->n_channels = ARRAY_SIZE(__wl_2ghz_channels); ++ wiphy->bands[IEEE80211_BAND_2GHZ] = band; ++ } ++ if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) { ++ band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz), ++ GFP_KERNEL); ++ if (!band) ++ return -ENOMEM; ++ ++ band->channels = kmemdup(&__wl_5ghz_channels, ++ sizeof(__wl_5ghz_channels), ++ GFP_KERNEL); ++ if (!band->channels) { ++ kfree(band); ++ return -ENOMEM; ++ } ++ ++ band->n_channels = ARRAY_SIZE(__wl_5ghz_channels); ++ wiphy->bands[IEEE80211_BAND_5GHZ] = band; ++ } ++ } ++ err = brcmf_setup_wiphybands(wiphy); ++ return err; + } + + static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) +@@ -6011,6 +6027,9 @@ static void brcmf_cfg80211_reg_notifier( + + static void brcmf_free_wiphy(struct wiphy *wiphy) + { ++ if (!wiphy) ++ return; ++ + kfree(wiphy->iface_combinations); + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/339-0002-brcmfmac-update-wiphy-band-information-upon-updating.patch b/package/kernel/mac80211/patches/339-0002-brcmfmac-update-wiphy-band-information-upon-updating.patch new file mode 100644 index 0000000000..a0c22eb411 --- /dev/null +++ b/package/kernel/mac80211/patches/339-0002-brcmfmac-update-wiphy-band-information-upon-updating.patch @@ -0,0 +1,29 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:25 +0200 +Subject: [PATCH] brcmfmac: update wiphy band information upon updating + regulatory domain + +When change the country code the available channels may change. So +the wiphy bands should be updated accordingly. + +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -6022,7 +6022,11 @@ static void brcmf_cfg80211_reg_notifier( + memset(&ccreq, 0, sizeof(ccreq)); + ccreq.rev = cpu_to_le32(-1); + memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2)); +- brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); ++ if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) { ++ brcmf_err("firmware rejected country setting\n"); ++ return; ++ } ++ brcmf_setup_wiphybands(wiphy); + } + + static void brcmf_free_wiphy(struct wiphy *wiphy) diff --git a/package/kernel/mac80211/patches/339-0003-brcmfmac-add-description-for-feature-flags.patch b/package/kernel/mac80211/patches/339-0003-brcmfmac-add-description-for-feature-flags.patch new file mode 100644 index 0000000000..193f507d0d --- /dev/null +++ b/package/kernel/mac80211/patches/339-0003-brcmfmac-add-description-for-feature-flags.patch @@ -0,0 +1,24 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:26 +0200 +Subject: [PATCH] brcmfmac: add description for feature flags + +Some feature flags were not described in the header file. Adding +the description. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h +@@ -19,7 +19,9 @@ + /* + * Features: + * ++ * MBSS: multiple BSSID support (eg. guest network in AP mode). + * MCHAN: multi-channel for concurrent P2P. ++ * WOWL: Wake-On-WLAN. + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ diff --git a/package/kernel/mac80211/patches/339-0004-brcmfmac-make-scheduled-scan-support-conditional.patch b/package/kernel/mac80211/patches/339-0004-brcmfmac-make-scheduled-scan-support-conditional.patch new file mode 100644 index 0000000000..42330b474e --- /dev/null +++ b/package/kernel/mac80211/patches/339-0004-brcmfmac-make-scheduled-scan-support-conditional.patch @@ -0,0 +1,51 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:27 +0200 +Subject: [PATCH] brcmfmac: make scheduled scan support conditional + +The scheduled scan support depends on firmware supporting the PNO +feature. This feature is optional so add a feature flag for this +in the driver and announce scheduled scan support accordingly. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -5782,7 +5782,8 @@ static int brcmf_setup_wiphy(struct wiph + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + wiphy->mgmt_stypes = brcmf_txrx_stypes; + wiphy->max_remain_on_channel_duration = 5000; +- brcmf_wiphy_pno_params(wiphy); ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) ++ brcmf_wiphy_pno_params(wiphy); + + /* vendor commands/events support */ + wiphy->vendor_commands = brcmf_vendor_cmds; +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c +@@ -124,6 +124,7 @@ void brcmf_feat_attach(struct brcmf_pub + struct brcmf_if *ifp = drvr->iflist[0]; + + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); ++ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); + if (drvr->bus_if->wowl_supported) + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); + if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h +@@ -21,11 +21,13 @@ + * + * MBSS: multiple BSSID support (eg. guest network in AP mode). + * MCHAN: multi-channel for concurrent P2P. ++ * PNO: preferred network offload. + * WOWL: Wake-On-WLAN. + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ + BRCMF_FEAT_DEF(MCHAN) \ ++ BRCMF_FEAT_DEF(PNO) \ + BRCMF_FEAT_DEF(WOWL) + /* + * Quirks: diff --git a/package/kernel/mac80211/patches/339-0005-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch b/package/kernel/mac80211/patches/339-0005-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch new file mode 100644 index 0000000000..b859d46894 --- /dev/null +++ b/package/kernel/mac80211/patches/339-0005-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch @@ -0,0 +1,43 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:28 +0200 +Subject: [PATCH] brcmfmac: add support for BCM4324 rev B5 chipset + +This patch adds support for the BCM4324 B5 revision. This device +is similar to BCM43241 from driver and firmware perspective. It +is known to be used in Lenovo Thinkpad Tablet devices. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -601,6 +601,8 @@ static const struct sdiod_drive_str sdio + #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 +630,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 +671,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) }, diff --git a/package/kernel/mac80211/patches/339-0006-brcmfmac-process-interrupt-regardless-sdiod-state.patch b/package/kernel/mac80211/patches/339-0006-brcmfmac-process-interrupt-regardless-sdiod-state.patch new file mode 100644 index 0000000000..d420308383 --- /dev/null +++ b/package/kernel/mac80211/patches/339-0006-brcmfmac-process-interrupt-regardless-sdiod-state.patch @@ -0,0 +1,27 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:29 +0200 +Subject: [PATCH] brcmfmac: process interrupt regardless sdiod state + +When the sdio bus state is not ready to process we abort the +interrupt service routine. This is not wanted as it keeps the +interrupt source active. Better clear the interrupt source. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky (Zhenhui) Lin +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -3555,10 +3555,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *b + 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()) diff --git a/package/kernel/mac80211/patches/339-0007-brcmfmac-fix-sdio-suspend-and-resume.patch b/package/kernel/mac80211/patches/339-0007-brcmfmac-fix-sdio-suspend-and-resume.patch new file mode 100644 index 0000000000..ac5584ec3c --- /dev/null +++ b/package/kernel/mac80211/patches/339-0007-brcmfmac-fix-sdio-suspend-and-resume.patch @@ -0,0 +1,68 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:30 +0200 +Subject: [PATCH] brcmfmac: fix sdio suspend and resume + +commit 330b4e4be937 ("brcmfmac: Add wowl support for SDIO devices.") +changed the behaviour by removing the MMC_PM_KEEP_POWER flag for +non-wowl scenario, which needs to be restored. Another necessary +change is to mark the card as being non-removable. With this in place +the suspend resume test passes successfully doing: + + # echo devices > /sys/power/pm_test + # echo mem > /sys/power/state + +Note that power may still be switched off when system is going +in S3 state. + +Reported-by: Fu, Zhonghui < +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky (Zhenhui) Lin +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1011,6 +1011,14 @@ static int brcmf_sdiod_remove(struct brc + return 0; + } + ++static void brcmf_sdiod_host_fixup(struct mmc_host *host) ++{ ++ /* runtime-pm powers off the device */ ++ pm_runtime_forbid(host->parent); ++ /* avoid removal detection upon resume */ ++ host->caps |= MMC_CAP_NONREMOVABLE; ++} ++ + static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) + { + struct sdio_func *func; +@@ -1076,7 +1084,7 @@ static int brcmf_sdiod_probe(struct brcm + ret = -ENODEV; + goto out; + } +- pm_runtime_forbid(host->parent); ++ brcmf_sdiod_host_fixup(host); + out: + if (ret) + brcmf_sdiod_remove(sdiodev); +@@ -1246,15 +1254,15 @@ static int brcmf_ops_sdio_suspend(struct + brcmf_sdiod_freezer_on(sdiodev); + brcmf_sdio_wd_timer(sdiodev->bus, 0); + ++ sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->wowl_enabled) { +- sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->pdata->oob_irq_supported) + enable_irq_wake(sdiodev->pdata->oob_irq_nr); + else +- sdio_flags = MMC_PM_WAKE_SDIO_IRQ; +- if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) +- brcmf_err("Failed to set pm_flags %x\n", sdio_flags); ++ sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } ++ if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) ++ brcmf_err("Failed to set pm_flags %x\n", sdio_flags); + return 0; + } + diff --git a/package/kernel/mac80211/patches/339-0008-brcmfmac-add-support-for-BCM4358-PCIe-device.patch b/package/kernel/mac80211/patches/339-0008-brcmfmac-add-support-for-BCM4358-PCIe-device.patch new file mode 100644 index 0000000000..a521b65d0f --- /dev/null +++ b/package/kernel/mac80211/patches/339-0008-brcmfmac-add-support-for-BCM4358-PCIe-device.patch @@ -0,0 +1,77 @@ +From: Arend van Spriel +Date: Tue, 14 Apr 2015 20:10:31 +0200 +Subject: [PATCH] brcmfmac: add support for BCM4358 PCIe device + +This patch adds support for the BCM4358 2x2 11ac device. + +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -649,6 +649,7 @@ static u32 brcmf_chip_tcm_rambase(struct + case BRCM_CC_43567_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: + case BRCM_CC_43570_CHIP_ID: ++ case BRCM_CC_4358_CHIP_ID: + case BRCM_CC_43602_CHIP_ID: + return 0x180000; + default: +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -51,6 +51,8 @@ enum brcmf_pcie_state { + #define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" + #define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" + #define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt" ++#define BRCMF_PCIE_4358_FW_NAME "brcm/brcmfmac4358-pcie.bin" ++#define BRCMF_PCIE_4358_NVRAM_NAME "brcm/brcmfmac4358-pcie.txt" + + #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ + +@@ -189,6 +191,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME) + MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); + MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); ++MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME); ++MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME); + + + struct brcmf_pcie_console { +@@ -1333,6 +1337,10 @@ static int brcmf_pcie_get_fwnames(struct + fw_name = BRCMF_PCIE_43570_FW_NAME; + nvram_name = BRCMF_PCIE_43570_NVRAM_NAME; + break; ++ case BRCM_CC_4358_CHIP_ID: ++ fw_name = BRCMF_PCIE_4358_FW_NAME; ++ nvram_name = BRCMF_PCIE_4358_NVRAM_NAME; ++ break; + default: + brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip); + return -ENODEV; +@@ -1850,6 +1858,7 @@ static struct pci_device_id brcmf_pcie_d + BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4358_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID), +--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +@@ -45,6 +45,7 @@ + #define BRCM_CC_43567_CHIP_ID 43567 + #define BRCM_CC_43569_CHIP_ID 43569 + #define BRCM_CC_43570_CHIP_ID 43570 ++#define BRCM_CC_4358_CHIP_ID 0x4358 + #define BRCM_CC_43602_CHIP_ID 43602 + + /* USB Device IDs */ +@@ -59,6 +60,7 @@ + #define BRCM_PCIE_4356_DEVICE_ID 0x43ec + #define BRCM_PCIE_43567_DEVICE_ID 0x43d3 + #define BRCM_PCIE_43570_DEVICE_ID 0x43d9 ++#define BRCM_PCIE_4358_DEVICE_ID 0x43e9 + #define BRCM_PCIE_43602_DEVICE_ID 0x43ba + #define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb + #define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc diff --git a/package/kernel/mac80211/patches/339-0009-brcmfmac-add-additional-43602-pcie-device-id.patch b/package/kernel/mac80211/patches/339-0009-brcmfmac-add-additional-43602-pcie-device-id.patch new file mode 100644 index 0000000000..bcbb984d42 --- /dev/null +++ b/package/kernel/mac80211/patches/339-0009-brcmfmac-add-additional-43602-pcie-device-id.patch @@ -0,0 +1,30 @@ +From: Hante Meuleman +Date: Tue, 14 Apr 2015 20:10:32 +0200 +Subject: [PATCH] brcmfmac: add additional 43602 pcie device id. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -1862,6 +1862,7 @@ static struct pci_device_id brcmf_pcie_d + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID), + { /* end: all zeroes */ } + }; + +--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +@@ -64,6 +64,7 @@ + #define BRCM_PCIE_43602_DEVICE_ID 0x43ba + #define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb + #define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc ++#define BRCM_PCIE_43602_RAW_DEVICE_ID 43602 + + /* brcmsmac IDs */ + #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ diff --git a/package/kernel/mac80211/patches/339-0010-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch b/package/kernel/mac80211/patches/339-0010-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch new file mode 100644 index 0000000000..5f9bbeaf5c --- /dev/null +++ b/package/kernel/mac80211/patches/339-0010-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch @@ -0,0 +1,351 @@ +From: Hante Meuleman +Date: Tue, 14 Apr 2015 20:10:33 +0200 +Subject: [PATCH] brcmfmac: Add support for multiple PCIE devices in + nvram. + +With PCIE it is possible to support multiple devices with the +same device type. They all load the same nvram file. In order to +support this the nvram can specify which part of the nvram is +for which pcie device. This patch adds support for these new +types of nvram files. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -23,6 +23,10 @@ + #include "debug.h" + #include "firmware.h" + ++#define BRCMF_FW_MAX_NVRAM_SIZE 64000 ++#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ ++#define BRCMF_FW_NVRAM_PCIEDEV_LEN 9 /* pcie/1/4/ */ ++ + char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; + module_param_string(firmware_path, brcmf_firmware_path, + BRCMF_FW_PATH_LEN, 0440); +@@ -46,6 +50,8 @@ enum nvram_parser_state { + * @column: current column in line. + * @pos: byte offset in input buffer. + * @entry: start position of key,value entry. ++ * @multi_dev_v1: detect pcie multi device v1 (compressed). ++ * @multi_dev_v2: detect pcie multi device v2. + */ + struct nvram_parser { + enum nvram_parser_state state; +@@ -56,6 +62,8 @@ struct nvram_parser { + u32 column; + u32 pos; + u32 entry; ++ bool multi_dev_v1; ++ bool multi_dev_v2; + }; + + static bool is_nvram_char(char c) +@@ -108,6 +116,10 @@ static enum nvram_parser_state brcmf_nvr + st = COMMENT; + else + st = VALUE; ++ if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) ++ nvp->multi_dev_v1 = true; ++ if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) ++ nvp->multi_dev_v2 = true; + } else if (!is_nvram_char(c)) { + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", + nvp->line, nvp->column); +@@ -133,6 +145,8 @@ brcmf_nvram_handle_value(struct nvram_pa + ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; + skv = (u8 *)&nvp->fwnv->data[nvp->entry]; + cplen = ekv - skv; ++ if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) ++ return END; + /* copy to output buffer */ + memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen); + nvp->nvram_len += cplen; +@@ -180,10 +194,18 @@ static enum nvram_parser_state + static int brcmf_init_nvram_parser(struct nvram_parser *nvp, + const struct firmware *nv) + { ++ size_t size; ++ + memset(nvp, 0, sizeof(*nvp)); + nvp->fwnv = nv; ++ /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ ++ if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) ++ size = BRCMF_FW_MAX_NVRAM_SIZE; ++ else ++ size = nv->size; + /* Alloc for extra 0 byte + roundup by 4 + length field */ +- nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL); ++ size += 1 + 3 + sizeof(u32); ++ nvp->nvram = kzalloc(size, GFP_KERNEL); + if (!nvp->nvram) + return -ENOMEM; + +@@ -192,12 +214,136 @@ static int brcmf_init_nvram_parser(struc + return 0; + } + ++/* brcmf_fw_strip_multi_v1 :Some nvram files contain settings for multiple ++ * devices. Strip it down for one device, use domain_nr/bus_nr to determine ++ * which data is to be returned. v1 is the version where nvram is stored ++ * compressed and "devpath" maps to index for valid entries. ++ */ ++static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, ++ u16 bus_nr) ++{ ++ u32 i, j; ++ bool found; ++ u8 *nvram; ++ u8 id; ++ ++ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); ++ if (!nvram) ++ goto fail; ++ ++ /* min length: devpath0=pcie/1/4/ + 0:x=y */ ++ if (nvp->nvram_len < BRCMF_FW_NVRAM_DEVPATH_LEN + 6) ++ goto fail; ++ ++ /* First search for the devpathX and see if it is the configuration ++ * for domain_nr/bus_nr. Search complete nvp ++ */ ++ found = false; ++ i = 0; ++ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) { ++ /* Format: devpathX=pcie/Y/Z/ ++ * Y = domain_nr, Z = bus_nr, X = virtual ID ++ */ ++ if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && ++ (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) { ++ if (((nvp->nvram[i + 14] - '0') == domain_nr) && ++ ((nvp->nvram[i + 16] - '0') == bus_nr)) { ++ id = nvp->nvram[i + 7] - '0'; ++ found = true; ++ break; ++ } ++ } ++ while (nvp->nvram[i] != 0) ++ i++; ++ i++; ++ } ++ if (!found) ++ goto fail; ++ ++ /* Now copy all valid entries, release old nvram and assign new one */ ++ i = 0; ++ j = 0; ++ while (i < nvp->nvram_len) { ++ if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { ++ i += 2; ++ while (nvp->nvram[i] != 0) { ++ nvram[j] = nvp->nvram[i]; ++ i++; ++ j++; ++ } ++ nvram[j] = 0; ++ j++; ++ } ++ while (nvp->nvram[i] != 0) ++ i++; ++ i++; ++ } ++ kfree(nvp->nvram); ++ nvp->nvram = nvram; ++ nvp->nvram_len = j; ++ return; ++ ++fail: ++ kfree(nvram); ++ nvp->nvram_len = 0; ++} ++ ++/* brcmf_fw_strip_multi_v2 :Some nvram files contain settings for multiple ++ * devices. Strip it down for one device, use domain_nr/bus_nr to determine ++ * which data is to be returned. v2 is the version where nvram is stored ++ * uncompressed, all relevant valid entries are identified by ++ * pcie/domain_nr/bus_nr: ++ */ ++static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, ++ u16 bus_nr) ++{ ++ u32 i, j; ++ u8 *nvram; ++ ++ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); ++ if (!nvram) ++ goto fail; ++ ++ /* Copy all valid entries, release old nvram and assign new one. ++ * Valid entries are of type pcie/X/Y/ where X = domain_nr and ++ * Y = bus_nr. ++ */ ++ i = 0; ++ j = 0; ++ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) { ++ if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) && ++ (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') && ++ ((nvp->nvram[i + 5] - '0') == domain_nr) && ++ ((nvp->nvram[i + 7] - '0') == bus_nr)) { ++ i += BRCMF_FW_NVRAM_PCIEDEV_LEN; ++ while (nvp->nvram[i] != 0) { ++ nvram[j] = nvp->nvram[i]; ++ i++; ++ j++; ++ } ++ nvram[j] = 0; ++ j++; ++ } ++ while (nvp->nvram[i] != 0) ++ i++; ++ i++; ++ } ++ kfree(nvp->nvram); ++ nvp->nvram = nvram; ++ nvp->nvram_len = j; ++ return; ++fail: ++ kfree(nvram); ++ nvp->nvram_len = 0; ++} ++ + /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil + * and ending in a NUL. Removes carriage returns, empty lines, comment lines, + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. + * End of buffer is completed with token identifying length of buffer. + */ +-static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length) ++static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, ++ u16 domain_nr, u16 bus_nr) + { + struct nvram_parser nvp; + u32 pad; +@@ -212,6 +358,16 @@ static void *brcmf_fw_nvram_strip(const + if (nvp.state == END) + break; + } ++ if (nvp.multi_dev_v1) ++ brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); ++ else if (nvp.multi_dev_v2) ++ brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); ++ ++ if (nvp.nvram_len == 0) { ++ kfree(nvp.nvram); ++ return NULL; ++ } ++ + pad = nvp.nvram_len; + *new_length = roundup(nvp.nvram_len + 1, 4); + while (pad != *new_length) { +@@ -239,6 +395,8 @@ struct brcmf_fw { + u16 flags; + const struct firmware *code; + const char *nvram_name; ++ u16 domain_nr; ++ u16 bus_nr; + void (*done)(struct device *dev, const struct firmware *fw, + void *nvram_image, u32 nvram_len); + }; +@@ -254,7 +412,8 @@ static void brcmf_fw_request_nvram_done( + goto fail; + + if (fw) { +- nvram = brcmf_fw_nvram_strip(fw, &nvram_length); ++ nvram = brcmf_fw_nvram_strip(fw, &nvram_length, ++ fwctx->domain_nr, fwctx->bus_nr); + release_firmware(fw); + if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) + goto fail; +@@ -309,11 +468,12 @@ fail: + kfree(fwctx); + } + +-int brcmf_fw_get_firmwares(struct device *dev, u16 flags, +- const char *code, const char *nvram, +- void (*fw_cb)(struct device *dev, +- const struct firmware *fw, +- void *nvram_image, u32 nvram_len)) ++int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, ++ const char *code, const char *nvram, ++ void (*fw_cb)(struct device *dev, ++ const struct firmware *fw, ++ void *nvram_image, u32 nvram_len), ++ u16 domain_nr, u16 bus_nr) + { + struct brcmf_fw *fwctx; + +@@ -333,8 +493,21 @@ int brcmf_fw_get_firmwares(struct device + fwctx->done = fw_cb; + if (flags & BRCMF_FW_REQUEST_NVRAM) + fwctx->nvram_name = nvram; ++ fwctx->domain_nr = domain_nr; ++ fwctx->bus_nr = bus_nr; + + return request_firmware_nowait(THIS_MODULE, true, code, dev, + GFP_KERNEL, fwctx, + brcmf_fw_request_code_done); + } ++ ++int brcmf_fw_get_firmwares(struct device *dev, u16 flags, ++ const char *code, const char *nvram, ++ void (*fw_cb)(struct device *dev, ++ const struct firmware *fw, ++ void *nvram_image, u32 nvram_len)) ++{ ++ return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, ++ 0); ++} ++ +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h +@@ -32,6 +32,12 @@ void brcmf_fw_nvram_free(void *nvram); + * fails it will not use the callback, but call device_release_driver() + * instead which will call the driver .remove() callback. + */ ++int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, ++ const char *code, const char *nvram, ++ void (*fw_cb)(struct device *dev, ++ const struct firmware *fw, ++ void *nvram_image, u32 nvram_len), ++ u16 domain_nr, u16 bus_nr); + int brcmf_fw_get_firmwares(struct device *dev, u16 flags, + const char *code, const char *nvram, + void (*fw_cb)(struct device *dev, +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -1649,8 +1649,13 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + struct brcmf_pciedev_info *devinfo; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_bus *bus; ++ u16 domain_nr; ++ u16 bus_nr; + +- brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); ++ domain_nr = pci_domain_nr(pdev->bus) + 1; ++ bus_nr = pdev->bus->number; ++ brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, ++ domain_nr, bus_nr); + + ret = -ENOMEM; + devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); +@@ -1699,10 +1704,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + if (ret) + goto fail_bus; + +- ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM | +- BRCMF_FW_REQ_NV_OPTIONAL, +- devinfo->fw_name, devinfo->nvram_name, +- brcmf_pcie_setup); ++ ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | ++ BRCMF_FW_REQ_NV_OPTIONAL, ++ devinfo->fw_name, devinfo->nvram_name, ++ brcmf_pcie_setup, domain_nr, bus_nr); + if (ret == 0) + return 0; + fail_bus: diff --git a/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch b/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch deleted file mode 100644 index 7a688c4be6..0000000000 --- a/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:27 +0100 -Subject: [PATCH] brcmfmac: remove duplication of ramsize info - -Removing the ramsize from the brcmf_sdio structure to avoid -duplication. The information is available in brcmf_chip -structure. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -432,8 +432,6 @@ struct brcmf_sdio { - struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ - struct brcmf_chip *ci; /* Chip info struct */ - -- u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ -- - u32 hostintmask; /* Copy of Host Interrupt Mask */ - atomic_t intstatus; /* Intstatus bits (events) pending */ - atomic_t fcstate; /* State of dongle flow-control */ -@@ -1075,7 +1073,7 @@ static int brcmf_sdio_readshared(struct - struct sdpcm_shared_le sh_le; - __le32 addr_le; - -- shaddr = bus->ci->rambase + bus->ramsize - 4; -+ shaddr = bus->ci->rambase + bus->ci->ramsize - 4; - - /* - * Read last word in socram to determine -@@ -3871,13 +3869,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdi - drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; - brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); - -- /* Get info on the SOCRAM cores... */ -- bus->ramsize = bus->ci->ramsize; -- if (!(bus->ramsize)) { -- brcmf_err("failed to find SOCRAM memory!\n"); -- goto fail; -- } -- - /* 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); diff --git a/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch b/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch deleted file mode 100644 index e2a2074247..0000000000 --- a/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:28 +0100 -Subject: [PATCH] brcmfmac: always perform cores checks - -Instead of checking the cores in the chip only if CONFIG_BRCMDBG -is selected perform the check always and extend it with more sanity -checking. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -419,13 +419,13 @@ static struct brcmf_core *brcmf_chip_add - return &core->pub; - } - --#ifdef DEBUG - /* safety check for chipinfo */ - static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) - { - struct brcmf_core_priv *core; - bool need_socram = false; - bool has_socram = false; -+ bool cpu_found = false; - int idx = 1; - - list_for_each_entry(core, &ci->cores, list) { -@@ -435,12 +435,14 @@ static int brcmf_chip_cores_check(struct - - switch (core->pub.id) { - case BCMA_CORE_ARM_CM3: -+ cpu_found = true; - need_socram = true; - break; - case BCMA_CORE_INTERNAL_MEM: - has_socram = true; - break; - case BCMA_CORE_ARM_CR4: -+ cpu_found = true; - if (ci->pub.rambase == 0) { - brcmf_err("RAM base not provided with ARM CR4 core\n"); - return -ENOMEM; -@@ -451,19 +453,21 @@ static int brcmf_chip_cores_check(struct - } - } - -+ if (!cpu_found) { -+ brcmf_err("CPU core not detected\n"); -+ return -ENXIO; -+ } - /* check RAM core presence for ARM CM3 core */ - if (need_socram && !has_socram) { - brcmf_err("RAM core not provided with ARM CM3 core\n"); - return -ENODEV; - } -+ if (!ci->pub.ramsize) { -+ brcmf_err("RAM size is undetermined\n"); -+ return -ENOMEM; -+ } - return 0; - } --#else /* DEBUG */ --static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) --{ -- return 0; --} --#endif - - static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) - { diff --git a/package/kernel/mac80211/patches/340-brcmfmac-cleanup-a-sizeof.patch b/package/kernel/mac80211/patches/340-brcmfmac-cleanup-a-sizeof.patch new file mode 100644 index 0000000000..d26e118d77 --- /dev/null +++ b/package/kernel/mac80211/patches/340-brcmfmac-cleanup-a-sizeof.patch @@ -0,0 +1,23 @@ +From: Dan Carpenter +Date: Thu, 7 May 2015 12:59:19 +0300 +Subject: [PATCH] brcmfmac: cleanup a sizeof() + +"flowrings" and "*flowrings" are both pointers so this always returns +sizeof(void *) and the current code works fine. But "*flowrings" is +intended here and static checkers complain, so lets change it. + +Signed-off-by: Dan Carpenter +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -1617,7 +1617,7 @@ static void brcmf_pcie_setup(struct devi + bus->msgbuf->commonrings[i] = + &devinfo->shared.commonrings[i]->commonring; + +- flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings), ++ flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings), + GFP_KERNEL); + if (!flowrings) + goto fail; diff --git a/package/kernel/mac80211/patches/341-brcmfmac-check-result-of-USB-firmware-request.patch b/package/kernel/mac80211/patches/341-brcmfmac-check-result-of-USB-firmware-request.patch new file mode 100644 index 0000000000..9b2880d8fc --- /dev/null +++ b/package/kernel/mac80211/patches/341-brcmfmac-check-result-of-USB-firmware-request.patch @@ -0,0 +1,33 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 7 May 2015 14:13:03 +0200 +Subject: [PATCH] brcmfmac: check result of USB firmware request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This prevents silence failures with driver waiting (infinitely) for a +callback. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c +@@ -1270,8 +1270,13 @@ static int brcmf_usb_probe_cb(struct brc + bus->chiprev = bus_pub->chiprev; + + /* request firmware here */ +- brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, +- brcmf_usb_probe_phase2); ++ ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), ++ NULL, brcmf_usb_probe_phase2); ++ if (ret) { ++ brcmf_err("firmware request failed: %d\n", ret); ++ goto fail; ++ } ++ + return 0; + + fail: diff --git a/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch b/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch deleted file mode 100644 index a272800577..0000000000 --- a/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch +++ /dev/null @@ -1,240 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:29 +0100 -Subject: [PATCH] brcmfmac: rename chip download functions - -The functions brcmf_chip_[enter/exit]_download() are not exclusively -used for firmware download so rename these more appropriate. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -807,7 +807,7 @@ struct brcmf_chip *brcmf_chip_attach(voi - err = -EINVAL; - if (WARN_ON(!ops->prepare)) - err = -EINVAL; -- if (WARN_ON(!ops->exit_dl)) -+ if (WARN_ON(!ops->activate)) - err = -EINVAL; - if (err < 0) - return ERR_PTR(-EINVAL); -@@ -905,7 +905,7 @@ void brcmf_chip_resetcore(struct brcmf_c - } - - static void --brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip) -+brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip) - { - struct brcmf_core *core; - -@@ -919,7 +919,7 @@ brcmf_chip_cm3_enterdl(struct brcmf_chip - brcmf_chip_resetcore(core, 0, 0, 0); - } - --static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip) -+static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip) - { - struct brcmf_core *core; - -@@ -929,7 +929,7 @@ static bool brcmf_chip_cm3_exitdl(struct - return false; - } - -- chip->ops->exit_dl(chip->ctx, &chip->pub, 0); -+ chip->ops->activate(chip->ctx, &chip->pub, 0); - - core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3); - brcmf_chip_resetcore(core, 0, 0, 0); -@@ -938,7 +938,7 @@ static bool brcmf_chip_cm3_exitdl(struct - } - - static inline void --brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip) -+brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip) - { - struct brcmf_core *core; - -@@ -951,11 +951,11 @@ brcmf_chip_cr4_enterdl(struct brcmf_chip - D11_BCMA_IOCTL_PHYCLOCKEN); - } - --static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec) -+static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec) - { - struct brcmf_core *core; - -- chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec); -+ chip->ops->activate(chip->ctx, &chip->pub, rstvec); - - /* restore ARM */ - core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4); -@@ -964,7 +964,7 @@ static bool brcmf_chip_cr4_exitdl(struct - return true; - } - --void brcmf_chip_enter_download(struct brcmf_chip *pub) -+void brcmf_chip_set_passive(struct brcmf_chip *pub) - { - struct brcmf_chip_priv *chip; - struct brcmf_core *arm; -@@ -974,14 +974,14 @@ void brcmf_chip_enter_download(struct br - chip = container_of(pub, struct brcmf_chip_priv, pub); - arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); - if (arm) { -- brcmf_chip_cr4_enterdl(chip); -+ brcmf_chip_cr4_set_passive(chip); - return; - } - -- brcmf_chip_cm3_enterdl(chip); -+ brcmf_chip_cm3_set_passive(chip); - } - --bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec) -+bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec) - { - struct brcmf_chip_priv *chip; - struct brcmf_core *arm; -@@ -991,9 +991,9 @@ bool brcmf_chip_exit_download(struct brc - chip = container_of(pub, struct brcmf_chip_priv, pub); - arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); - if (arm) -- return brcmf_chip_cr4_exitdl(chip, rstvec); -+ return brcmf_chip_cr4_set_active(chip, rstvec); - -- return brcmf_chip_cm3_exitdl(chip); -+ return brcmf_chip_cm3_set_active(chip); - } - - bool brcmf_chip_sr_capable(struct brcmf_chip *pub) ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h -@@ -64,7 +64,7 @@ struct brcmf_core { - * @write32: write 32-bit value over bus. - * @prepare: prepare bus for core configuration. - * @setup: bus-specific core setup. -- * @exit_dl: exit download state. -+ * @active: chip becomes active. - * The callback should use the provided @rstvec when non-zero. - */ - struct brcmf_buscore_ops { -@@ -72,7 +72,7 @@ struct brcmf_buscore_ops { - void (*write32)(void *ctx, u32 addr, u32 value); - int (*prepare)(void *ctx); - int (*setup)(void *ctx, struct brcmf_chip *chip); -- void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec); -+ void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); - }; - - struct brcmf_chip *brcmf_chip_attach(void *ctx, -@@ -84,8 +84,8 @@ bool brcmf_chip_iscoreup(struct brcmf_co - void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset); - void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, - u32 postreset); --void brcmf_chip_enter_download(struct brcmf_chip *ci); --bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec); -+void brcmf_chip_set_passive(struct brcmf_chip *ci); -+bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); - bool brcmf_chip_sr_capable(struct brcmf_chip *pub); - - #endif /* BRCMF_AXIDMP_H */ ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -509,7 +509,7 @@ static void brcmf_pcie_attach(struct brc - - static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) - { -- brcmf_chip_enter_download(devinfo->ci); -+ brcmf_chip_set_passive(devinfo->ci); - - if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { - brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); -@@ -536,7 +536,7 @@ static int brcmf_pcie_exit_download_stat - brcmf_chip_resetcore(core, 0, 0, 0); - } - -- return !brcmf_chip_exit_download(devinfo->ci, resetintr); -+ return !brcmf_chip_set_active(devinfo->ci, resetintr); - } - - -@@ -1566,8 +1566,8 @@ static int brcmf_pcie_buscoreprep(void * - } - - --static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip, -- u32 rstvec) -+static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, -+ u32 rstvec) - { - struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; - -@@ -1577,7 +1577,7 @@ static void brcmf_pcie_buscore_exitdl(vo - - static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { - .prepare = brcmf_pcie_buscoreprep, -- .exit_dl = brcmf_pcie_buscore_exitdl, -+ .activate = brcmf_pcie_buscore_activate, - .read32 = brcmf_pcie_buscore_read32, - .write32 = brcmf_pcie_buscore_write32, - }; ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -3357,7 +3357,7 @@ static int brcmf_sdio_download_firmware( - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - - /* Keep arm in reset */ -- brcmf_chip_enter_download(bus->ci); -+ brcmf_chip_set_passive(bus->ci); - - rstvec = get_unaligned_le32(fw->data); - brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); -@@ -3378,7 +3378,7 @@ static int brcmf_sdio_download_firmware( - } - - /* Take arm out of reset */ -- if (!brcmf_chip_exit_download(bus->ci, rstvec)) { -+ if (!brcmf_chip_set_active(bus->ci, rstvec)) { - brcmf_err("error getting out of ARM core reset\n"); - goto err; - } -@@ -3771,8 +3771,8 @@ static int brcmf_sdio_buscoreprep(void * - return 0; - } - --static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip, -- u32 rstvec) -+static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip, -+ u32 rstvec) - { - struct brcmf_sdio_dev *sdiodev = ctx; - struct brcmf_core *core; -@@ -3815,7 +3815,7 @@ static void brcmf_sdio_buscore_write32(v - - static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { - .prepare = brcmf_sdio_buscoreprep, -- .exit_dl = brcmf_sdio_buscore_exitdl, -+ .activate = brcmf_sdio_buscore_activate, - .read32 = brcmf_sdio_buscore_read32, - .write32 = brcmf_sdio_buscore_write32, - }; -@@ -4239,12 +4239,11 @@ void brcmf_sdio_remove(struct brcmf_sdio - sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - /* Leave the device in state where it is -- * 'quiet'. This is done by putting it in -- * download_state which essentially resets -- * all necessary cores. -+ * 'passive'. This is done by resetting all -+ * necessary cores. - */ - msleep(20); -- brcmf_chip_enter_download(bus->ci); -+ brcmf_chip_set_passive(bus->ci); - brcmf_sdio_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); - } diff --git a/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch b/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch deleted file mode 100644 index 6b1dd8144f..0000000000 --- a/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:30 +0100 -Subject: [PATCH] brcmfmac: assure device is ready for download after - brcmf_chip_attach() - -Make the brcmf_chip_attach() function responsible for putting the -device in a state where it is accessible for firmware download. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -786,12 +786,6 @@ static int brcmf_chip_setup(struct brcmf - if (chip->ops->setup) - ret = chip->ops->setup(chip->ctx, pub); - -- /* -- * Make sure any on-chip ARM is off (in case strapping is wrong), -- * or downloaded code was already running. -- */ -- brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3); -- brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4); - return ret; - } - -@@ -833,6 +827,8 @@ struct brcmf_chip *brcmf_chip_attach(voi - if (err < 0) - goto fail; - -+ /* assure chip is passive for download */ -+ brcmf_chip_set_passive(&chip->pub); - return &chip->pub; - - fail: ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -509,8 +509,6 @@ static void brcmf_pcie_attach(struct brc - - static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) - { -- brcmf_chip_set_passive(devinfo->ci); -- - if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { - brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -3356,9 +3356,6 @@ static int brcmf_sdio_download_firmware( - sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - -- /* Keep arm in reset */ -- brcmf_chip_set_passive(bus->ci); -- - rstvec = get_unaligned_le32(fw->data); - brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); - diff --git a/package/kernel/mac80211/patches/342-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch b/package/kernel/mac80211/patches/342-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch new file mode 100644 index 0000000000..d46b300daa --- /dev/null +++ b/package/kernel/mac80211/patches/342-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch @@ -0,0 +1,47 @@ +From: "Fu, Zhonghui" +Date: Mon, 11 May 2015 10:41:32 +0800 +Subject: [PATCH] brcmfmac: prohibit ACPI power management for brcmfmac driver + +ACPI will manage WiFi chip's power state during suspend/resume +process on some tablet platforms(such as ASUS T100TA). This is +not supported by brcmfmac driver now, and the context of WiFi +chip will be damaged after resume. This patch informs ACPI not +to manage WiFi chip's power state. + +Signed-off-by: Zhonghui Fu +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -1122,6 +1123,8 @@ static int brcmf_ops_sdio_probe(struct s + int err; + struct brcmf_sdio_dev *sdiodev; + struct brcmf_bus *bus_if; ++ struct device *dev; ++ struct acpi_device *adev; + + brcmf_dbg(SDIO, "Enter\n"); + brcmf_dbg(SDIO, "Class=%x\n", func->class); +@@ -1129,6 +1132,12 @@ static int brcmf_ops_sdio_probe(struct s + brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); + brcmf_dbg(SDIO, "Function#: %d\n", func->num); + ++ /* prohibit ACPI power management for this device */ ++ dev = &func->dev; ++ adev = ACPI_COMPANION(dev); ++ if (adev) ++ adev->flags.power_manageable = 0; ++ + /* Consume func num 1 but dont do anything with it. */ + if (func->num == 1) + return 0; diff --git a/package/kernel/mac80211/patches/343-brcmfmac-avoid-gcc-5.1-warning.patch b/package/kernel/mac80211/patches/343-brcmfmac-avoid-gcc-5.1-warning.patch new file mode 100644 index 0000000000..9b4609fb75 --- /dev/null +++ b/package/kernel/mac80211/patches/343-brcmfmac-avoid-gcc-5.1-warning.patch @@ -0,0 +1,30 @@ +From: Arnd Bergmann +Date: Tue, 12 May 2015 23:54:25 +0200 +Subject: [PATCH] brcmfmac: avoid gcc-5.1 warning + +gcc-5.0 gained a new warning in the fwsignal portion of the brcmfmac +driver: + +drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c: In function 'brcmf_fws_txs_process': +drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c:1478:8: warning: 'skb' may be used uninitialized in this function [-Wmaybe-uninitialized] + +This is a false positive, and marking the brcmf_fws_hanger_poppkt function +as 'static inline' makes the warning go away. I have checked the object +file output and while a little code gets moved around, the size of +the binary remains identical. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -635,7 +635,7 @@ static int brcmf_fws_hanger_pushpkt(stru + return 0; + } + +-static int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h, ++static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h, + u32 slot_id, struct sk_buff **pktout, + bool remove_item) + { diff --git a/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch b/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch deleted file mode 100644 index bcc2ed4868..0000000000 --- a/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch +++ /dev/null @@ -1,367 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:31 +0100 -Subject: [PATCH] brcmfmac: extract ram size info from internal memory - registers - -Instead of hard-coded memory sizes it is possible to obtain that -information from the internal memory registers. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -100,9 +100,6 @@ - #define BCM4329_CORE_SOCRAM_BASE 0x18003000 - /* ARM Cortex M3 core, ID 0x82a */ - #define BCM4329_CORE_ARM_BASE 0x18002000 --#define BCM4329_RAMSIZE 0x48000 --/* bcm43143 */ --#define BCM43143_RAMSIZE 0x70000 - - #define CORE_SB(base, field) \ - (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) -@@ -150,6 +147,78 @@ struct sbconfig { - u32 sbidhigh; /* identification */ - }; - -+/* bankidx and bankinfo reg defines corerev >= 8 */ -+#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 -+#define SOCRAM_BANKINFO_SZMASK 0x0000007f -+#define SOCRAM_BANKIDX_ROM_MASK 0x00000100 -+ -+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 -+/* socram bankinfo memtype */ -+#define SOCRAM_MEMTYPE_RAM 0 -+#define SOCRAM_MEMTYPE_R0M 1 -+#define SOCRAM_MEMTYPE_DEVRAM 2 -+ -+#define SOCRAM_BANKINFO_SZBASE 8192 -+#define SRCI_LSS_MASK 0x00f00000 -+#define SRCI_LSS_SHIFT 20 -+#define SRCI_SRNB_MASK 0xf0 -+#define SRCI_SRNB_SHIFT 4 -+#define SRCI_SRBSZ_MASK 0xf -+#define SRCI_SRBSZ_SHIFT 0 -+#define SR_BSZ_BASE 14 -+ -+struct sbsocramregs { -+ u32 coreinfo; -+ u32 bwalloc; -+ u32 extracoreinfo; -+ u32 biststat; -+ u32 bankidx; -+ u32 standbyctrl; -+ -+ u32 errlogstatus; /* rev 6 */ -+ u32 errlogaddr; /* rev 6 */ -+ /* used for patching rev 3 & 5 */ -+ u32 cambankidx; -+ u32 cambankstandbyctrl; -+ u32 cambankpatchctrl; -+ u32 cambankpatchtblbaseaddr; -+ u32 cambankcmdreg; -+ u32 cambankdatareg; -+ u32 cambankmaskreg; -+ u32 PAD[1]; -+ u32 bankinfo; /* corev 8 */ -+ u32 bankpda; -+ u32 PAD[14]; -+ u32 extmemconfig; -+ u32 extmemparitycsr; -+ u32 extmemparityerrdata; -+ u32 extmemparityerrcnt; -+ u32 extmemwrctrlandsize; -+ u32 PAD[84]; -+ u32 workaround; -+ u32 pwrctl; /* corerev >= 2 */ -+ u32 PAD[133]; -+ u32 sr_control; /* corerev >= 15 */ -+ u32 sr_status; /* corerev >= 15 */ -+ u32 sr_address; /* corerev >= 15 */ -+ u32 sr_data; /* corerev >= 15 */ -+}; -+ -+#define SOCRAMREGOFFS(_f) offsetof(struct sbsocramregs, _f) -+ -+#define ARMCR4_CAP (0x04) -+#define ARMCR4_BANKIDX (0x40) -+#define ARMCR4_BANKINFO (0x44) -+#define ARMCR4_BANKPDA (0x4C) -+ -+#define ARMCR4_TCBBNB_MASK 0xf0 -+#define ARMCR4_TCBBNB_SHIFT 4 -+#define ARMCR4_TCBANB_MASK 0xf -+#define ARMCR4_TCBANB_SHIFT 0 -+ -+#define ARMCR4_BSZ_MASK 0x3f -+#define ARMCR4_BSZ_MULT 8192 -+ - struct brcmf_core_priv { - struct brcmf_core pub; - u32 wrapbase; -@@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct - break; - case BCMA_CORE_ARM_CR4: - cpu_found = true; -- if (ci->pub.rambase == 0) { -- brcmf_err("RAM base not provided with ARM CR4 core\n"); -- return -ENOMEM; -- } - break; - default: - break; -@@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct - brcmf_err("RAM core not provided with ARM CM3 core\n"); - return -ENODEV; - } -- if (!ci->pub.ramsize) { -- brcmf_err("RAM size is undetermined\n"); -- return -ENOMEM; -- } - return 0; - } - --static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) -+static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg) - { -- switch (ci->pub.chip) { -- case BRCM_CC_4329_CHIP_ID: -- ci->pub.ramsize = BCM4329_RAMSIZE; -- break; -- case BRCM_CC_43143_CHIP_ID: -- ci->pub.ramsize = BCM43143_RAMSIZE; -- break; -- case BRCM_CC_43241_CHIP_ID: -- ci->pub.ramsize = 0x90000; -- break; -- case BRCM_CC_4330_CHIP_ID: -- ci->pub.ramsize = 0x48000; -- break; -+ return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg); -+} -+ -+static void brcmf_chip_core_write32(struct brcmf_core_priv *core, -+ u16 reg, u32 val) -+{ -+ core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val); -+} -+ -+static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx, -+ u32 *banksize) -+{ -+ u32 bankinfo; -+ u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); -+ -+ bankidx |= idx; -+ brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx); -+ bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo)); -+ *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1; -+ *banksize *= SOCRAM_BANKINFO_SZBASE; -+ return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK); -+} -+ -+static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize, -+ u32 *srsize) -+{ -+ u32 coreinfo; -+ uint nb, banksize, lss; -+ bool retent; -+ int i; -+ -+ *ramsize = 0; -+ *srsize = 0; -+ -+ if (WARN_ON(sr->pub.rev < 4)) -+ return; -+ -+ if (!brcmf_chip_iscoreup(&sr->pub)) -+ brcmf_chip_resetcore(&sr->pub, 0, 0, 0); -+ -+ /* Get info for determining size */ -+ coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo)); -+ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ -+ if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) { -+ banksize = (coreinfo & SRCI_SRBSZ_MASK); -+ lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; -+ if (lss != 0) -+ nb--; -+ *ramsize = nb * (1 << (banksize + SR_BSZ_BASE)); -+ if (lss != 0) -+ *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE)); -+ } else { -+ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ for (i = 0; i < nb; i++) { -+ retent = brcmf_chip_socram_banksize(sr, i, &banksize); -+ *ramsize += banksize; -+ if (retent) -+ *srsize += banksize; -+ } -+ } -+ -+ /* hardcoded save&restore memory sizes */ -+ switch (sr->chip->pub.chip) { - case BRCM_CC_4334_CHIP_ID: -- case BRCM_CC_43340_CHIP_ID: -- ci->pub.ramsize = 0x80000; -+ if (sr->chip->pub.chiprev < 2) -+ *srsize = (32 * 1024); - break; -- case BRCM_CC_4335_CHIP_ID: -- ci->pub.ramsize = 0xc0000; -- ci->pub.rambase = 0x180000; -- break; -- case BRCM_CC_43362_CHIP_ID: -- ci->pub.ramsize = 0x3c000; -+ default: - break; -+ } -+} -+ -+/** Return the TCM-RAM size of the ARMCR4 core. */ -+static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4) -+{ -+ u32 corecap; -+ u32 memsize = 0; -+ u32 nab; -+ u32 nbb; -+ u32 totb; -+ u32 bxinfo; -+ u32 idx; -+ -+ corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP); -+ -+ nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT; -+ nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT; -+ totb = nab + nbb; -+ -+ for (idx = 0; idx < totb; idx++) { -+ brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx); -+ bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO); -+ memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT; -+ } -+ -+ return memsize; -+} -+ -+static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) -+{ -+ switch (ci->pub.chip) { - case BRCM_CC_4345_CHIP_ID: -- ci->pub.ramsize = 0xc8000; -- ci->pub.rambase = 0x198000; -- break; -+ return 0x198000; -+ case BRCM_CC_4335_CHIP_ID: - case BRCM_CC_4339_CHIP_ID: - case BRCM_CC_4354_CHIP_ID: - case BRCM_CC_4356_CHIP_ID: - case BRCM_CC_43567_CHIP_ID: - case BRCM_CC_43569_CHIP_ID: - case BRCM_CC_43570_CHIP_ID: -- ci->pub.ramsize = 0xc0000; -- ci->pub.rambase = 0x180000; -- break; - case BRCM_CC_43602_CHIP_ID: -- ci->pub.ramsize = 0xf0000; -- ci->pub.rambase = 0x180000; -- break; -+ return 0x180000; - default: - brcmf_err("unknown chip: %s\n", ci->pub.name); - break; - } -+ return 0; -+} -+ -+static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) -+{ -+ struct brcmf_core_priv *mem_core; -+ struct brcmf_core *mem; -+ -+ mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4); -+ if (mem) { -+ mem_core = container_of(mem, struct brcmf_core_priv, pub); -+ ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core); -+ ci->pub.rambase = brcmf_chip_tcm_rambase(ci); -+ if (!ci->pub.rambase) { -+ brcmf_err("RAM base not provided with ARM CR4 core\n"); -+ return -EINVAL; -+ } -+ } else { -+ mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM); -+ mem_core = container_of(mem, struct brcmf_core_priv, pub); -+ brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize, -+ &ci->pub.srsize); -+ } -+ brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n", -+ ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize, -+ ci->pub.srsize, ci->pub.srsize); -+ -+ if (!ci->pub.ramsize) { -+ brcmf_err("RAM size is undetermined\n"); -+ return -ENOMEM; -+ } -+ return 0; - } - - static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr, -@@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct - struct brcmf_core *core; - u32 regdata; - u32 socitype; -+ int ret; - - /* Get CC core rev - * Chipid is assume to be at offset 0 from SI_ENUM_BASE -@@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct - return -ENODEV; - } - -- brcmf_chip_get_raminfo(ci); -- -- return brcmf_chip_cores_check(ci); -+ ret = brcmf_chip_cores_check(ci); -+ if (ret) -+ return ret; -+ -+ /* assure chip is passive for core access */ -+ brcmf_chip_set_passive(&ci->pub); -+ return brcmf_chip_get_raminfo(ci); - } - - static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) -@@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(voi - if (err < 0) - goto fail; - -- /* assure chip is passive for download */ -- brcmf_chip_set_passive(&chip->pub); - return &chip->pub; - - fail: ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h -@@ -30,7 +30,8 @@ - * @pmucaps: PMU capabilities. - * @pmurev: PMU revision. - * @rambase: RAM base address (only applicable for ARM CR4 chips). -- * @ramsize: amount of RAM on chip. -+ * @ramsize: amount of RAM on chip including retention. -+ * @srsize: amount of retention RAM on chip. - * @name: string representation of the chip identifier. - */ - struct brcmf_chip { -@@ -41,6 +42,7 @@ struct brcmf_chip { - u32 pmurev; - u32 rambase; - u32 ramsize; -+ u32 srsize; - char name[8]; - }; - diff --git a/package/kernel/mac80211/patches/344-0001-brcmfmac-allow-device-tree-node-without-interrupts-p.patch b/package/kernel/mac80211/patches/344-0001-brcmfmac-allow-device-tree-node-without-interrupts-p.patch new file mode 100644 index 0000000000..b16782d593 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0001-brcmfmac-allow-device-tree-node-without-interrupts-p.patch @@ -0,0 +1,45 @@ +From: Arend van Spriel +Date: Wed, 20 May 2015 14:09:47 +0200 +Subject: [PATCH] brcmfmac: allow device tree node without 'interrupts' + property + +As described in the device tree bindings for 'brcm,bcm4329-fmac' +nodes, the interrupts property is optional. So adding a check +for the presence of this property before attempting to parse +and map the interrupt. If not present or parsing fails return +and fallback to in-band sdio interrupt. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c +@@ -39,10 +39,16 @@ void brcmf_of_probe(struct brcmf_sdio_de + if (!sdiodev->pdata) + return; + ++ if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) ++ sdiodev->pdata->drive_strength = val; ++ ++ /* make sure there are interrupts defined in the node */ ++ if (!of_find_property(np, "interrupts", NULL)) ++ return; ++ + irq = irq_of_parse_and_map(np, 0); + if (!irq) { + brcmf_err("interrupt could not be mapped\n"); +- devm_kfree(dev, sdiodev->pdata); + return; + } + irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); +@@ -50,7 +56,4 @@ void brcmf_of_probe(struct brcmf_sdio_de + sdiodev->pdata->oob_irq_supported = true; + sdiodev->pdata->oob_irq_nr = irq; + sdiodev->pdata->oob_irq_flags = irqf; +- +- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) +- sdiodev->pdata->drive_strength = val; + } diff --git a/package/kernel/mac80211/patches/344-0002-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch b/package/kernel/mac80211/patches/344-0002-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch new file mode 100644 index 0000000000..f81250ee4c --- /dev/null +++ b/package/kernel/mac80211/patches/344-0002-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch @@ -0,0 +1,87 @@ +From: Hante Meuleman +Date: Wed, 20 May 2015 14:09:48 +0200 +Subject: [PATCH] brcmfmac: Improve throughput by scheduling msbug flow worker. + +The tx flow worker in msgbuf gets scheduled at tx till a certain +threshold has been reached. Then the tx completes will take over +the scheduling. When amsdu and ampdu is used the frames are +transferred wireless in a very bulky fashion, in combination +with this scheduling algorithm and buffer limiters in the stack +this can result in limited throughput. This change causes the +flow worker to be scheduled more frequently from tx. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Daniel (Deognyoun) Kim +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +@@ -249,8 +249,8 @@ void brcmf_flowring_delete(struct brcmf_ + } + + +-void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, +- struct sk_buff *skb) ++u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, ++ struct sk_buff *skb) + { + struct brcmf_flowring_ring *ring; + +@@ -271,6 +271,7 @@ void brcmf_flowring_enqueue(struct brcmf + if (skb_queue_len(&ring->skblist) < BRCMF_FLOWRING_LOW) + brcmf_flowring_block(flow, flowid, false); + } ++ return skb_queue_len(&ring->skblist); + } + + +--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h +@@ -64,8 +64,8 @@ u32 brcmf_flowring_create(struct brcmf_f + void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid); + void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid); + u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid); +-void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, +- struct sk_buff *skb); ++u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, ++ struct sk_buff *skb); + struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid); + void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, + struct sk_buff *skb); +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -73,7 +73,7 @@ + #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 + #define BRCMF_MSGBUF_TX_FLUSH_CNT2 96 + +-#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 64 ++#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 + #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 + + struct msgbuf_common_hdr { +@@ -797,6 +797,8 @@ static int brcmf_msgbuf_txdata(struct br + struct brcmf_flowring *flow = msgbuf->flow; + struct ethhdr *eh = (struct ethhdr *)(skb->data); + u32 flowid; ++ u32 queue_count; ++ bool force; + + flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx); + if (flowid == BRCMF_FLOWRING_INVALID_ID) { +@@ -804,8 +806,9 @@ static int brcmf_msgbuf_txdata(struct br + if (flowid == BRCMF_FLOWRING_INVALID_ID) + return -ENOMEM; + } +- brcmf_flowring_enqueue(flow, flowid, skb); +- brcmf_msgbuf_schedule_txdata(msgbuf, flowid, false); ++ queue_count = brcmf_flowring_enqueue(flow, flowid, skb); ++ force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0); ++ brcmf_msgbuf_schedule_txdata(msgbuf, flowid, force); + + return 0; + } diff --git a/package/kernel/mac80211/patches/344-0003-brcmfmac-remove-pci-shared-structure-rev4-support.patch b/package/kernel/mac80211/patches/344-0003-brcmfmac-remove-pci-shared-structure-rev4-support.patch new file mode 100644 index 0000000000..61153c4a98 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0003-brcmfmac-remove-pci-shared-structure-rev4-support.patch @@ -0,0 +1,41 @@ +From: Franky Lin +Date: Wed, 20 May 2015 14:09:49 +0200 +Subject: [PATCH] brcmfmac: remove pci shared structure rev4 support + +All pcie full dongle chips supported by fmac are using rev 5+ shared +structure. This patch removes the rev4 related code. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -112,10 +112,9 @@ enum brcmf_pcie_state { + BRCMF_PCIE_MB_INT_D2H3_DB0 | \ + BRCMF_PCIE_MB_INT_D2H3_DB1) + +-#define BRCMF_PCIE_MIN_SHARED_VERSION 4 ++#define BRCMF_PCIE_MIN_SHARED_VERSION 5 + #define BRCMF_PCIE_MAX_SHARED_VERSION 5 + #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF +-#define BRCMF_PCIE_SHARED_TXPUSH_SUPPORT 0x4000 + + #define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 + #define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 +@@ -1280,11 +1279,6 @@ brcmf_pcie_init_share_ram_info(struct br + brcmf_err("Unsupported PCIE version %d\n", version); + return -EINVAL; + } +- if (shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT) { +- brcmf_err("Unsupported legacy TX mode 0x%x\n", +- shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT); +- return -EINVAL; +- } + + addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET; + shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr); diff --git a/package/kernel/mac80211/patches/344-0004-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch b/package/kernel/mac80211/patches/344-0004-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch new file mode 100644 index 0000000000..8c8eebe44f --- /dev/null +++ b/package/kernel/mac80211/patches/344-0004-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch @@ -0,0 +1,120 @@ +From: Franky Lin +Date: Wed, 20 May 2015 14:09:50 +0200 +Subject: [PATCH] brcmfmac: remove dummy cache flush/invalidate function + +brcmf_dma_flush and brcmf_dma_invalidate_cache are not necessary and +have never been implemented. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c +@@ -22,17 +22,6 @@ + #include "core.h" + #include "commonring.h" + +- +-/* dma flushing needs implementation for mips and arm platforms. Should +- * be put in util. Note, this is not real flushing. It is virtual non +- * cached memory. Only write buffers should have to be drained. Though +- * this may be different depending on platform...... +- * SEE ALSO msgbuf.c +- */ +-#define brcmf_dma_flush(addr, len) +-#define brcmf_dma_invalidate_cache(addr, len) +- +- + void brcmf_commonring_register_cb(struct brcmf_commonring *commonring, + int (*cr_ring_bell)(void *ctx), + int (*cr_update_rptr)(void *ctx), +@@ -206,14 +195,9 @@ int brcmf_commonring_write_complete(stru + address = commonring->buf_addr; + address += (commonring->f_ptr * commonring->item_len); + if (commonring->f_ptr > commonring->w_ptr) { +- brcmf_dma_flush(address, +- (commonring->depth - commonring->f_ptr) * +- commonring->item_len); + address = commonring->buf_addr; + commonring->f_ptr = 0; + } +- brcmf_dma_flush(address, (commonring->w_ptr - commonring->f_ptr) * +- commonring->item_len); + + commonring->f_ptr = commonring->w_ptr; + +@@ -258,8 +242,6 @@ void *brcmf_commonring_get_read_ptr(stru + if (commonring->r_ptr == commonring->depth) + commonring->r_ptr = 0; + +- brcmf_dma_invalidate_cache(ret_addr, *n_ items * commonring->item_len); +- + return ret_addr; + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -278,16 +278,6 @@ struct brcmf_msgbuf_pktids { + struct brcmf_msgbuf_pktid *array; + }; + +- +-/* dma flushing needs implementation for mips and arm platforms. Should +- * be put in util. Note, this is not real flushing. It is virtual non +- * cached memory. Only write buffers should have to be drained. Though +- * this may be different depending on platform...... +- */ +-#define brcmf_dma_flush(addr, len) +-#define brcmf_dma_invalidate_cache(addr, len) +- +- + static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf); + + +@@ -462,7 +452,6 @@ static int brcmf_msgbuf_tx_ioctl(struct + memcpy(msgbuf->ioctbuf, buf, buf_len); + else + memset(msgbuf->ioctbuf, 0, buf_len); +- brcmf_dma_flush(ioctl_buf, buf_len); + + err = brcmf_commonring_write_complete(commonring); + brcmf_commonring_unlock(commonring); +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -276,15 +276,6 @@ static const u32 brcmf_ring_itemsize[BRC + }; + + +-/* dma flushing needs implementation for mips and arm platforms. Should +- * be put in util. Note, this is not real flushing. It is virtual non +- * cached memory. Only write buffers should have to be drained. Though +- * this may be different depending on platform...... +- */ +-#define brcmf_dma_flush(addr, len) +-#define brcmf_dma_invalidate_cache(addr, len) +- +- + static u32 + brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) + { +@@ -1174,7 +1165,6 @@ static int brcmf_pcie_init_scratchbuffer + goto fail; + + memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); +- brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); + + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; +@@ -1192,7 +1182,6 @@ static int brcmf_pcie_init_scratchbuffer + goto fail; + + memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); +- brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); + + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; diff --git a/package/kernel/mac80211/patches/344-0005-brcmfmac-add-support-for-dma-indices-feature.patch b/package/kernel/mac80211/patches/344-0005-brcmfmac-add-support-for-dma-indices-feature.patch new file mode 100644 index 0000000000..2f50abd0e1 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0005-brcmfmac-add-support-for-dma-indices-feature.patch @@ -0,0 +1,270 @@ +From: Franky Lin +Date: Wed, 20 May 2015 14:09:51 +0200 +Subject: [PATCH] brcmfmac: add support for dma indices feature + +PCIe full dongle firmware can support a dma indices feature with which +firmware can update/fetch the read/write indices of message buffer +rings on both host to dongle and dongle to host directions. The support is +announced by firmware through shared flags. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -115,6 +115,8 @@ enum brcmf_pcie_state { + #define BRCMF_PCIE_MIN_SHARED_VERSION 5 + #define BRCMF_PCIE_MAX_SHARED_VERSION 5 + #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF ++#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 ++#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 + + #define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 + #define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 +@@ -146,6 +148,10 @@ enum brcmf_pcie_state { + #define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8 + #define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12 + #define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16 ++#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET 20 ++#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET 28 ++#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET 36 ++#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET 44 + #define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0 + #define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52 + +@@ -247,6 +253,13 @@ struct brcmf_pciedev_info { + bool mbdata_completed; + bool irq_allocated; + bool wowl_enabled; ++ u8 dma_idx_sz; ++ void *idxbuf; ++ u32 idxbuf_sz; ++ dma_addr_t idxbuf_dmahandle; ++ 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_pcie_ringbuf { +@@ -323,6 +336,25 @@ brcmf_pcie_write_tcm16(struct brcmf_pcie + } + + ++static u16 ++brcmf_pcie_read_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset) ++{ ++ u16 *address = devinfo->idxbuf + mem_offset; ++ ++ return (*(address)); ++} ++ ++ ++static void ++brcmf_pcie_write_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset, ++ u16 value) ++{ ++ u16 *address = devinfo->idxbuf + mem_offset; ++ ++ *(address) = value; ++} ++ ++ + static u32 + brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset) + { +@@ -868,7 +900,7 @@ static int brcmf_pcie_ring_mb_write_rptr + brcmf_dbg(PCIE, "W r_ptr %d (%d), ring %d\n", commonring->r_ptr, + commonring->w_ptr, ring->id); + +- brcmf_pcie_write_tcm16(devinfo, ring->r_idx_addr, commonring->r_ptr); ++ devinfo->write_ptr(devinfo, ring->r_idx_addr, commonring->r_ptr); + + return 0; + } +@@ -886,7 +918,7 @@ static int brcmf_pcie_ring_mb_write_wptr + brcmf_dbg(PCIE, "W w_ptr %d (%d), ring %d\n", commonring->w_ptr, + commonring->r_ptr, ring->id); + +- brcmf_pcie_write_tcm16(devinfo, ring->w_idx_addr, commonring->w_ptr); ++ devinfo->write_ptr(devinfo, ring->w_idx_addr, commonring->w_ptr); + + return 0; + } +@@ -915,7 +947,7 @@ static int brcmf_pcie_ring_mb_update_rpt + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + +- commonring->r_ptr = brcmf_pcie_read_tcm16(devinfo, ring->r_idx_addr); ++ commonring->r_ptr = devinfo->read_ptr(devinfo, ring->r_idx_addr); + + brcmf_dbg(PCIE, "R r_ptr %d (%d), ring %d\n", commonring->r_ptr, + commonring->w_ptr, ring->id); +@@ -933,7 +965,7 @@ static int brcmf_pcie_ring_mb_update_wpt + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + +- commonring->w_ptr = brcmf_pcie_read_tcm16(devinfo, ring->w_idx_addr); ++ commonring->w_ptr = devinfo->read_ptr(devinfo, ring->w_idx_addr); + + brcmf_dbg(PCIE, "R w_ptr %d (%d), ring %d\n", commonring->w_ptr, + commonring->r_ptr, ring->id); +@@ -1038,6 +1070,13 @@ static void brcmf_pcie_release_ringbuffe + } + kfree(devinfo->shared.flowrings); + devinfo->shared.flowrings = NULL; ++ if (devinfo->idxbuf) { ++ dma_free_coherent(&devinfo->pdev->dev, ++ devinfo->idxbuf_sz, ++ devinfo->idxbuf, ++ devinfo->idxbuf_dmahandle); ++ devinfo->idxbuf = NULL; ++ } + } + + +@@ -1053,19 +1092,72 @@ static int brcmf_pcie_init_ringbuffers(s + u32 addr; + u32 ring_mem_ptr; + u32 i; ++ u64 address; ++ u32 bufsz; + u16 max_sub_queues; ++ u8 idx_offset; + + ring_addr = devinfo->shared.ring_info_addr; + brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr); ++ addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; ++ max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); + +- addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; +- d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); +- addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; +- d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); +- addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; +- h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); +- addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; +- h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); ++ if (devinfo->dma_idx_sz != 0) { ++ bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) * ++ devinfo->dma_idx_sz * 2; ++ devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz, ++ &devinfo->idxbuf_dmahandle, ++ GFP_KERNEL); ++ if (!devinfo->idxbuf) ++ devinfo->dma_idx_sz = 0; ++ } ++ ++ if (devinfo->dma_idx_sz == 0) { ++ addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; ++ d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); ++ addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; ++ d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); ++ addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; ++ h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); ++ addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; ++ h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); ++ idx_offset = sizeof(u32); ++ devinfo->write_ptr = brcmf_pcie_write_tcm16; ++ devinfo->read_ptr = brcmf_pcie_read_tcm16; ++ brcmf_dbg(PCIE, "Using TCM indices\n"); ++ } else { ++ memset(devinfo->idxbuf, 0, bufsz); ++ devinfo->idxbuf_sz = bufsz; ++ idx_offset = devinfo->dma_idx_sz; ++ devinfo->write_ptr = brcmf_pcie_write_idx; ++ devinfo->read_ptr = brcmf_pcie_read_idx; ++ ++ h2d_w_idx_ptr = 0; ++ addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET; ++ address = (u64)devinfo->idxbuf_dmahandle; ++ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); ++ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); ++ ++ h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset; ++ addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET; ++ address += max_sub_queues * idx_offset; ++ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); ++ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); ++ ++ d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset; ++ addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET; ++ address += max_sub_queues * idx_offset; ++ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); ++ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); ++ ++ d2h_r_idx_ptr = d2h_w_idx_ptr + ++ BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; ++ addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET; ++ address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; ++ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); ++ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); ++ brcmf_dbg(PCIE, "Using host memory indices\n"); ++ } + + addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET; + ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr); +@@ -1079,8 +1171,8 @@ static int brcmf_pcie_init_ringbuffers(s + ring->id = i; + devinfo->shared.commonrings[i] = ring; + +- h2d_w_idx_ptr += sizeof(u32); +- h2d_r_idx_ptr += sizeof(u32); ++ h2d_w_idx_ptr += idx_offset; ++ h2d_r_idx_ptr += idx_offset; + ring_mem_ptr += BRCMF_RING_MEM_SZ; + } + +@@ -1094,13 +1186,11 @@ static int brcmf_pcie_init_ringbuffers(s + ring->id = i; + devinfo->shared.commonrings[i] = ring; + +- d2h_w_idx_ptr += sizeof(u32); +- d2h_r_idx_ptr += sizeof(u32); ++ d2h_w_idx_ptr += idx_offset; ++ d2h_r_idx_ptr += idx_offset; + ring_mem_ptr += BRCMF_RING_MEM_SZ; + } + +- addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; +- max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); + devinfo->shared.nrof_flowrings = + max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS; + rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring), +@@ -1124,15 +1214,15 @@ static int brcmf_pcie_init_ringbuffers(s + ring); + ring->w_idx_addr = h2d_w_idx_ptr; + ring->r_idx_addr = h2d_r_idx_ptr; +- h2d_w_idx_ptr += sizeof(u32); +- h2d_r_idx_ptr += sizeof(u32); ++ h2d_w_idx_ptr += idx_offset; ++ h2d_r_idx_ptr += idx_offset; + } + devinfo->shared.flowrings = rings; + + return 0; + + fail: +- brcmf_err("Allocating commonring buffers failed\n"); ++ brcmf_err("Allocating ring buffers failed\n"); + brcmf_pcie_release_ringbuffers(devinfo); + return -ENOMEM; + } +@@ -1269,6 +1359,14 @@ brcmf_pcie_init_share_ram_info(struct br + return -EINVAL; + } + ++ /* check firmware support dma indicies */ ++ if (shared->flags & BRCMF_PCIE_SHARED_DMA_INDEX) { ++ if (shared->flags & BRCMF_PCIE_SHARED_DMA_2B_IDX) ++ devinfo->dma_idx_sz = sizeof(u16); ++ else ++ devinfo->dma_idx_sz = sizeof(u32); ++ } ++ + addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET; + shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr); + if (shared->max_rxbufpost == 0) diff --git a/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch b/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch deleted file mode 100644 index 69618a7aa7..0000000000 --- a/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:32 +0100 -Subject: [PATCH] brcmfmac: take save&restore memory into account for SDIO - shared info - -The firmware provides pointer to SDIO shared information at end of -RAM during firmware initialization. End of RAM is obviously determined -by the actual ram size, but part of that may be used for save&restore -memory. In that case another location in RAM will hold the pointer. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shar - static int brcmf_sdio_readshared(struct brcmf_sdio *bus, - struct sdpcm_shared *sh) - { -- u32 addr; -+ u32 addr = 0; - int rv; - u32 shaddr = 0; - struct sdpcm_shared_le sh_le; - __le32 addr_le; - -- shaddr = bus->ci->rambase + bus->ci->ramsize - 4; -+ sdio_claim_host(bus->sdiodev->func[1]); -+ brcmf_sdio_bus_sleep(bus, false, false); - - /* - * Read last word in socram to determine - * address of sdpcm_shared structure - */ -- sdio_claim_host(bus->sdiodev->func[1]); -- brcmf_sdio_bus_sleep(bus, false, false); -- rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); -- sdio_release_host(bus->sdiodev->func[1]); -+ shaddr = bus->ci->rambase + bus->ci->ramsize - 4; -+ if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci)) -+ shaddr -= bus->ci->srsize; -+ rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, -+ (u8 *)&addr_le, 4); - if (rv < 0) -- return rv; -- -- addr = le32_to_cpu(addr_le); -- -- brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr); -+ goto fail; - - /* - * Check if addr is valid. - * NVRAM length at the end of memory should have been overwritten. - */ -+ addr = le32_to_cpu(addr_le); - if (!brcmf_sdio_valid_shared_address(addr)) { -- brcmf_err("invalid sdpcm_shared address 0x%08X\n", -- addr); -- return -EINVAL; -+ brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr); -+ rv = -EINVAL; -+ goto fail; - } - -+ brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); -+ - /* Read hndrte_shared structure */ - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, - sizeof(struct sdpcm_shared_le)); - if (rv < 0) -- return rv; -+ goto fail; -+ -+ sdio_release_host(bus->sdiodev->func[1]); - - /* Endianness */ - sh->flags = le32_to_cpu(sh_le.flags); -@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct - sh->flags & SDPCM_SHARED_VERSION_MASK); - return -EPROTO; - } -- - return 0; -+ -+fail: -+ brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n", -+ rv, addr); -+ sdio_release_host(bus->sdiodev->func[1]); -+ return rv; - } - - static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus) diff --git a/package/kernel/mac80211/patches/345-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch b/package/kernel/mac80211/patches/345-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch new file mode 100644 index 0000000000..28408d2b4f --- /dev/null +++ b/package/kernel/mac80211/patches/345-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch @@ -0,0 +1,102 @@ +From: Arend van Spriel +Date: Tue, 26 May 2015 13:19:46 +0200 +Subject: [PATCH] brcmfmac: avoid null pointer access when + brcmf_msgbuf_get_pktid() fails + +The function brcmf_msgbuf_get_pktid() may return a NULL pointer so +the callers should check the return pointer before accessing it to +avoid the crash below (see [1]): + +brcmfmac: brcmf_msgbuf_get_pktid: Invalid packet id 273 (not in use) +BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 +IP: [] skb_pull+0x5/0x50 +PGD 0 +Oops: 0000 [#1] PREEMPT SMP +Modules linked in: pci_stub vboxpci(O) vboxnetflt(O) vboxnetadp(O) vboxdrv(O) + snd_hda_codec_hdmi bnep mousedev hid_generic ushwmon msr ext4 crc16 mbcache + jbd2 sd_mod uas usb_storage ahci libahci libata scsi_mod xhci_pci xhci_hcd + usbcore usb_common +CPU: 0 PID: 1661 Comm: irq/61-brcmf_pc Tainted: G O 4.0.1-MacbookPro-ARCH #1 +Hardware name: Apple Inc. MacBookPro12,1/Mac-E43C1C25D4880AD6, + BIOS MBP121.88Z.0167.B02.1503241251 03/24/2015 +task: ffff880264203cc0 ti: ffff88025ffe4000 task.ti: ffff88025ffe4000 +RIP: 0010:[] [] skb_pull+0x5/0x50 +RSP: 0018:ffff88025ffe7d40 EFLAGS: 00010202 +RAX: 0000000000000000 RBX: ffff88008a33c000 RCX: 0000000000000044 +RDX: 0000000000000000 RSI: 000000000000004a RDI: 0000000000000000 +RBP: ffff88025ffe7da8 R08: 0000000000000096 R09: 000000000000004a +R10: 0000000000000000 R11: 000000000000048e R12: ffff88025ff14f00 +R13: 0000000000000000 R14: ffff880263b48200 R15: ffff88008a33c000 +FS: 0000000000000000(0000) GS:ffff88026ec00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000080 CR3: 000000000180b000 CR4: 00000000003407f0 +Stack: + ffffffffa06aed74 ffff88025ffe7dc8 ffff880263b48270 ffff880263b48278 + 05ea88020000004a 0002ffff81014635 000000001720b2f6 ffff88026ec116c0 + ffff880263b48200 0000000000010000 ffff880263b4ae00 ffff880264203cc0 +Call Trace: + [] ? brcmf_msgbuf_process_rx+0x404/0x480 [brcmfmac] + [] ? irq_finalize_oneshot.part.30+0xf0/0xf0 + [] brcmf_proto_msgbuf_rx_trigger+0x35/0xf0 [brcmfmac] + [] brcmf_pcie_isr_thread_v2+0x8a/0x130 [brcmfmac] + [] irq_thread_fn+0x20/0x50 + [] irq_thread+0x13f/0x170 + [] ? wake_threads_waitq+0x30/0x30 + [] ? irq_thread_dtor+0xb0/0xb0 + [] kthread+0xd8/0xf0 + [] ? kthread_create_on_node+0x1c0/0x1c0 + [] ret_from_fork+0x58/0x90 + [] ? kthread_create_on_node+0x1c0/0x1c0 +Code: 01 83 e2 f7 88 50 01 48 83 c4 08 5b 5d f3 c3 0f 1f 80 00 00 00 00 83 e2 + f7 88 50 01 c3 66 0f 1f 84 00 00 00 00 00 0f 1f +RIP [] skb_pull+0x5/0x50 + RSP +CR2: 0000000000000080 +---[ end trace b074c0f90e7c997d ]--- + +[1] http://mid.gmane.org/20150430193259.GA5630@googlemail.com + +Cc: # v3.18, v3.19, v4.0, v4.1 +Reported-by: Michael Hornung +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -500,11 +500,9 @@ static int brcmf_msgbuf_query_dcmd(struc + msgbuf->rx_pktids, + msgbuf->ioctl_resp_pktid); + if (msgbuf->ioctl_resp_ret_len != 0) { +- if (!skb) { +- brcmf_err("Invalid packet id idx recv'd %d\n", +- msgbuf->ioctl_resp_pktid); ++ if (!skb) + return -EBADF; +- } ++ + memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? + len : msgbuf->ioctl_resp_ret_len); + } +@@ -866,10 +864,8 @@ brcmf_msgbuf_process_txstatus(struct brc + flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; + skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, + msgbuf->tx_pktids, idx); +- if (!skb) { +- brcmf_err("Invalid packet id idx recv'd %d\n", idx); ++ if (!skb) + return; +- } + + set_bit(flowid, msgbuf->txstatus_done_map); + commonring = msgbuf->flowrings[flowid]; +@@ -1148,6 +1144,8 @@ brcmf_msgbuf_process_rx_complete(struct + + skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, + msgbuf->rx_pktids, idx); ++ if (!skb) ++ return; + + if (data_offset) + skb_pull(skb, data_offset); diff --git a/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch b/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch deleted file mode 100644 index 1b10dbb800..0000000000 --- a/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: Arend van Spriel -Date: Wed, 11 Mar 2015 16:11:33 +0100 -Subject: [PATCH] brcmfmac: fix watchdog timer regression - -The watchdog timer is used to put the device in a low-power mode when -it is idle for some time. This timer is stopped during that mode and -should be restarted upon activity. This has been broken by commit -d4150fced0365 ("brcmfmac: Simplify watchdog sleep."). This patch -restores the behaviour as it was before that commit. - -Reported-by: Pontus Fuchs -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -972,7 +972,6 @@ static int brcmf_sdio_clkctl(struct brcm - brcmf_sdio_sdclk(bus, true); - /* Now request HT Avail on the backplane */ - brcmf_sdio_htclk(bus, true, pendok); -- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); - break; - - case CLK_SDONLY: -@@ -984,7 +983,6 @@ static int brcmf_sdio_clkctl(struct brcm - else - brcmf_err("request for %d -> %d\n", - bus->clkstate, target); -- brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); - break; - - case CLK_NONE: -@@ -993,7 +991,6 @@ static int brcmf_sdio_clkctl(struct brcm - brcmf_sdio_htclk(bus, false, false); - /* Now remove the SD clock */ - brcmf_sdio_sdclk(bus, false); -- brcmf_sdio_wd_timer(bus, 0); - break; - } - #ifdef DEBUG -@@ -1048,6 +1045,7 @@ end: - brcmf_sdio_clkctl(bus, CLK_NONE, pendok); - } else { - brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); -+ brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); - } - bus->sleeping = sleep; - brcmf_dbg(SDIO, "new state %s\n", -@@ -4242,6 +4240,7 @@ void brcmf_sdio_remove(struct brcmf_sdio - if (bus->ci) { - if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { - sdio_claim_host(bus->sdiodev->func[1]); -+ brcmf_sdio_wd_timer(bus, 0); - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - /* Leave the device in state where it is - * 'passive'. This is done by resetting all diff --git a/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch b/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch deleted file mode 100644 index af76f13ecd..0000000000 --- a/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Arend van Spriel -Date: Wed, 18 Mar 2015 13:25:21 +0100 -Subject: [PATCH] brcmfmac: avoid runtime-pm for sdio host controller - -Several host controllers supporting runtime-pm are causing issues -with our sdio wireless cards because they disable the sdio interrupt -upon going into runtime suspend. This patch avoids that by doing -a pm_runtime_forbid() call during the probe. Tested with Sony Vaio -Duo 13 which uses sdhci-acpi host controller. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1006,6 +1007,7 @@ static int brcmf_sdiod_remove(struct brc - sg_free_table(&sdiodev->sgtable); - sdiodev->sbwad = 0; - -+ pm_runtime_allow(sdiodev->func[1]->card->host->parent); - return 0; - } - -@@ -1074,7 +1076,7 @@ static int brcmf_sdiod_probe(struct brcm - ret = -ENODEV; - goto out; - } -- -+ pm_runtime_forbid(host->parent); - out: - if (ret) - brcmf_sdiod_remove(sdiodev); diff --git a/package/kernel/mac80211/patches/346-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch b/package/kernel/mac80211/patches/346-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch new file mode 100644 index 0000000000..f0230347ef --- /dev/null +++ b/package/kernel/mac80211/patches/346-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch @@ -0,0 +1,63 @@ +From: Arend van Spriel +Date: Wed, 27 May 2015 19:31:41 +0200 +Subject: [PATCH] brcmfmac: fix invalid access to struct acpi_device fields + +The fields of struct acpi_device are only known when CONFIG_ACPI is +defined. Fix this by using a helper function. This will resolve the +issue found in linux-next: + + ../brcmfmac/bcmsdh.c: In function 'brcmf_ops_sdio_probe': + ../brcmfmac/bcmsdh.c:1139:7: error: dereferencing pointer to incomplete type + adev->flags.power_manageable = 0; + ^ + +Fixes: f0992ace680c ("brcmfmac: prohibit ACPI power management ...") +Cc: Fu, Zhonghui +Reported-by: Stephen Rothwell +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1117,6 +1117,18 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_id + static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; + + ++static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev, ++ int val) ++{ ++#if IS_ENABLED(CONFIG_ACPI) ++ struct acpi_device *adev; ++ ++ adev = ACPI_COMPANION(dev); ++ if (adev) ++ adev->flags.power_manageable = 0; ++#endif ++} ++ + static int brcmf_ops_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) + { +@@ -1124,7 +1136,6 @@ static int brcmf_ops_sdio_probe(struct s + struct brcmf_sdio_dev *sdiodev; + struct brcmf_bus *bus_if; + struct device *dev; +- struct acpi_device *adev; + + brcmf_dbg(SDIO, "Enter\n"); + brcmf_dbg(SDIO, "Class=%x\n", func->class); +@@ -1132,11 +1143,9 @@ static int brcmf_ops_sdio_probe(struct s + brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); + brcmf_dbg(SDIO, "Function#: %d\n", func->num); + +- /* prohibit ACPI power management for this device */ + dev = &func->dev; +- adev = ACPI_COMPANION(dev); +- if (adev) +- adev->flags.power_manageable = 0; ++ /* prohibit ACPI power management for this device */ ++ brcmf_sdiod_acpi_set_power_manageable(dev, 0); + + /* Consume func num 1 but dont do anything with it. */ + if (func->num == 1) diff --git a/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch b/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch deleted file mode 100644 index c419cc68f5..0000000000 --- a/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch +++ /dev/null @@ -1,171 +0,0 @@ -From: Hante Meuleman -Date: Wed, 18 Mar 2015 13:25:22 +0100 -Subject: [PATCH] brcmfmac: Add necessary memory barriers for SDIO. - -SDIO uses a thread to handle all communication with the device, -for this data is exchanged between threads. This data needs proper -memory barriers to make sure that data "exchange" is going correct. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -507,8 +507,8 @@ struct brcmf_sdio { - - struct workqueue_struct *brcmf_wq; - struct work_struct datawork; -- atomic_t dpc_tskcnt; -- atomic_t dpc_running; -+ bool dpc_triggered; -+ bool dpc_running; - - bool txoff; /* Transmit flow-controlled */ - struct brcmf_sdio_count sdcnt; -@@ -2713,6 +2713,7 @@ static void brcmf_sdio_dpc(struct brcmf_ - err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, - bus->ctrl_frame_len); - bus->ctrl_frame_err = err; -+ wmb(); - bus->ctrl_frame_stat = false; - } - sdio_release_host(bus->sdiodev->func[1]); -@@ -2734,6 +2735,7 @@ static void brcmf_sdio_dpc(struct brcmf_ - sdio_claim_host(bus->sdiodev->func[1]); - if (bus->ctrl_frame_stat) { - bus->ctrl_frame_err = -ENODEV; -+ wmb(); - bus->ctrl_frame_stat = false; - brcmf_sdio_wait_event_wakeup(bus); - } -@@ -2744,7 +2746,7 @@ static void brcmf_sdio_dpc(struct brcmf_ - (!atomic_read(&bus->fcstate) && - brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && - data_ok(bus))) { -- atomic_inc(&bus->dpc_tskcnt); -+ bus->dpc_triggered = true; - } - } - -@@ -2940,6 +2942,7 @@ brcmf_sdio_bus_txctl(struct device *dev, - /* Send from dpc */ - bus->ctrl_frame_buf = msg; - bus->ctrl_frame_len = msglen; -+ wmb(); - bus->ctrl_frame_stat = true; - - brcmf_sdio_trigger_dpc(bus); -@@ -2958,6 +2961,7 @@ brcmf_sdio_bus_txctl(struct device *dev, - if (!ret) { - brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", - bus->ctrl_frame_err); -+ rmb(); - ret = bus->ctrl_frame_err; - } - -@@ -3526,8 +3530,8 @@ done: - - void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus) - { -- if (atomic_read(&bus->dpc_tskcnt) == 0) { -- atomic_inc(&bus->dpc_tskcnt); -+ if (!bus->dpc_triggered) { -+ bus->dpc_triggered = true; - queue_work(bus->brcmf_wq, &bus->datawork); - } - } -@@ -3558,7 +3562,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b - if (!bus->intr) - brcmf_err("isr w/o interrupt configured!\n"); - -- atomic_inc(&bus->dpc_tskcnt); -+ bus->dpc_triggered = true; - queue_work(bus->brcmf_wq, &bus->datawork); - } - -@@ -3578,7 +3582,7 @@ static void brcmf_sdio_bus_watchdog(stru - if (!bus->intr || - (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { - -- if (atomic_read(&bus->dpc_tskcnt) == 0) { -+ if (!bus->dpc_triggered) { - u8 devpend; - - sdio_claim_host(bus->sdiodev->func[1]); -@@ -3596,7 +3600,7 @@ static void brcmf_sdio_bus_watchdog(stru - bus->sdcnt.pollcnt++; - atomic_set(&bus->ipend, 1); - -- atomic_inc(&bus->dpc_tskcnt); -+ bus->dpc_triggered = true; - queue_work(bus->brcmf_wq, &bus->datawork); - } - } -@@ -3623,17 +3627,21 @@ static void brcmf_sdio_bus_watchdog(stru - #endif /* DEBUG */ - - /* On idle timeout clear activity flag and/or turn off clock */ -- if ((atomic_read(&bus->dpc_tskcnt) == 0) && -- (atomic_read(&bus->dpc_running) == 0) && -- (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { -- bus->idlecount++; -- if (bus->idlecount > bus->idletime) { -- brcmf_dbg(SDIO, "idle\n"); -- sdio_claim_host(bus->sdiodev->func[1]); -- brcmf_sdio_wd_timer(bus, 0); -+ if (!bus->dpc_triggered) { -+ rmb(); -+ if ((!bus->dpc_running) && (bus->idletime > 0) && -+ (bus->clkstate == CLK_AVAIL)) { -+ bus->idlecount++; -+ if (bus->idlecount > bus->idletime) { -+ brcmf_dbg(SDIO, "idle\n"); -+ sdio_claim_host(bus->sdiodev->func[1]); -+ brcmf_sdio_wd_timer(bus, 0); -+ bus->idlecount = 0; -+ brcmf_sdio_bus_sleep(bus, true, false); -+ sdio_release_host(bus->sdiodev->func[1]); -+ } -+ } else { - bus->idlecount = 0; -- brcmf_sdio_bus_sleep(bus, true, false); -- sdio_release_host(bus->sdiodev->func[1]); - } - } else { - bus->idlecount = 0; -@@ -3645,13 +3653,14 @@ static void brcmf_sdio_dataworker(struct - struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio, - datawork); - -- while (atomic_read(&bus->dpc_tskcnt)) { -- atomic_set(&bus->dpc_running, 1); -- atomic_set(&bus->dpc_tskcnt, 0); -+ bus->dpc_running = true; -+ wmb(); -+ while (ACCESS_ONCE(bus->dpc_triggered)) { -+ bus->dpc_triggered = false; - brcmf_sdio_dpc(bus); - bus->idlecount = 0; -- atomic_set(&bus->dpc_running, 0); - } -+ bus->dpc_running = false; - if (brcmf_sdiod_freezing(bus->sdiodev)) { - brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); - brcmf_sdiod_try_freeze(bus->sdiodev); -@@ -4144,8 +4153,8 @@ struct brcmf_sdio *brcmf_sdio_probe(stru - bus->watchdog_tsk = NULL; - } - /* Initialize DPC thread */ -- atomic_set(&bus->dpc_tskcnt, 0); -- atomic_set(&bus->dpc_running, 0); -+ bus->dpc_triggered = false; -+ bus->dpc_running = false; - - /* Assign bus interface call back */ - bus->sdiodev->bus_if->dev = bus->sdiodev->dev; diff --git a/package/kernel/mac80211/patches/347-brcmfmac-simplify-check-stripping-v2-NVRAM.patch b/package/kernel/mac80211/patches/347-brcmfmac-simplify-check-stripping-v2-NVRAM.patch new file mode 100644 index 0000000000..2bfd44f998 --- /dev/null +++ b/package/kernel/mac80211/patches/347-brcmfmac-simplify-check-stripping-v2-NVRAM.patch @@ -0,0 +1,56 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 May 2015 09:34:21 +0200 +Subject: [PATCH] brcmfmac: simplify check stripping v2 NVRAM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Comparing NVRAM entry with a full filtering string is simpler than +comparing it with a short prefix and then checking random chars at magic +offsets. The cost of snprintf relatively low, we execute it just once. +Tested on BCM43602 with NVRAM hacked to use V2 format. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -25,7 +25,7 @@ + + #define BRCMF_FW_MAX_NVRAM_SIZE 64000 + #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ +-#define BRCMF_FW_NVRAM_PCIEDEV_LEN 9 /* pcie/1/4/ */ ++#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */ + + char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; + module_param_string(firmware_path, brcmf_firmware_path, +@@ -297,6 +297,8 @@ fail: + static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, + u16 bus_nr) + { ++ char prefix[BRCMF_FW_NVRAM_PCIEDEV_LEN]; ++ size_t len; + u32 i, j; + u8 *nvram; + +@@ -308,14 +310,13 @@ static void brcmf_fw_strip_multi_v2(stru + * Valid entries are of type pcie/X/Y/ where X = domain_nr and + * Y = bus_nr. + */ ++ snprintf(prefix, sizeof(prefix), "pcie/%d/%d/", domain_nr, bus_nr); ++ len = strlen(prefix); + i = 0; + j = 0; +- while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) { +- if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) && +- (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') && +- ((nvp->nvram[i + 5] - '0') == domain_nr) && +- ((nvp->nvram[i + 7] - '0') == bus_nr)) { +- i += BRCMF_FW_NVRAM_PCIEDEV_LEN; ++ while (i < nvp->nvram_len - len) { ++ if (strncmp(&nvp->nvram[i], prefix, len) == 0) { ++ i += len; + while (nvp->nvram[i] != 0) { + nvram[j] = nvp->nvram[i]; + i++; diff --git a/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch b/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch deleted file mode 100644 index 1bc98a053e..0000000000 --- a/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Hante Meuleman -Date: Wed, 18 Mar 2015 13:25:24 +0100 -Subject: [PATCH] brcmfmac: Remove unnecessary new-line in pcie console - logging. - -Reviewed-by: Arend Van Spriel -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/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -651,10 +651,9 @@ static void brcmf_pcie_bus_console_read( - console->log_str[console->log_idx] = ch; - console->log_idx++; - } -- - if (ch == '\n') { - console->log_str[console->log_idx] = 0; -- brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str); -+ brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str); - console->log_idx = 0; - } - } diff --git a/package/kernel/mac80211/patches/348-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch b/package/kernel/mac80211/patches/348-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch new file mode 100644 index 0000000000..0e65114f86 --- /dev/null +++ b/package/kernel/mac80211/patches/348-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch @@ -0,0 +1,57 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 May 2015 11:01:08 +0200 +Subject: [PATCH] brcmfmac: simplify check finding NVRAM v1 device path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With a simple use of snprintf and small buffer we can compare NVRAM +entry value with a full string. This way we avoid checking random chars +at magic offsets. +Tested on BCM43602 with NVRAM hacked to use v1 format. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -222,6 +222,10 @@ static int brcmf_init_nvram_parser(struc + static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, + u16 bus_nr) + { ++ /* Device path with a leading '=' key-value separator */ ++ char pcie_path[] = "=pcie/?/?"; ++ size_t pcie_len; ++ + u32 i, j; + bool found; + u8 *nvram; +@@ -238,6 +242,9 @@ static void brcmf_fw_strip_multi_v1(stru + /* First search for the devpathX and see if it is the configuration + * for domain_nr/bus_nr. Search complete nvp + */ ++ snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, ++ bus_nr); ++ pcie_len = strlen(pcie_path); + found = false; + i = 0; + while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) { +@@ -245,13 +252,10 @@ static void brcmf_fw_strip_multi_v1(stru + * Y = domain_nr, Z = bus_nr, X = virtual ID + */ + if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && +- (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) { +- if (((nvp->nvram[i + 14] - '0') == domain_nr) && +- ((nvp->nvram[i + 16] - '0') == bus_nr)) { +- id = nvp->nvram[i + 7] - '0'; +- found = true; +- break; +- } ++ (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { ++ id = nvp->nvram[i + 7] - '0'; ++ found = true; ++ break; + } + while (nvp->nvram[i] != 0) + i++; diff --git a/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch b/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch deleted file mode 100644 index fcf0bf34f0..0000000000 --- a/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Arend van Spriel -Date: Wed, 18 Mar 2015 13:25:25 +0100 -Subject: [PATCH] brcmfmac: add MODULE_FIRMWARE() macros for bcm4356 PCIe - device - -The BCM4356 PCIe wireless device was added recently but overlooked -the fact that the MODULE_FIRMWARE() macros were missing for the -firmwares needed by this device. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -189,6 +189,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME - MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); -+MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME); -+MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); - diff --git a/package/kernel/mac80211/patches/349-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch b/package/kernel/mac80211/patches/349-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch new file mode 100644 index 0000000000..dc174e5a3d --- /dev/null +++ b/package/kernel/mac80211/patches/349-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch @@ -0,0 +1,45 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 May 2015 13:59:54 +0200 +Subject: [PATCH] brcmfmac: treat \0 as end of comment when parsing NVRAM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes brcmfmac dealing with NVRAM coming from platform e.g. from a +flash MTD partition. In such cases entries are separated by \0 instead +of \n which caused ignoring whole content after the first "comment". +While platform NVRAM doesn't usually contain comments, we switch to +COMMENT state after e.g. finding an unexpected char in key name. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -162,17 +162,20 @@ brcmf_nvram_handle_value(struct nvram_pa + static enum nvram_parser_state + brcmf_nvram_handle_comment(struct nvram_parser *nvp) + { +- char *eol, *sol; ++ char *eoc, *sol; + + sol = (char *)&nvp->fwnv->data[nvp->pos]; +- eol = strchr(sol, '\n'); +- if (eol == NULL) +- return END; ++ eoc = strchr(sol, '\n'); ++ if (!eoc) { ++ eoc = strchr(sol, '\0'); ++ if (!eoc) ++ return END; ++ } + + /* eat all moving to next line */ + nvp->line++; + nvp->column = 1; +- nvp->pos += (eol - sol) + 1; ++ nvp->pos += (eoc - sol) + 1; + return IDLE; + } + diff --git a/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch b/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch deleted file mode 100644 index b3e9bc9a07..0000000000 --- a/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Arend van Spriel -Date: Wed, 18 Mar 2015 13:25:26 +0100 -Subject: [PATCH] brcmfmac: add support for BCM43430 SDIO chipset - -This patch added support for the BCM43430 802.11n SDIO chipset. - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -1098,6 +1098,7 @@ static const struct sdio_device_id brcmf - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), -+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), - BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), - { /* end: all zeroes */ } ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -600,6 +600,12 @@ static void brcmf_chip_socram_ramsize(st - if (sr->chip->pub.chiprev < 2) - *srsize = (32 * 1024); - break; -+ case BRCM_CC_43430_CHIP_ID: -+ /* assume sr for now as we can not check -+ * firmware sr capability at this point. -+ */ -+ *srsize = (64 * 1024); -+ break; - default: - break; - } -@@ -1072,6 +1078,7 @@ static void - brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip) - { - struct brcmf_core *core; -+ struct brcmf_core_priv *sr; - - brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3); - core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211); -@@ -1081,6 +1088,13 @@ brcmf_chip_cm3_set_passive(struct brcmf_ - D11_BCMA_IOCTL_PHYCLOCKEN); - core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM); - brcmf_chip_resetcore(core, 0, 0, 0); -+ -+ /* disable bank #3 remap for this device */ -+ if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) { -+ sr = container_of(core, struct brcmf_core_priv, pub); -+ brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3); -+ brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0); -+ } - } - - static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip) -@@ -1188,6 +1202,10 @@ bool brcmf_chip_sr_capable(struct brcmf_ - addr = CORE_CC_REG(base, chipcontrol_data); - reg = chip->ops->read32(chip->ctx, addr); - return (reg & pmu_cc3_mask) != 0; -+ case BRCM_CC_43430_CHIP_ID: -+ addr = CORE_CC_REG(base, sr_control1); -+ reg = chip->ops->read32(chip->ctx, addr); -+ return reg != 0; - default: - addr = CORE_CC_REG(base, pmucapabilities_ext); - reg = chip->ops->read32(chip->ctx, addr); ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -615,6 +615,8 @@ static const struct sdiod_drive_str sdio - #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" - #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" - #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" -+#define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin" -+#define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt" - #define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" - #define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" - #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" -@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM43362_NVRAM_NAME); - MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4339_NVRAM_NAME); -+MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME); -+MODULE_FIRMWARE(BCM43430_NVRAM_NAME); - MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4345_NVRAM_NAME); - MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); -@@ -671,6 +675,7 @@ static const struct brcmf_firmware_names - { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, - { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, -+ { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) }, - { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, - { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } - }; ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -37,6 +37,7 @@ - #define BRCM_CC_43362_CHIP_ID 43362 - #define BRCM_CC_4335_CHIP_ID 0x4335 - #define BRCM_CC_4339_CHIP_ID 0x4339 -+#define BRCM_CC_43430_CHIP_ID 43430 - #define BRCM_CC_4345_CHIP_ID 0x4345 - #define BRCM_CC_4354_CHIP_ID 0x4354 - #define BRCM_CC_4356_CHIP_ID 0x4356 ---- a/drivers/net/wireless/brcm80211/include/chipcommon.h -+++ b/drivers/net/wireless/brcm80211/include/chipcommon.h -@@ -183,7 +183,14 @@ struct chipcregs { - u8 uart1lsr; - u8 uart1msr; - u8 uart1scratch; -- u32 PAD[126]; -+ u32 PAD[62]; -+ -+ /* save/restore, corerev >= 48 */ -+ u32 sr_capability; /* 0x500 */ -+ u32 sr_control0; /* 0x504 */ -+ u32 sr_control1; /* 0x508 */ -+ u32 gpio_control; /* 0x50C */ -+ u32 PAD[60]; - - /* PMU registers (corerev >= 20) */ - u32 pmucontrol; /* 0x600 */ ---- a/include/linux/mmc/sdio_ids.h -+++ b/include/linux/mmc/sdio_ids.h -@@ -33,6 +33,7 @@ - #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d - #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 - #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 -+#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 - #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 - #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 - diff --git a/package/kernel/mac80211/patches/350-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch b/package/kernel/mac80211/patches/350-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch new file mode 100644 index 0000000000..5700142646 --- /dev/null +++ b/package/kernel/mac80211/patches/350-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch @@ -0,0 +1,50 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 23 May 2015 09:15:33 +0200 +Subject: [PATCH] brcmfmac: allow NVRAM values to contain spaces +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Platform NVRAMs often contain values with spaces. Even if right now most +firmware-supported entries are simple values, we shouldn't reject these +with spaces. It was semi-confirmed by Broadcom in the early patch adding +support for platform NVRAMs. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -66,6 +66,12 @@ struct nvram_parser { + bool multi_dev_v2; + }; + ++/** ++ * is_nvram_char() - check if char is a valid one for NVRAM entry ++ * ++ * It accepts all printable ASCII chars except for '#' which opens a comment. ++ * Please note that ' ' (space) while accepted is not a valid key name char. ++ */ + static bool is_nvram_char(char c) + { + /* comment marker excluded */ +@@ -73,7 +79,7 @@ static bool is_nvram_char(char c) + return false; + + /* key and value may have any other readable character */ +- return (c > 0x20 && c < 0x7f); ++ return (c >= 0x20 && c < 0x7f); + } + + static bool is_whitespace(char c) +@@ -120,7 +126,7 @@ static enum nvram_parser_state brcmf_nvr + nvp->multi_dev_v1 = true; + if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) + nvp->multi_dev_v2 = true; +- } else if (!is_nvram_char(c)) { ++ } else if (!is_nvram_char(c) || c == ' ') { + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", + nvp->line, nvp->column); + return COMMENT; diff --git a/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch b/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch deleted file mode 100644 index c3d7bc2cbf..0000000000 --- a/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Arend van Spriel -Date: Wed, 18 Mar 2015 13:25:27 +0100 -Subject: [PATCH] brcmfmac: only support the BCM43455/7 device - -Recently support was added for the BCM4345 SDIO chipset by -commit 9c51026509d7 ("brcmfmac: Add support for BCM4345 SDIO chipset") -however this was verified using a BCM43455 device, which is -a more recent revision of the chip. This patch assure that -older revisions are not probed as they would fail. - -Reviewed-by: Hante Meuleman -Reviewed-by: Syed Asifful Dayyan -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -617,8 +617,8 @@ static const struct sdiod_drive_str sdio - #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" - #define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin" - #define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt" --#define BCM4345_FIRMWARE_NAME "brcm/brcmfmac4345-sdio.bin" --#define BCM4345_NVRAM_NAME "brcm/brcmfmac4345-sdio.txt" -+#define BCM43455_FIRMWARE_NAME "brcm/brcmfmac43455-sdio.bin" -+#define BCM43455_NVRAM_NAME "brcm/brcmfmac43455-sdio.txt" - #define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" - #define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt" - -@@ -644,8 +644,8 @@ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4339_NVRAM_NAME); - MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM43430_NVRAM_NAME); --MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME); --MODULE_FIRMWARE(BCM4345_NVRAM_NAME); -+MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME); -+MODULE_FIRMWARE(BCM43455_NVRAM_NAME); - MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4354_NVRAM_NAME); - -@@ -676,7 +676,7 @@ static const struct brcmf_firmware_names - { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, - { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) }, -- { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) }, -+ { BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) }, - { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } - }; - diff --git a/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch b/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch deleted file mode 100644 index a62cfdfc4c..0000000000 --- a/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Arend van Spriel -Date: Wed, 18 Mar 2015 13:25:28 +0100 -Subject: [PATCH] brcmfmac: remove support for unreleased BCM4354 PCIe - -There are no known BCM4354 PCIe devices released so removing -support from the driver until proven otherwise. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -47,8 +47,6 @@ enum brcmf_pcie_state { - - #define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin" - #define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt" --#define BRCMF_PCIE_4354_FW_NAME "brcm/brcmfmac4354-pcie.bin" --#define BRCMF_PCIE_4354_NVRAM_NAME "brcm/brcmfmac4354-pcie.txt" - #define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin" - #define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" - #define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" -@@ -187,8 +185,6 @@ enum brcmf_pcie_state { - - MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); --MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); --MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); -@@ -1327,10 +1323,6 @@ static int brcmf_pcie_get_fwnames(struct - fw_name = BRCMF_PCIE_43602_FW_NAME; - nvram_name = BRCMF_PCIE_43602_NVRAM_NAME; - break; -- case BRCM_CC_4354_CHIP_ID: -- fw_name = BRCMF_PCIE_4354_FW_NAME; -- nvram_name = BRCMF_PCIE_4354_NVRAM_NAME; -- break; - case BRCM_CC_4356_CHIP_ID: - fw_name = BRCMF_PCIE_4356_FW_NAME; - nvram_name = BRCMF_PCIE_4356_NVRAM_NAME; -@@ -1855,7 +1847,6 @@ cleanup: - PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } - - static struct pci_device_id brcmf_pcie_devid_table[] = { -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), diff --git a/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch b/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch deleted file mode 100644 index 366ff85d03..0000000000 --- a/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Arend van Spriel -Date: Fri, 20 Mar 2015 22:18:17 +0100 -Subject: [PATCH] brcmfmac: disable MBSS feature for BCM43362 - -The BCM43362 firmware falsely reports it is capable of providing -MBSS. As a result AP mode no longer works for this device. Therefor -disable MBSS in the driver for this chipset. - -Cc: stable@vger.kernel.org # 3.19.y -Reported-by: Jorg Krause -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c -@@ -126,7 +126,8 @@ void brcmf_feat_attach(struct brcmf_pub - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); - if (drvr->bus_if->wowl_supported) - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); -- brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); -+ if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) -+ brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); - - /* set chip related quirks */ - switch (drvr->bus_if->chip) { diff --git a/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch b/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch deleted file mode 100644 index 6e461f617f..0000000000 --- a/package/kernel/mac80211/patches/354-brcmfmac-use-static-superset-of-channels-for-wiphy-b.patch +++ /dev/null @@ -1,300 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:24 +0200 -Subject: [PATCH] brcmfmac: use static superset of channels for wiphy - bands - -The driver was constructing a list of channels per wiphy band -by querying the device. This list is not what the hardware is -able to do as it is already filtered by the country setting in -the device. As user-space may change the country this would -require updating the channel list which is not recommended [1]. -This patch introduces a superset of channels. The individual -channels are disabled appropriately by querying the device. - -[1] http://mid.gmane.org/1426706320.3001.21.camel@sipsolutions.net - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -129,13 +129,47 @@ static struct ieee80211_rate __wl_rates[ - RATETAB_ENT(BRCM_RATE_54M, 0), - }; - --#define wl_a_rates (__wl_rates + 4) --#define wl_a_rates_size 8 - #define wl_g_rates (__wl_rates + 0) --#define wl_g_rates_size 12 -+#define wl_g_rates_size ARRAY_SIZE(__wl_rates) -+#define wl_a_rates (__wl_rates + 4) -+#define wl_a_rates_size (wl_g_rates_size - 4) -+ -+#define CHAN2G(_channel, _freq) { \ -+ .band = IEEE80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_channel), \ -+ .flags = IEEE80211_CHAN_DISABLED, \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+#define CHAN5G(_channel) { \ -+ .band = IEEE80211_BAND_5GHZ, \ -+ .center_freq = 5000 + (5 * (_channel)), \ -+ .hw_value = (_channel), \ -+ .flags = IEEE80211_CHAN_DISABLED, \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel __wl_2ghz_channels[] = { -+ CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427), -+ CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447), -+ CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467), -+ CHAN2G(13, 2472), CHAN2G(14, 2484) -+}; -+ -+static struct ieee80211_channel __wl_5ghz_channels[] = { -+ CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42), -+ CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56), -+ CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108), -+ CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128), -+ CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149), -+ CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165) -+}; - - /* Band templates duplicated per wiphy. The channel info -- * is filled in after querying the device. -+ * above is added to the band during setup. - */ - static const struct ieee80211_supported_band __wl_band_2ghz = { - .band = IEEE80211_BAND_2GHZ, -@@ -143,7 +177,7 @@ static const struct ieee80211_supported_ - .n_bitrates = wl_g_rates_size, - }; - --static const struct ieee80211_supported_band __wl_band_5ghz_a = { -+static const struct ieee80211_supported_band __wl_band_5ghz = { - .band = IEEE80211_BAND_5GHZ, - .bitrates = wl_a_rates, - .n_bitrates = wl_a_rates_size, -@@ -5252,40 +5286,6 @@ dongle_scantime_out: - return err; - } - --/* Filter the list of channels received from firmware counting only -- * the 20MHz channels. The wiphy band data only needs those which get -- * flagged to indicate if they can take part in higher bandwidth. -- */ --static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg, -- struct brcmf_chanspec_list *chlist, -- u32 chcnt[]) --{ -- u32 total = le32_to_cpu(chlist->count); -- struct brcmu_chan ch; -- int i; -- -- for (i = 0; i < total; i++) { -- ch.chspec = (u16)le32_to_cpu(chlist->element[i]); -- cfg->d11inf.decchspec(&ch); -- -- /* Firmware gives a ordered list. We skip non-20MHz -- * channels is 2G. For 5G we can abort upon reaching -- * a non-20MHz channel in the list. -- */ -- if (ch.bw != BRCMU_CHAN_BW_20) { -- if (ch.band == BRCMU_CHAN_BAND_5G) -- break; -- else -- continue; -- } -- -- if (ch.band == BRCMU_CHAN_BAND_2G) -- chcnt[0] += 1; -- else if (ch.band == BRCMU_CHAN_BAND_5G) -- chcnt[1] += 1; -- } --} -- - static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel, - struct brcmu_chan *ch) - { -@@ -5321,7 +5321,6 @@ static int brcmf_construct_chaninfo(stru - u32 i, j; - u32 total; - u32 chaninfo; -- u32 chcnt[2] = { 0, 0 }; - u32 index; - - pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); -@@ -5338,42 +5337,15 @@ static int brcmf_construct_chaninfo(stru - goto fail_pbuf; - } - -- brcmf_count_20mhz_channels(cfg, list, chcnt); - wiphy = cfg_to_wiphy(cfg); -- if (chcnt[0]) { -- band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz), -- GFP_KERNEL); -- if (band == NULL) { -- err = -ENOMEM; -- goto fail_pbuf; -- } -- band->channels = kcalloc(chcnt[0], sizeof(*channel), -- GFP_KERNEL); -- if (band->channels == NULL) { -- kfree(band); -- err = -ENOMEM; -- goto fail_pbuf; -- } -- band->n_channels = 0; -- wiphy->bands[IEEE80211_BAND_2GHZ] = band; -- } -- if (chcnt[1]) { -- band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a), -- GFP_KERNEL); -- if (band == NULL) { -- err = -ENOMEM; -- goto fail_band2g; -- } -- band->channels = kcalloc(chcnt[1], sizeof(*channel), -- GFP_KERNEL); -- if (band->channels == NULL) { -- kfree(band); -- err = -ENOMEM; -- goto fail_band2g; -- } -- band->n_channels = 0; -- wiphy->bands[IEEE80211_BAND_5GHZ] = band; -- } -+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; -+ if (band) -+ for (i = 0; i < band->n_channels; i++) -+ band->channels[i].flags = IEEE80211_CHAN_DISABLED; -+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; -+ if (band) -+ for (i = 0; i < band->n_channels; i++) -+ band->channels[i].flags = IEEE80211_CHAN_DISABLED; - - total = le32_to_cpu(list->count); - for (i = 0; i < total; i++) { -@@ -5388,6 +5360,8 @@ static int brcmf_construct_chaninfo(stru - brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); - continue; - } -+ if (!band) -+ continue; - if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) && - ch.bw == BRCMU_CHAN_BW_40) - continue; -@@ -5415,9 +5389,9 @@ static int brcmf_construct_chaninfo(stru - } else if (ch.bw == BRCMU_CHAN_BW_40) { - brcmf_update_bw40_channel_flag(&channel[index], &ch); - } else { -- /* disable other bandwidths for now as mentioned -- * order assure they are enabled for subsequent -- * chanspecs. -+ /* enable the channel and disable other bandwidths -+ * for now as mentioned order assure they are enabled -+ * for subsequent chanspecs. - */ - channel[index].flags = IEEE80211_CHAN_NO_HT40 | - IEEE80211_CHAN_NO_80MHZ; -@@ -5436,16 +5410,8 @@ static int brcmf_construct_chaninfo(stru - IEEE80211_CHAN_NO_IR; - } - } -- if (index == band->n_channels) -- band->n_channels++; - } -- kfree(pbuf); -- return 0; - --fail_band2g: -- kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); -- kfree(wiphy->bands[IEEE80211_BAND_2GHZ]); -- wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; - fail_pbuf: - kfree(pbuf); - return err; -@@ -5778,7 +5744,12 @@ static void brcmf_wiphy_wowl_params(stru - - static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) - { -+ struct ieee80211_supported_band *band; - struct ieee80211_iface_combination ifc_combo; -+ __le32 bandlist[3]; -+ u32 n_bands; -+ int err, i; -+ - wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; - wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; -@@ -5820,7 +5791,52 @@ static int brcmf_setup_wiphy(struct wiph - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) - brcmf_wiphy_wowl_params(wiphy); - -- return brcmf_setup_wiphybands(wiphy); -+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist, -+ sizeof(bandlist)); -+ if (err) { -+ brcmf_err("could not obtain band info: err=%d\n", err); -+ return err; -+ } -+ /* first entry in bandlist is number of bands */ -+ n_bands = le32_to_cpu(bandlist[0]); -+ for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) { -+ if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) { -+ band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz), -+ GFP_KERNEL); -+ if (!band) -+ return -ENOMEM; -+ -+ band->channels = kmemdup(&__wl_2ghz_channels, -+ sizeof(__wl_2ghz_channels), -+ GFP_KERNEL); -+ if (!band->channels) { -+ kfree(band); -+ return -ENOMEM; -+ } -+ -+ band->n_channels = ARRAY_SIZE(__wl_2ghz_channels); -+ wiphy->bands[IEEE80211_BAND_2GHZ] = band; -+ } -+ if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) { -+ band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz), -+ GFP_KERNEL); -+ if (!band) -+ return -ENOMEM; -+ -+ band->channels = kmemdup(&__wl_5ghz_channels, -+ sizeof(__wl_5ghz_channels), -+ GFP_KERNEL); -+ if (!band->channels) { -+ kfree(band); -+ return -ENOMEM; -+ } -+ -+ band->n_channels = ARRAY_SIZE(__wl_5ghz_channels); -+ wiphy->bands[IEEE80211_BAND_5GHZ] = band; -+ } -+ } -+ err = brcmf_setup_wiphybands(wiphy); -+ return err; - } - - static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) -@@ -6011,6 +6027,9 @@ static void brcmf_cfg80211_reg_notifier( - - static void brcmf_free_wiphy(struct wiphy *wiphy) - { -+ if (!wiphy) -+ return; -+ - kfree(wiphy->iface_combinations); - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch b/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch deleted file mode 100644 index a0c22eb411..0000000000 --- a/package/kernel/mac80211/patches/355-brcmfmac-update-wiphy-band-information-upon-updating.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:25 +0200 -Subject: [PATCH] brcmfmac: update wiphy band information upon updating - regulatory domain - -When change the country code the available channels may change. So -the wiphy bands should be updated accordingly. - -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -6022,7 +6022,11 @@ static void brcmf_cfg80211_reg_notifier( - memset(&ccreq, 0, sizeof(ccreq)); - ccreq.rev = cpu_to_le32(-1); - memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2)); -- brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); -+ if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) { -+ brcmf_err("firmware rejected country setting\n"); -+ return; -+ } -+ brcmf_setup_wiphybands(wiphy); - } - - static void brcmf_free_wiphy(struct wiphy *wiphy) diff --git a/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch b/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch deleted file mode 100644 index 193f507d0d..0000000000 --- a/package/kernel/mac80211/patches/356-brcmfmac-add-description-for-feature-flags.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:26 +0200 -Subject: [PATCH] brcmfmac: add description for feature flags - -Some feature flags were not described in the header file. Adding -the description. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h -@@ -19,7 +19,9 @@ - /* - * Features: - * -+ * MBSS: multiple BSSID support (eg. guest network in AP mode). - * MCHAN: multi-channel for concurrent P2P. -+ * WOWL: Wake-On-WLAN. - */ - #define BRCMF_FEAT_LIST \ - BRCMF_FEAT_DEF(MBSS) \ diff --git a/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch b/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch deleted file mode 100644 index 42330b474e..0000000000 --- a/package/kernel/mac80211/patches/357-brcmfmac-make-scheduled-scan-support-conditional.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:27 +0200 -Subject: [PATCH] brcmfmac: make scheduled scan support conditional - -The scheduled scan support depends on firmware supporting the PNO -feature. This feature is optional so add a feature flag for this -in the driver and announce scheduled scan support accordingly. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -5782,7 +5782,8 @@ static int brcmf_setup_wiphy(struct wiph - wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; - wiphy->mgmt_stypes = brcmf_txrx_stypes; - wiphy->max_remain_on_channel_duration = 5000; -- brcmf_wiphy_pno_params(wiphy); -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) -+ brcmf_wiphy_pno_params(wiphy); - - /* vendor commands/events support */ - wiphy->vendor_commands = brcmf_vendor_cmds; ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c -@@ -124,6 +124,7 @@ void brcmf_feat_attach(struct brcmf_pub - struct brcmf_if *ifp = drvr->iflist[0]; - - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); -+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); - if (drvr->bus_if->wowl_supported) - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); - if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h -@@ -21,11 +21,13 @@ - * - * MBSS: multiple BSSID support (eg. guest network in AP mode). - * MCHAN: multi-channel for concurrent P2P. -+ * PNO: preferred network offload. - * WOWL: Wake-On-WLAN. - */ - #define BRCMF_FEAT_LIST \ - BRCMF_FEAT_DEF(MBSS) \ - BRCMF_FEAT_DEF(MCHAN) \ -+ BRCMF_FEAT_DEF(PNO) \ - BRCMF_FEAT_DEF(WOWL) - /* - * Quirks: diff --git a/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch b/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch deleted file mode 100644 index b859d46894..0000000000 --- a/package/kernel/mac80211/patches/358-brcmfmac-add-support-for-BCM4324-rev-B5-chipset.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:28 +0200 -Subject: [PATCH] brcmfmac: add support for BCM4324 rev B5 chipset - -This patch adds support for the BCM4324 B5 revision. This device -is similar to BCM43241 from driver and firmware perspective. It -is known to be used in Lenovo Thinkpad Tablet devices. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -601,6 +601,8 @@ static const struct sdiod_drive_str sdio - #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 +630,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 +671,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) }, diff --git a/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch b/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch deleted file mode 100644 index d420308383..0000000000 --- a/package/kernel/mac80211/patches/359-brcmfmac-process-interrupt-regardless-sdiod-state.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:29 +0200 -Subject: [PATCH] brcmfmac: process interrupt regardless sdiod state - -When the sdio bus state is not ready to process we abort the -interrupt service routine. This is not wanted as it keeps the -interrupt source active. Better clear the interrupt source. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky (Zhenhui) Lin -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -3555,10 +3555,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *b - 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()) diff --git a/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch b/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch deleted file mode 100644 index ac5584ec3c..0000000000 --- a/package/kernel/mac80211/patches/360-brcmfmac-fix-sdio-suspend-and-resume.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:30 +0200 -Subject: [PATCH] brcmfmac: fix sdio suspend and resume - -commit 330b4e4be937 ("brcmfmac: Add wowl support for SDIO devices.") -changed the behaviour by removing the MMC_PM_KEEP_POWER flag for -non-wowl scenario, which needs to be restored. Another necessary -change is to mark the card as being non-removable. With this in place -the suspend resume test passes successfully doing: - - # echo devices > /sys/power/pm_test - # echo mem > /sys/power/state - -Note that power may still be switched off when system is going -in S3 state. - -Reported-by: Fu, Zhonghui < -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky (Zhenhui) Lin -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -1011,6 +1011,14 @@ static int brcmf_sdiod_remove(struct brc - return 0; - } - -+static void brcmf_sdiod_host_fixup(struct mmc_host *host) -+{ -+ /* runtime-pm powers off the device */ -+ pm_runtime_forbid(host->parent); -+ /* avoid removal detection upon resume */ -+ host->caps |= MMC_CAP_NONREMOVABLE; -+} -+ - static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) - { - struct sdio_func *func; -@@ -1076,7 +1084,7 @@ static int brcmf_sdiod_probe(struct brcm - ret = -ENODEV; - goto out; - } -- pm_runtime_forbid(host->parent); -+ brcmf_sdiod_host_fixup(host); - out: - if (ret) - brcmf_sdiod_remove(sdiodev); -@@ -1246,15 +1254,15 @@ static int brcmf_ops_sdio_suspend(struct - brcmf_sdiod_freezer_on(sdiodev); - brcmf_sdio_wd_timer(sdiodev->bus, 0); - -+ sdio_flags = MMC_PM_KEEP_POWER; - if (sdiodev->wowl_enabled) { -- sdio_flags = MMC_PM_KEEP_POWER; - if (sdiodev->pdata->oob_irq_supported) - enable_irq_wake(sdiodev->pdata->oob_irq_nr); - else -- sdio_flags = MMC_PM_WAKE_SDIO_IRQ; -- if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) -- brcmf_err("Failed to set pm_flags %x\n", sdio_flags); -+ sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; - } -+ if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) -+ brcmf_err("Failed to set pm_flags %x\n", sdio_flags); - return 0; - } - diff --git a/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch b/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch deleted file mode 100644 index a521b65d0f..0000000000 --- a/package/kernel/mac80211/patches/361-brcmfmac-add-support-for-BCM4358-PCIe-device.patch +++ /dev/null @@ -1,77 +0,0 @@ -From: Arend van Spriel -Date: Tue, 14 Apr 2015 20:10:31 +0200 -Subject: [PATCH] brcmfmac: add support for BCM4358 PCIe device - -This patch adds support for the BCM4358 2x2 11ac device. - -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -649,6 +649,7 @@ static u32 brcmf_chip_tcm_rambase(struct - case BRCM_CC_43567_CHIP_ID: - case BRCM_CC_43569_CHIP_ID: - case BRCM_CC_43570_CHIP_ID: -+ case BRCM_CC_4358_CHIP_ID: - case BRCM_CC_43602_CHIP_ID: - return 0x180000; - default: ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -51,6 +51,8 @@ enum brcmf_pcie_state { - #define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" - #define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" - #define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt" -+#define BRCMF_PCIE_4358_FW_NAME "brcm/brcmfmac4358-pcie.bin" -+#define BRCMF_PCIE_4358_NVRAM_NAME "brcm/brcmfmac4358-pcie.txt" - - #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ - -@@ -189,6 +191,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME) - MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); - MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); -+MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME); -+MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME); - - - struct brcmf_pcie_console { -@@ -1333,6 +1337,10 @@ static int brcmf_pcie_get_fwnames(struct - fw_name = BRCMF_PCIE_43570_FW_NAME; - nvram_name = BRCMF_PCIE_43570_NVRAM_NAME; - break; -+ case BRCM_CC_4358_CHIP_ID: -+ fw_name = BRCMF_PCIE_4358_FW_NAME; -+ nvram_name = BRCMF_PCIE_4358_NVRAM_NAME; -+ break; - default: - brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip); - return -ENODEV; -@@ -1850,6 +1858,7 @@ static struct pci_device_id brcmf_pcie_d - BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4358_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID), ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -45,6 +45,7 @@ - #define BRCM_CC_43567_CHIP_ID 43567 - #define BRCM_CC_43569_CHIP_ID 43569 - #define BRCM_CC_43570_CHIP_ID 43570 -+#define BRCM_CC_4358_CHIP_ID 0x4358 - #define BRCM_CC_43602_CHIP_ID 43602 - - /* USB Device IDs */ -@@ -59,6 +60,7 @@ - #define BRCM_PCIE_4356_DEVICE_ID 0x43ec - #define BRCM_PCIE_43567_DEVICE_ID 0x43d3 - #define BRCM_PCIE_43570_DEVICE_ID 0x43d9 -+#define BRCM_PCIE_4358_DEVICE_ID 0x43e9 - #define BRCM_PCIE_43602_DEVICE_ID 0x43ba - #define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb - #define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc diff --git a/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch b/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch deleted file mode 100644 index bcbb984d42..0000000000 --- a/package/kernel/mac80211/patches/362-brcmfmac-add-additional-43602-pcie-device-id.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Hante Meuleman -Date: Tue, 14 Apr 2015 20:10:32 +0200 -Subject: [PATCH] brcmfmac: add additional 43602 pcie device id. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1862,6 +1862,7 @@ static struct pci_device_id brcmf_pcie_d - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID), - BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID), -+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID), - { /* end: all zeroes */ } - }; - ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -64,6 +64,7 @@ - #define BRCM_PCIE_43602_DEVICE_ID 0x43ba - #define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb - #define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc -+#define BRCM_PCIE_43602_RAW_DEVICE_ID 43602 - - /* brcmsmac IDs */ - #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ diff --git a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch b/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch deleted file mode 100644 index 5f9bbeaf5c..0000000000 --- a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch +++ /dev/null @@ -1,351 +0,0 @@ -From: Hante Meuleman -Date: Tue, 14 Apr 2015 20:10:33 +0200 -Subject: [PATCH] brcmfmac: Add support for multiple PCIE devices in - nvram. - -With PCIE it is possible to support multiple devices with the -same device type. They all load the same nvram file. In order to -support this the nvram can specify which part of the nvram is -for which pcie device. This patch adds support for these new -types of nvram files. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -23,6 +23,10 @@ - #include "debug.h" - #include "firmware.h" - -+#define BRCMF_FW_MAX_NVRAM_SIZE 64000 -+#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ -+#define BRCMF_FW_NVRAM_PCIEDEV_LEN 9 /* pcie/1/4/ */ -+ - char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; - module_param_string(firmware_path, brcmf_firmware_path, - BRCMF_FW_PATH_LEN, 0440); -@@ -46,6 +50,8 @@ enum nvram_parser_state { - * @column: current column in line. - * @pos: byte offset in input buffer. - * @entry: start position of key,value entry. -+ * @multi_dev_v1: detect pcie multi device v1 (compressed). -+ * @multi_dev_v2: detect pcie multi device v2. - */ - struct nvram_parser { - enum nvram_parser_state state; -@@ -56,6 +62,8 @@ struct nvram_parser { - u32 column; - u32 pos; - u32 entry; -+ bool multi_dev_v1; -+ bool multi_dev_v2; - }; - - static bool is_nvram_char(char c) -@@ -108,6 +116,10 @@ static enum nvram_parser_state brcmf_nvr - st = COMMENT; - else - st = VALUE; -+ if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) -+ nvp->multi_dev_v1 = true; -+ if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) -+ nvp->multi_dev_v2 = true; - } else if (!is_nvram_char(c)) { - brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", - nvp->line, nvp->column); -@@ -133,6 +145,8 @@ brcmf_nvram_handle_value(struct nvram_pa - ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; - skv = (u8 *)&nvp->fwnv->data[nvp->entry]; - cplen = ekv - skv; -+ if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) -+ return END; - /* copy to output buffer */ - memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen); - nvp->nvram_len += cplen; -@@ -180,10 +194,18 @@ static enum nvram_parser_state - static int brcmf_init_nvram_parser(struct nvram_parser *nvp, - const struct firmware *nv) - { -+ size_t size; -+ - memset(nvp, 0, sizeof(*nvp)); - nvp->fwnv = nv; -+ /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ -+ if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) -+ size = BRCMF_FW_MAX_NVRAM_SIZE; -+ else -+ size = nv->size; - /* Alloc for extra 0 byte + roundup by 4 + length field */ -- nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ size += 1 + 3 + sizeof(u32); -+ nvp->nvram = kzalloc(size, GFP_KERNEL); - if (!nvp->nvram) - return -ENOMEM; - -@@ -192,12 +214,136 @@ static int brcmf_init_nvram_parser(struc - return 0; - } - -+/* brcmf_fw_strip_multi_v1 :Some nvram files contain settings for multiple -+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine -+ * which data is to be returned. v1 is the version where nvram is stored -+ * compressed and "devpath" maps to index for valid entries. -+ */ -+static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, -+ u16 bus_nr) -+{ -+ u32 i, j; -+ bool found; -+ u8 *nvram; -+ u8 id; -+ -+ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ if (!nvram) -+ goto fail; -+ -+ /* min length: devpath0=pcie/1/4/ + 0:x=y */ -+ if (nvp->nvram_len < BRCMF_FW_NVRAM_DEVPATH_LEN + 6) -+ goto fail; -+ -+ /* First search for the devpathX and see if it is the configuration -+ * for domain_nr/bus_nr. Search complete nvp -+ */ -+ found = false; -+ i = 0; -+ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) { -+ /* Format: devpathX=pcie/Y/Z/ -+ * Y = domain_nr, Z = bus_nr, X = virtual ID -+ */ -+ if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && -+ (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) { -+ if (((nvp->nvram[i + 14] - '0') == domain_nr) && -+ ((nvp->nvram[i + 16] - '0') == bus_nr)) { -+ id = nvp->nvram[i + 7] - '0'; -+ found = true; -+ break; -+ } -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ if (!found) -+ goto fail; -+ -+ /* Now copy all valid entries, release old nvram and assign new one */ -+ i = 0; -+ j = 0; -+ while (i < nvp->nvram_len) { -+ if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { -+ i += 2; -+ while (nvp->nvram[i] != 0) { -+ nvram[j] = nvp->nvram[i]; -+ i++; -+ j++; -+ } -+ nvram[j] = 0; -+ j++; -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ kfree(nvp->nvram); -+ nvp->nvram = nvram; -+ nvp->nvram_len = j; -+ return; -+ -+fail: -+ kfree(nvram); -+ nvp->nvram_len = 0; -+} -+ -+/* brcmf_fw_strip_multi_v2 :Some nvram files contain settings for multiple -+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine -+ * which data is to be returned. v2 is the version where nvram is stored -+ * uncompressed, all relevant valid entries are identified by -+ * pcie/domain_nr/bus_nr: -+ */ -+static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, -+ u16 bus_nr) -+{ -+ u32 i, j; -+ u8 *nvram; -+ -+ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ if (!nvram) -+ goto fail; -+ -+ /* Copy all valid entries, release old nvram and assign new one. -+ * Valid entries are of type pcie/X/Y/ where X = domain_nr and -+ * Y = bus_nr. -+ */ -+ i = 0; -+ j = 0; -+ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) { -+ if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) && -+ (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') && -+ ((nvp->nvram[i + 5] - '0') == domain_nr) && -+ ((nvp->nvram[i + 7] - '0') == bus_nr)) { -+ i += BRCMF_FW_NVRAM_PCIEDEV_LEN; -+ while (nvp->nvram[i] != 0) { -+ nvram[j] = nvp->nvram[i]; -+ i++; -+ j++; -+ } -+ nvram[j] = 0; -+ j++; -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ kfree(nvp->nvram); -+ nvp->nvram = nvram; -+ nvp->nvram_len = j; -+ return; -+fail: -+ kfree(nvram); -+ nvp->nvram_len = 0; -+} -+ - /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil - * and ending in a NUL. Removes carriage returns, empty lines, comment lines, - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. - * End of buffer is completed with token identifying length of buffer. - */ --static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length) -+static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, -+ u16 domain_nr, u16 bus_nr) - { - struct nvram_parser nvp; - u32 pad; -@@ -212,6 +358,16 @@ static void *brcmf_fw_nvram_strip(const - if (nvp.state == END) - break; - } -+ if (nvp.multi_dev_v1) -+ brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); -+ else if (nvp.multi_dev_v2) -+ brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); -+ -+ if (nvp.nvram_len == 0) { -+ kfree(nvp.nvram); -+ return NULL; -+ } -+ - pad = nvp.nvram_len; - *new_length = roundup(nvp.nvram_len + 1, 4); - while (pad != *new_length) { -@@ -239,6 +395,8 @@ struct brcmf_fw { - u16 flags; - const struct firmware *code; - const char *nvram_name; -+ u16 domain_nr; -+ u16 bus_nr; - void (*done)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len); - }; -@@ -254,7 +412,8 @@ static void brcmf_fw_request_nvram_done( - goto fail; - - if (fw) { -- nvram = brcmf_fw_nvram_strip(fw, &nvram_length); -+ nvram = brcmf_fw_nvram_strip(fw, &nvram_length, -+ fwctx->domain_nr, fwctx->bus_nr); - release_firmware(fw); - if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) - goto fail; -@@ -309,11 +468,12 @@ fail: - kfree(fwctx); - } - --int brcmf_fw_get_firmwares(struct device *dev, u16 flags, -- const char *code, const char *nvram, -- void (*fw_cb)(struct device *dev, -- const struct firmware *fw, -- void *nvram_image, u32 nvram_len)) -+int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, -+ const char *code, const char *nvram, -+ void (*fw_cb)(struct device *dev, -+ const struct firmware *fw, -+ void *nvram_image, u32 nvram_len), -+ u16 domain_nr, u16 bus_nr) - { - struct brcmf_fw *fwctx; - -@@ -333,8 +493,21 @@ int brcmf_fw_get_firmwares(struct device - fwctx->done = fw_cb; - if (flags & BRCMF_FW_REQUEST_NVRAM) - fwctx->nvram_name = nvram; -+ fwctx->domain_nr = domain_nr; -+ fwctx->bus_nr = bus_nr; - - return request_firmware_nowait(THIS_MODULE, true, code, dev, - GFP_KERNEL, fwctx, - brcmf_fw_request_code_done); - } -+ -+int brcmf_fw_get_firmwares(struct device *dev, u16 flags, -+ const char *code, const char *nvram, -+ void (*fw_cb)(struct device *dev, -+ const struct firmware *fw, -+ void *nvram_image, u32 nvram_len)) -+{ -+ return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, -+ 0); -+} -+ ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h -@@ -32,6 +32,12 @@ void brcmf_fw_nvram_free(void *nvram); - * fails it will not use the callback, but call device_release_driver() - * instead which will call the driver .remove() callback. - */ -+int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, -+ const char *code, const char *nvram, -+ void (*fw_cb)(struct device *dev, -+ const struct firmware *fw, -+ void *nvram_image, u32 nvram_len), -+ u16 domain_nr, u16 bus_nr); - int brcmf_fw_get_firmwares(struct device *dev, u16 flags, - const char *code, const char *nvram, - void (*fw_cb)(struct device *dev, ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1649,8 +1649,13 @@ brcmf_pcie_probe(struct pci_dev *pdev, c - struct brcmf_pciedev_info *devinfo; - struct brcmf_pciedev *pcie_bus_dev; - struct brcmf_bus *bus; -+ u16 domain_nr; -+ u16 bus_nr; - -- brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); -+ domain_nr = pci_domain_nr(pdev->bus) + 1; -+ bus_nr = pdev->bus->number; -+ brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, -+ domain_nr, bus_nr); - - ret = -ENOMEM; - devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); -@@ -1699,10 +1704,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c - if (ret) - goto fail_bus; - -- ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM | -- BRCMF_FW_REQ_NV_OPTIONAL, -- devinfo->fw_name, devinfo->nvram_name, -- brcmf_pcie_setup); -+ ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | -+ BRCMF_FW_REQ_NV_OPTIONAL, -+ devinfo->fw_name, devinfo->nvram_name, -+ brcmf_pcie_setup, domain_nr, bus_nr); - if (ret == 0) - return 0; - fail_bus: diff --git a/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch b/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch deleted file mode 100644 index d26e118d77..0000000000 --- a/package/kernel/mac80211/patches/364-brcmfmac-cleanup-a-sizeof.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Dan Carpenter -Date: Thu, 7 May 2015 12:59:19 +0300 -Subject: [PATCH] brcmfmac: cleanup a sizeof() - -"flowrings" and "*flowrings" are both pointers so this always returns -sizeof(void *) and the current code works fine. But "*flowrings" is -intended here and static checkers complain, so lets change it. - -Signed-off-by: Dan Carpenter -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1617,7 +1617,7 @@ static void brcmf_pcie_setup(struct devi - bus->msgbuf->commonrings[i] = - &devinfo->shared.commonrings[i]->commonring; - -- flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings), -+ flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings), - GFP_KERNEL); - if (!flowrings) - goto fail; diff --git a/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch b/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch deleted file mode 100644 index 9b2880d8fc..0000000000 --- a/package/kernel/mac80211/patches/365-brcmfmac-check-result-of-USB-firmware-request.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 7 May 2015 14:13:03 +0200 -Subject: [PATCH] brcmfmac: check result of USB firmware request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This prevents silence failures with driver waiting (infinitely) for a -callback. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c -@@ -1270,8 +1270,13 @@ static int brcmf_usb_probe_cb(struct brc - bus->chiprev = bus_pub->chiprev; - - /* request firmware here */ -- brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, -- brcmf_usb_probe_phase2); -+ ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), -+ NULL, brcmf_usb_probe_phase2); -+ if (ret) { -+ brcmf_err("firmware request failed: %d\n", ret); -+ goto fail; -+ } -+ - return 0; - - fail: diff --git a/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch b/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch deleted file mode 100644 index d46b300daa..0000000000 --- a/package/kernel/mac80211/patches/366-brcmfmac-prohibit-ACPI-power-management-for-brcmfmac.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: "Fu, Zhonghui" -Date: Mon, 11 May 2015 10:41:32 +0800 -Subject: [PATCH] brcmfmac: prohibit ACPI power management for brcmfmac driver - -ACPI will manage WiFi chip's power state during suspend/resume -process on some tablet platforms(such as ASUS T100TA). This is -not supported by brcmfmac driver now, and the context of WiFi -chip will be damaged after resume. This patch informs ACPI not -to manage WiFi chip's power state. - -Signed-off-by: Zhonghui Fu -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -1122,6 +1123,8 @@ static int brcmf_ops_sdio_probe(struct s - int err; - struct brcmf_sdio_dev *sdiodev; - struct brcmf_bus *bus_if; -+ struct device *dev; -+ struct acpi_device *adev; - - brcmf_dbg(SDIO, "Enter\n"); - brcmf_dbg(SDIO, "Class=%x\n", func->class); -@@ -1129,6 +1132,12 @@ static int brcmf_ops_sdio_probe(struct s - brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(SDIO, "Function#: %d\n", func->num); - -+ /* prohibit ACPI power management for this device */ -+ dev = &func->dev; -+ adev = ACPI_COMPANION(dev); -+ if (adev) -+ adev->flags.power_manageable = 0; -+ - /* Consume func num 1 but dont do anything with it. */ - if (func->num == 1) - return 0; diff --git a/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch b/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch deleted file mode 100644 index 9b4609fb75..0000000000 --- a/package/kernel/mac80211/patches/367-brcmfmac-avoid-gcc-5.1-warning.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Arnd Bergmann -Date: Tue, 12 May 2015 23:54:25 +0200 -Subject: [PATCH] brcmfmac: avoid gcc-5.1 warning - -gcc-5.0 gained a new warning in the fwsignal portion of the brcmfmac -driver: - -drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c: In function 'brcmf_fws_txs_process': -drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c:1478:8: warning: 'skb' may be used uninitialized in this function [-Wmaybe-uninitialized] - -This is a false positive, and marking the brcmf_fws_hanger_poppkt function -as 'static inline' makes the warning go away. I have checked the object -file output and while a little code gets moved around, the size of -the binary remains identical. - -Signed-off-by: Arnd Bergmann -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -635,7 +635,7 @@ static int brcmf_fws_hanger_pushpkt(stru - return 0; - } - --static int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h, -+static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h, - u32 slot_id, struct sk_buff **pktout, - bool remove_item) - { diff --git a/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch b/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch deleted file mode 100644 index b16782d593..0000000000 --- a/package/kernel/mac80211/patches/368-brcmfmac-allow-device-tree-node-without-interrupts-p.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Arend van Spriel -Date: Wed, 20 May 2015 14:09:47 +0200 -Subject: [PATCH] brcmfmac: allow device tree node without 'interrupts' - property - -As described in the device tree bindings for 'brcm,bcm4329-fmac' -nodes, the interrupts property is optional. So adding a check -for the presence of this property before attempting to parse -and map the interrupt. If not present or parsing fails return -and fallback to in-band sdio interrupt. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/of.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c -@@ -39,10 +39,16 @@ void brcmf_of_probe(struct brcmf_sdio_de - if (!sdiodev->pdata) - return; - -+ if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) -+ sdiodev->pdata->drive_strength = val; -+ -+ /* make sure there are interrupts defined in the node */ -+ if (!of_find_property(np, "interrupts", NULL)) -+ return; -+ - irq = irq_of_parse_and_map(np, 0); - if (!irq) { - brcmf_err("interrupt could not be mapped\n"); -- devm_kfree(dev, sdiodev->pdata); - return; - } - irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); -@@ -50,7 +56,4 @@ void brcmf_of_probe(struct brcmf_sdio_de - sdiodev->pdata->oob_irq_supported = true; - sdiodev->pdata->oob_irq_nr = irq; - sdiodev->pdata->oob_irq_flags = irqf; -- -- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) -- sdiodev->pdata->drive_strength = val; - } diff --git a/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch b/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch deleted file mode 100644 index f81250ee4c..0000000000 --- a/package/kernel/mac80211/patches/369-brcmfmac-Improve-throughput-by-scheduling-msbug-flow.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Hante Meuleman -Date: Wed, 20 May 2015 14:09:48 +0200 -Subject: [PATCH] brcmfmac: Improve throughput by scheduling msbug flow worker. - -The tx flow worker in msgbuf gets scheduled at tx till a certain -threshold has been reached. Then the tx completes will take over -the scheduling. When amsdu and ampdu is used the frames are -transferred wireless in a very bulky fashion, in combination -with this scheduling algorithm and buffer limiters in the stack -this can result in limited throughput. This change causes the -flow worker to be scheduled more frequently from tx. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Daniel (Deognyoun) Kim -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -@@ -249,8 +249,8 @@ void brcmf_flowring_delete(struct brcmf_ - } - - --void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, -- struct sk_buff *skb) -+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, -+ struct sk_buff *skb) - { - struct brcmf_flowring_ring *ring; - -@@ -271,6 +271,7 @@ void brcmf_flowring_enqueue(struct brcmf - if (skb_queue_len(&ring->skblist) < BRCMF_FLOWRING_LOW) - brcmf_flowring_block(flow, flowid, false); - } -+ return skb_queue_len(&ring->skblist); - } - - ---- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h -@@ -64,8 +64,8 @@ u32 brcmf_flowring_create(struct brcmf_f - void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid); - void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid); - u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid); --void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, -- struct sk_buff *skb); -+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, -+ struct sk_buff *skb); - struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid); - void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, - struct sk_buff *skb); ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -73,7 +73,7 @@ - #define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 - #define BRCMF_MSGBUF_TX_FLUSH_CNT2 96 - --#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 64 -+#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 - #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 - - struct msgbuf_common_hdr { -@@ -797,6 +797,8 @@ static int brcmf_msgbuf_txdata(struct br - struct brcmf_flowring *flow = msgbuf->flow; - struct ethhdr *eh = (struct ethhdr *)(skb->data); - u32 flowid; -+ u32 queue_count; -+ bool force; - - flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx); - if (flowid == BRCMF_FLOWRING_INVALID_ID) { -@@ -804,8 +806,9 @@ static int brcmf_msgbuf_txdata(struct br - if (flowid == BRCMF_FLOWRING_INVALID_ID) - return -ENOMEM; - } -- brcmf_flowring_enqueue(flow, flowid, skb); -- brcmf_msgbuf_schedule_txdata(msgbuf, flowid, false); -+ queue_count = brcmf_flowring_enqueue(flow, flowid, skb); -+ force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0); -+ brcmf_msgbuf_schedule_txdata(msgbuf, flowid, force); - - return 0; - } diff --git a/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch b/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch deleted file mode 100644 index 61153c4a98..0000000000 --- a/package/kernel/mac80211/patches/370-brcmfmac-remove-pci-shared-structure-rev4-support.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Franky Lin -Date: Wed, 20 May 2015 14:09:49 +0200 -Subject: [PATCH] brcmfmac: remove pci shared structure rev4 support - -All pcie full dongle chips supported by fmac are using rev 5+ shared -structure. This patch removes the rev4 related code. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -112,10 +112,9 @@ enum brcmf_pcie_state { - BRCMF_PCIE_MB_INT_D2H3_DB0 | \ - BRCMF_PCIE_MB_INT_D2H3_DB1) - --#define BRCMF_PCIE_MIN_SHARED_VERSION 4 -+#define BRCMF_PCIE_MIN_SHARED_VERSION 5 - #define BRCMF_PCIE_MAX_SHARED_VERSION 5 - #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF --#define BRCMF_PCIE_SHARED_TXPUSH_SUPPORT 0x4000 - - #define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 - #define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 -@@ -1280,11 +1279,6 @@ brcmf_pcie_init_share_ram_info(struct br - brcmf_err("Unsupported PCIE version %d\n", version); - return -EINVAL; - } -- if (shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT) { -- brcmf_err("Unsupported legacy TX mode 0x%x\n", -- shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT); -- return -EINVAL; -- } - - addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET; - shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr); diff --git a/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch b/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch deleted file mode 100644 index 8c8eebe44f..0000000000 --- a/package/kernel/mac80211/patches/371-brcmfmac-remove-dummy-cache-flush-invalidate-functio.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Franky Lin -Date: Wed, 20 May 2015 14:09:50 +0200 -Subject: [PATCH] brcmfmac: remove dummy cache flush/invalidate function - -brcmf_dma_flush and brcmf_dma_invalidate_cache are not necessary and -have never been implemented. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c -@@ -22,17 +22,6 @@ - #include "core.h" - #include "commonring.h" - -- --/* dma flushing needs implementation for mips and arm platforms. Should -- * be put in util. Note, this is not real flushing. It is virtual non -- * cached memory. Only write buffers should have to be drained. Though -- * this may be different depending on platform...... -- * SEE ALSO msgbuf.c -- */ --#define brcmf_dma_flush(addr, len) --#define brcmf_dma_invalidate_cache(addr, len) -- -- - void brcmf_commonring_register_cb(struct brcmf_commonring *commonring, - int (*cr_ring_bell)(void *ctx), - int (*cr_update_rptr)(void *ctx), -@@ -206,14 +195,9 @@ int brcmf_commonring_write_complete(stru - address = commonring->buf_addr; - address += (commonring->f_ptr * commonring->item_len); - if (commonring->f_ptr > commonring->w_ptr) { -- brcmf_dma_flush(address, -- (commonring->depth - commonring->f_ptr) * -- commonring->item_len); - address = commonring->buf_addr; - commonring->f_ptr = 0; - } -- brcmf_dma_flush(address, (commonring->w_ptr - commonring->f_ptr) * -- commonring->item_len); - - commonring->f_ptr = commonring->w_ptr; - -@@ -258,8 +242,6 @@ void *brcmf_commonring_get_read_ptr(stru - if (commonring->r_ptr == commonring->depth) - commonring->r_ptr = 0; - -- brcmf_dma_invalidate_cache(ret_addr, *n_ items * commonring->item_len); -- - return ret_addr; - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -278,16 +278,6 @@ struct brcmf_msgbuf_pktids { - struct brcmf_msgbuf_pktid *array; - }; - -- --/* dma flushing needs implementation for mips and arm platforms. Should -- * be put in util. Note, this is not real flushing. It is virtual non -- * cached memory. Only write buffers should have to be drained. Though -- * this may be different depending on platform...... -- */ --#define brcmf_dma_flush(addr, len) --#define brcmf_dma_invalidate_cache(addr, len) -- -- - static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf); - - -@@ -462,7 +452,6 @@ static int brcmf_msgbuf_tx_ioctl(struct - memcpy(msgbuf->ioctbuf, buf, buf_len); - else - memset(msgbuf->ioctbuf, 0, buf_len); -- brcmf_dma_flush(ioctl_buf, buf_len); - - err = brcmf_commonring_write_complete(commonring); - brcmf_commonring_unlock(commonring); ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -276,15 +276,6 @@ static const u32 brcmf_ring_itemsize[BRC - }; - - --/* dma flushing needs implementation for mips and arm platforms. Should -- * be put in util. Note, this is not real flushing. It is virtual non -- * cached memory. Only write buffers should have to be drained. Though -- * this may be different depending on platform...... -- */ --#define brcmf_dma_flush(addr, len) --#define brcmf_dma_invalidate_cache(addr, len) -- -- - static u32 - brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) - { -@@ -1174,7 +1165,6 @@ static int brcmf_pcie_init_scratchbuffer - goto fail; - - memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); -- brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); - - addr = devinfo->shared.tcm_base_address + - BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; -@@ -1192,7 +1182,6 @@ static int brcmf_pcie_init_scratchbuffer - goto fail; - - memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); -- brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); - - addr = devinfo->shared.tcm_base_address + - BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; diff --git a/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch b/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch deleted file mode 100644 index 2f50abd0e1..0000000000 --- a/package/kernel/mac80211/patches/372-brcmfmac-add-support-for-dma-indices-feature.patch +++ /dev/null @@ -1,270 +0,0 @@ -From: Franky Lin -Date: Wed, 20 May 2015 14:09:51 +0200 -Subject: [PATCH] brcmfmac: add support for dma indices feature - -PCIe full dongle firmware can support a dma indices feature with which -firmware can update/fetch the read/write indices of message buffer -rings on both host to dongle and dongle to host directions. The support is -announced by firmware through shared flags. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -115,6 +115,8 @@ enum brcmf_pcie_state { - #define BRCMF_PCIE_MIN_SHARED_VERSION 5 - #define BRCMF_PCIE_MAX_SHARED_VERSION 5 - #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF -+#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 -+#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 - - #define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 - #define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 -@@ -146,6 +148,10 @@ enum brcmf_pcie_state { - #define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8 - #define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12 - #define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16 -+#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET 20 -+#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET 28 -+#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET 36 -+#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET 44 - #define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0 - #define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52 - -@@ -247,6 +253,13 @@ struct brcmf_pciedev_info { - bool mbdata_completed; - bool irq_allocated; - bool wowl_enabled; -+ u8 dma_idx_sz; -+ void *idxbuf; -+ u32 idxbuf_sz; -+ dma_addr_t idxbuf_dmahandle; -+ 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_pcie_ringbuf { -@@ -323,6 +336,25 @@ brcmf_pcie_write_tcm16(struct brcmf_pcie - } - - -+static u16 -+brcmf_pcie_read_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset) -+{ -+ u16 *address = devinfo->idxbuf + mem_offset; -+ -+ return (*(address)); -+} -+ -+ -+static void -+brcmf_pcie_write_idx(struct brcmf_pciedev_info *devinfo, u32 mem_offset, -+ u16 value) -+{ -+ u16 *address = devinfo->idxbuf + mem_offset; -+ -+ *(address) = value; -+} -+ -+ - static u32 - brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset) - { -@@ -868,7 +900,7 @@ static int brcmf_pcie_ring_mb_write_rptr - brcmf_dbg(PCIE, "W r_ptr %d (%d), ring %d\n", commonring->r_ptr, - commonring->w_ptr, ring->id); - -- brcmf_pcie_write_tcm16(devinfo, ring->r_idx_addr, commonring->r_ptr); -+ devinfo->write_ptr(devinfo, ring->r_idx_addr, commonring->r_ptr); - - return 0; - } -@@ -886,7 +918,7 @@ static int brcmf_pcie_ring_mb_write_wptr - brcmf_dbg(PCIE, "W w_ptr %d (%d), ring %d\n", commonring->w_ptr, - commonring->r_ptr, ring->id); - -- brcmf_pcie_write_tcm16(devinfo, ring->w_idx_addr, commonring->w_ptr); -+ devinfo->write_ptr(devinfo, ring->w_idx_addr, commonring->w_ptr); - - return 0; - } -@@ -915,7 +947,7 @@ static int brcmf_pcie_ring_mb_update_rpt - if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) - return -EIO; - -- commonring->r_ptr = brcmf_pcie_read_tcm16(devinfo, ring->r_idx_addr); -+ commonring->r_ptr = devinfo->read_ptr(devinfo, ring->r_idx_addr); - - brcmf_dbg(PCIE, "R r_ptr %d (%d), ring %d\n", commonring->r_ptr, - commonring->w_ptr, ring->id); -@@ -933,7 +965,7 @@ static int brcmf_pcie_ring_mb_update_wpt - if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) - return -EIO; - -- commonring->w_ptr = brcmf_pcie_read_tcm16(devinfo, ring->w_idx_addr); -+ commonring->w_ptr = devinfo->read_ptr(devinfo, ring->w_idx_addr); - - brcmf_dbg(PCIE, "R w_ptr %d (%d), ring %d\n", commonring->w_ptr, - commonring->r_ptr, ring->id); -@@ -1038,6 +1070,13 @@ static void brcmf_pcie_release_ringbuffe - } - kfree(devinfo->shared.flowrings); - devinfo->shared.flowrings = NULL; -+ if (devinfo->idxbuf) { -+ dma_free_coherent(&devinfo->pdev->dev, -+ devinfo->idxbuf_sz, -+ devinfo->idxbuf, -+ devinfo->idxbuf_dmahandle); -+ devinfo->idxbuf = NULL; -+ } - } - - -@@ -1053,19 +1092,72 @@ static int brcmf_pcie_init_ringbuffers(s - u32 addr; - u32 ring_mem_ptr; - u32 i; -+ u64 address; -+ u32 bufsz; - u16 max_sub_queues; -+ u8 idx_offset; - - ring_addr = devinfo->shared.ring_info_addr; - brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr); -+ addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; -+ max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); - -- addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; -- d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; -- d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; -- h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -- addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; -- h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ if (devinfo->dma_idx_sz != 0) { -+ bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) * -+ devinfo->dma_idx_sz * 2; -+ devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz, -+ &devinfo->idxbuf_dmahandle, -+ GFP_KERNEL); -+ if (!devinfo->idxbuf) -+ devinfo->dma_idx_sz = 0; -+ } -+ -+ if (devinfo->dma_idx_sz == 0) { -+ addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; -+ d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; -+ d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; -+ h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; -+ h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -+ idx_offset = sizeof(u32); -+ devinfo->write_ptr = brcmf_pcie_write_tcm16; -+ devinfo->read_ptr = brcmf_pcie_read_tcm16; -+ brcmf_dbg(PCIE, "Using TCM indices\n"); -+ } else { -+ memset(devinfo->idxbuf, 0, bufsz); -+ devinfo->idxbuf_sz = bufsz; -+ idx_offset = devinfo->dma_idx_sz; -+ devinfo->write_ptr = brcmf_pcie_write_idx; -+ devinfo->read_ptr = brcmf_pcie_read_idx; -+ -+ h2d_w_idx_ptr = 0; -+ addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET; -+ address = (u64)devinfo->idxbuf_dmahandle; -+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ -+ h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset; -+ addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET; -+ address += max_sub_queues * idx_offset; -+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ -+ d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset; -+ addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET; -+ address += max_sub_queues * idx_offset; -+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ -+ d2h_r_idx_ptr = d2h_w_idx_ptr + -+ BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; -+ addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET; -+ address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; -+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); -+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); -+ brcmf_dbg(PCIE, "Using host memory indices\n"); -+ } - - addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET; - ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr); -@@ -1079,8 +1171,8 @@ static int brcmf_pcie_init_ringbuffers(s - ring->id = i; - devinfo->shared.commonrings[i] = ring; - -- h2d_w_idx_ptr += sizeof(u32); -- h2d_r_idx_ptr += sizeof(u32); -+ h2d_w_idx_ptr += idx_offset; -+ h2d_r_idx_ptr += idx_offset; - ring_mem_ptr += BRCMF_RING_MEM_SZ; - } - -@@ -1094,13 +1186,11 @@ static int brcmf_pcie_init_ringbuffers(s - ring->id = i; - devinfo->shared.commonrings[i] = ring; - -- d2h_w_idx_ptr += sizeof(u32); -- d2h_r_idx_ptr += sizeof(u32); -+ d2h_w_idx_ptr += idx_offset; -+ d2h_r_idx_ptr += idx_offset; - ring_mem_ptr += BRCMF_RING_MEM_SZ; - } - -- addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; -- max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); - devinfo->shared.nrof_flowrings = - max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS; - rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring), -@@ -1124,15 +1214,15 @@ static int brcmf_pcie_init_ringbuffers(s - ring); - ring->w_idx_addr = h2d_w_idx_ptr; - ring->r_idx_addr = h2d_r_idx_ptr; -- h2d_w_idx_ptr += sizeof(u32); -- h2d_r_idx_ptr += sizeof(u32); -+ h2d_w_idx_ptr += idx_offset; -+ h2d_r_idx_ptr += idx_offset; - } - devinfo->shared.flowrings = rings; - - return 0; - - fail: -- brcmf_err("Allocating commonring buffers failed\n"); -+ brcmf_err("Allocating ring buffers failed\n"); - brcmf_pcie_release_ringbuffers(devinfo); - return -ENOMEM; - } -@@ -1269,6 +1359,14 @@ brcmf_pcie_init_share_ram_info(struct br - return -EINVAL; - } - -+ /* check firmware support dma indicies */ -+ if (shared->flags & BRCMF_PCIE_SHARED_DMA_INDEX) { -+ if (shared->flags & BRCMF_PCIE_SHARED_DMA_2B_IDX) -+ devinfo->dma_idx_sz = sizeof(u16); -+ else -+ devinfo->dma_idx_sz = sizeof(u32); -+ } -+ - addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET; - shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr); - if (shared->max_rxbufpost == 0) diff --git a/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch b/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch deleted file mode 100644 index 28408d2b4f..0000000000 --- a/package/kernel/mac80211/patches/373-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch +++ /dev/null @@ -1,102 +0,0 @@ -From: Arend van Spriel -Date: Tue, 26 May 2015 13:19:46 +0200 -Subject: [PATCH] brcmfmac: avoid null pointer access when - brcmf_msgbuf_get_pktid() fails - -The function brcmf_msgbuf_get_pktid() may return a NULL pointer so -the callers should check the return pointer before accessing it to -avoid the crash below (see [1]): - -brcmfmac: brcmf_msgbuf_get_pktid: Invalid packet id 273 (not in use) -BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 -IP: [] skb_pull+0x5/0x50 -PGD 0 -Oops: 0000 [#1] PREEMPT SMP -Modules linked in: pci_stub vboxpci(O) vboxnetflt(O) vboxnetadp(O) vboxdrv(O) - snd_hda_codec_hdmi bnep mousedev hid_generic ushwmon msr ext4 crc16 mbcache - jbd2 sd_mod uas usb_storage ahci libahci libata scsi_mod xhci_pci xhci_hcd - usbcore usb_common -CPU: 0 PID: 1661 Comm: irq/61-brcmf_pc Tainted: G O 4.0.1-MacbookPro-ARCH #1 -Hardware name: Apple Inc. MacBookPro12,1/Mac-E43C1C25D4880AD6, - BIOS MBP121.88Z.0167.B02.1503241251 03/24/2015 -task: ffff880264203cc0 ti: ffff88025ffe4000 task.ti: ffff88025ffe4000 -RIP: 0010:[] [] skb_pull+0x5/0x50 -RSP: 0018:ffff88025ffe7d40 EFLAGS: 00010202 -RAX: 0000000000000000 RBX: ffff88008a33c000 RCX: 0000000000000044 -RDX: 0000000000000000 RSI: 000000000000004a RDI: 0000000000000000 -RBP: ffff88025ffe7da8 R08: 0000000000000096 R09: 000000000000004a -R10: 0000000000000000 R11: 000000000000048e R12: ffff88025ff14f00 -R13: 0000000000000000 R14: ffff880263b48200 R15: ffff88008a33c000 -FS: 0000000000000000(0000) GS:ffff88026ec00000(0000) knlGS:0000000000000000 -CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 -CR2: 0000000000000080 CR3: 000000000180b000 CR4: 00000000003407f0 -Stack: - ffffffffa06aed74 ffff88025ffe7dc8 ffff880263b48270 ffff880263b48278 - 05ea88020000004a 0002ffff81014635 000000001720b2f6 ffff88026ec116c0 - ffff880263b48200 0000000000010000 ffff880263b4ae00 ffff880264203cc0 -Call Trace: - [] ? brcmf_msgbuf_process_rx+0x404/0x480 [brcmfmac] - [] ? irq_finalize_oneshot.part.30+0xf0/0xf0 - [] brcmf_proto_msgbuf_rx_trigger+0x35/0xf0 [brcmfmac] - [] brcmf_pcie_isr_thread_v2+0x8a/0x130 [brcmfmac] - [] irq_thread_fn+0x20/0x50 - [] irq_thread+0x13f/0x170 - [] ? wake_threads_waitq+0x30/0x30 - [] ? irq_thread_dtor+0xb0/0xb0 - [] kthread+0xd8/0xf0 - [] ? kthread_create_on_node+0x1c0/0x1c0 - [] ret_from_fork+0x58/0x90 - [] ? kthread_create_on_node+0x1c0/0x1c0 -Code: 01 83 e2 f7 88 50 01 48 83 c4 08 5b 5d f3 c3 0f 1f 80 00 00 00 00 83 e2 - f7 88 50 01 c3 66 0f 1f 84 00 00 00 00 00 0f 1f -RIP [] skb_pull+0x5/0x50 - RSP -CR2: 0000000000000080 ----[ end trace b074c0f90e7c997d ]--- - -[1] http://mid.gmane.org/20150430193259.GA5630@googlemail.com - -Cc: # v3.18, v3.19, v4.0, v4.1 -Reported-by: Michael Hornung -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -500,11 +500,9 @@ static int brcmf_msgbuf_query_dcmd(struc - msgbuf->rx_pktids, - msgbuf->ioctl_resp_pktid); - if (msgbuf->ioctl_resp_ret_len != 0) { -- if (!skb) { -- brcmf_err("Invalid packet id idx recv'd %d\n", -- msgbuf->ioctl_resp_pktid); -+ if (!skb) - return -EBADF; -- } -+ - memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? - len : msgbuf->ioctl_resp_ret_len); - } -@@ -866,10 +864,8 @@ brcmf_msgbuf_process_txstatus(struct brc - flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; - skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, - msgbuf->tx_pktids, idx); -- if (!skb) { -- brcmf_err("Invalid packet id idx recv'd %d\n", idx); -+ if (!skb) - return; -- } - - set_bit(flowid, msgbuf->txstatus_done_map); - commonring = msgbuf->flowrings[flowid]; -@@ -1148,6 +1144,8 @@ brcmf_msgbuf_process_rx_complete(struct - - skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, - msgbuf->rx_pktids, idx); -+ if (!skb) -+ return; - - if (data_offset) - skb_pull(skb, data_offset); diff --git a/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch b/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch deleted file mode 100644 index f0230347ef..0000000000 --- a/package/kernel/mac80211/patches/374-brcmfmac-fix-invalid-access-to-struct-acpi_device-fi.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Arend van Spriel -Date: Wed, 27 May 2015 19:31:41 +0200 -Subject: [PATCH] brcmfmac: fix invalid access to struct acpi_device fields - -The fields of struct acpi_device are only known when CONFIG_ACPI is -defined. Fix this by using a helper function. This will resolve the -issue found in linux-next: - - ../brcmfmac/bcmsdh.c: In function 'brcmf_ops_sdio_probe': - ../brcmfmac/bcmsdh.c:1139:7: error: dereferencing pointer to incomplete type - adev->flags.power_manageable = 0; - ^ - -Fixes: f0992ace680c ("brcmfmac: prohibit ACPI power management ...") -Cc: Fu, Zhonghui -Reported-by: Stephen Rothwell -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -1117,6 +1117,18 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_id - static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; - - -+static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev, -+ int val) -+{ -+#if IS_ENABLED(CONFIG_ACPI) -+ struct acpi_device *adev; -+ -+ adev = ACPI_COMPANION(dev); -+ if (adev) -+ adev->flags.power_manageable = 0; -+#endif -+} -+ - static int brcmf_ops_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) - { -@@ -1124,7 +1136,6 @@ static int brcmf_ops_sdio_probe(struct s - struct brcmf_sdio_dev *sdiodev; - struct brcmf_bus *bus_if; - struct device *dev; -- struct acpi_device *adev; - - brcmf_dbg(SDIO, "Enter\n"); - brcmf_dbg(SDIO, "Class=%x\n", func->class); -@@ -1132,11 +1143,9 @@ static int brcmf_ops_sdio_probe(struct s - brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(SDIO, "Function#: %d\n", func->num); - -- /* prohibit ACPI power management for this device */ - dev = &func->dev; -- adev = ACPI_COMPANION(dev); -- if (adev) -- adev->flags.power_manageable = 0; -+ /* prohibit ACPI power management for this device */ -+ brcmf_sdiod_acpi_set_power_manageable(dev, 0); - - /* Consume func num 1 but dont do anything with it. */ - if (func->num == 1) diff --git a/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch b/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch deleted file mode 100644 index 2bfd44f998..0000000000 --- a/package/kernel/mac80211/patches/375-brcmfmac-simplify-check-stripping-v2-NVRAM.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 20 May 2015 09:34:21 +0200 -Subject: [PATCH] brcmfmac: simplify check stripping v2 NVRAM -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Comparing NVRAM entry with a full filtering string is simpler than -comparing it with a short prefix and then checking random chars at magic -offsets. The cost of snprintf relatively low, we execute it just once. -Tested on BCM43602 with NVRAM hacked to use V2 format. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -25,7 +25,7 @@ - - #define BRCMF_FW_MAX_NVRAM_SIZE 64000 - #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ --#define BRCMF_FW_NVRAM_PCIEDEV_LEN 9 /* pcie/1/4/ */ -+#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */ - - char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; - module_param_string(firmware_path, brcmf_firmware_path, -@@ -297,6 +297,8 @@ fail: - static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, - u16 bus_nr) - { -+ char prefix[BRCMF_FW_NVRAM_PCIEDEV_LEN]; -+ size_t len; - u32 i, j; - u8 *nvram; - -@@ -308,14 +310,13 @@ static void brcmf_fw_strip_multi_v2(stru - * Valid entries are of type pcie/X/Y/ where X = domain_nr and - * Y = bus_nr. - */ -+ snprintf(prefix, sizeof(prefix), "pcie/%d/%d/", domain_nr, bus_nr); -+ len = strlen(prefix); - i = 0; - j = 0; -- while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) { -- if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) && -- (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') && -- ((nvp->nvram[i + 5] - '0') == domain_nr) && -- ((nvp->nvram[i + 7] - '0') == bus_nr)) { -- i += BRCMF_FW_NVRAM_PCIEDEV_LEN; -+ while (i < nvp->nvram_len - len) { -+ if (strncmp(&nvp->nvram[i], prefix, len) == 0) { -+ i += len; - while (nvp->nvram[i] != 0) { - nvram[j] = nvp->nvram[i]; - i++; diff --git a/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch b/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch deleted file mode 100644 index 0e65114f86..0000000000 --- a/package/kernel/mac80211/patches/376-brcmfmac-simplify-check-finding-NVRAM-v1-device-path.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 20 May 2015 11:01:08 +0200 -Subject: [PATCH] brcmfmac: simplify check finding NVRAM v1 device path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With a simple use of snprintf and small buffer we can compare NVRAM -entry value with a full string. This way we avoid checking random chars -at magic offsets. -Tested on BCM43602 with NVRAM hacked to use v1 format. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -222,6 +222,10 @@ static int brcmf_init_nvram_parser(struc - static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, - u16 bus_nr) - { -+ /* Device path with a leading '=' key-value separator */ -+ char pcie_path[] = "=pcie/?/?"; -+ size_t pcie_len; -+ - u32 i, j; - bool found; - u8 *nvram; -@@ -238,6 +242,9 @@ static void brcmf_fw_strip_multi_v1(stru - /* First search for the devpathX and see if it is the configuration - * for domain_nr/bus_nr. Search complete nvp - */ -+ snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, -+ bus_nr); -+ pcie_len = strlen(pcie_path); - found = false; - i = 0; - while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) { -@@ -245,13 +252,10 @@ static void brcmf_fw_strip_multi_v1(stru - * Y = domain_nr, Z = bus_nr, X = virtual ID - */ - if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && -- (strncmp(&nvp->nvram[i + 8], "=pcie/", 6) == 0)) { -- if (((nvp->nvram[i + 14] - '0') == domain_nr) && -- ((nvp->nvram[i + 16] - '0') == bus_nr)) { -- id = nvp->nvram[i + 7] - '0'; -- found = true; -- break; -- } -+ (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { -+ id = nvp->nvram[i + 7] - '0'; -+ found = true; -+ break; - } - while (nvp->nvram[i] != 0) - i++; diff --git a/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch b/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch deleted file mode 100644 index dc174e5a3d..0000000000 --- a/package/kernel/mac80211/patches/377-brcmfmac-treat-0-as-end-of-comment-when-parsing-NVRA.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 20 May 2015 13:59:54 +0200 -Subject: [PATCH] brcmfmac: treat \0 as end of comment when parsing NVRAM -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes brcmfmac dealing with NVRAM coming from platform e.g. from a -flash MTD partition. In such cases entries are separated by \0 instead -of \n which caused ignoring whole content after the first "comment". -While platform NVRAM doesn't usually contain comments, we switch to -COMMENT state after e.g. finding an unexpected char in key name. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -162,17 +162,20 @@ brcmf_nvram_handle_value(struct nvram_pa - static enum nvram_parser_state - brcmf_nvram_handle_comment(struct nvram_parser *nvp) - { -- char *eol, *sol; -+ char *eoc, *sol; - - sol = (char *)&nvp->fwnv->data[nvp->pos]; -- eol = strchr(sol, '\n'); -- if (eol == NULL) -- return END; -+ eoc = strchr(sol, '\n'); -+ if (!eoc) { -+ eoc = strchr(sol, '\0'); -+ if (!eoc) -+ return END; -+ } - - /* eat all moving to next line */ - nvp->line++; - nvp->column = 1; -- nvp->pos += (eol - sol) + 1; -+ nvp->pos += (eoc - sol) + 1; - return IDLE; - } - diff --git a/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch b/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch deleted file mode 100644 index 5700142646..0000000000 --- a/package/kernel/mac80211/patches/378-brcmfmac-allow-NVRAM-values-to-contain-spaces.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 23 May 2015 09:15:33 +0200 -Subject: [PATCH] brcmfmac: allow NVRAM values to contain spaces -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Platform NVRAMs often contain values with spaces. Even if right now most -firmware-supported entries are simple values, we shouldn't reject these -with spaces. It was semi-confirmed by Broadcom in the early patch adding -support for platform NVRAMs. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -66,6 +66,12 @@ struct nvram_parser { - bool multi_dev_v2; - }; - -+/** -+ * is_nvram_char() - check if char is a valid one for NVRAM entry -+ * -+ * It accepts all printable ASCII chars except for '#' which opens a comment. -+ * Please note that ' ' (space) while accepted is not a valid key name char. -+ */ - static bool is_nvram_char(char c) - { - /* comment marker excluded */ -@@ -73,7 +79,7 @@ static bool is_nvram_char(char c) - return false; - - /* key and value may have any other readable character */ -- return (c > 0x20 && c < 0x7f); -+ return (c >= 0x20 && c < 0x7f); - } - - static bool is_whitespace(char c) -@@ -120,7 +126,7 @@ static enum nvram_parser_state brcmf_nvr - nvp->multi_dev_v1 = true; - if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) - nvp->multi_dev_v2 = true; -- } else if (!is_nvram_char(c)) { -+ } else if (!is_nvram_char(c) || c == ' ') { - brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", - nvp->line, nvp->column); - return COMMENT; diff --git a/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch b/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch new file mode 100644 index 0000000000..74df9f93f7 --- /dev/null +++ b/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch @@ -0,0 +1,109 @@ +From: Hante Meuleman +Date: Mon, 8 Jun 2015 14:38:32 +0200 +Subject: [PATCH] brcmfmac: Update msgbuf read pointer quicker. + +On device to host data using msgbuf the read pointer gets updated +once all data is processed. Updating this pointer more frequently +allows the firmware to add more data quicker. This will result in +slightly higher and more stable throughput on CPU bounded host +processors. + +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/brcm80211/brcmfmac/commonring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c +@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struc + void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, + u16 *n_items) + { +- void *ret_addr; +- + if (commonring->cr_update_wptr) + commonring->cr_update_wptr(commonring->cr_ctx); + +@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(stru + if (*n_items == 0) + return NULL; + +- ret_addr = commonring->buf_addr + +- (commonring->r_ptr * commonring->item_len); +- +- commonring->r_ptr += *n_items; +- if (commonring->r_ptr == commonring->depth) +- commonring->r_ptr = 0; +- +- return ret_addr; ++ return commonring->buf_addr + ++ (commonring->r_ptr * commonring->item_len); + } + + +-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring) ++int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, ++ u16 n_items) + { ++ commonring->r_ptr += n_items; ++ if (commonring->r_ptr == commonring->depth) ++ commonring->r_ptr = 0; ++ + if (commonring->cr_write_rptr) + return commonring->cr_write_rptr(commonring->cr_ctx); + +--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h +@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struc + u16 n_items); + void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, + u16 *n_items); +-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring); ++int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, ++ u16 n_items); + + #define brcmf_commonring_n_items(commonring) (commonring->depth) + #define brcmf_commonring_len_item(commonring) (commonring->item_len) +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -75,6 +75,8 @@ + + #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 + #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 ++#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48 ++ + + struct msgbuf_common_hdr { + u8 msgtype; +@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(stru + { + void *buf; + u16 count; ++ u16 processed; + + again: + buf = brcmf_commonring_get_read_ptr(commonring, &count); + if (buf == NULL) + return; + ++ processed = 0; + while (count) { + brcmf_msgbuf_process_msgtype(msgbuf, + buf + msgbuf->rx_dataoffset); + buf += brcmf_commonring_len_item(commonring); ++ processed++; ++ if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) { ++ brcmf_commonring_read_complete(commonring, processed); ++ processed = 0; ++ } + count--; + } +- brcmf_commonring_read_complete(commonring); ++ if (processed) ++ brcmf_commonring_read_complete(commonring, processed); + + if (commonring->r_ptr == 0) + goto again; diff --git a/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch b/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch new file mode 100644 index 0000000000..9e5b48608d --- /dev/null +++ b/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch @@ -0,0 +1,39 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:33 +0200 +Subject: [PATCH] brcmfmac: remove chipinfo debugfs entry + +The information provided by chipinfo is also provided by the +revinfo debugfs entry. Removing it from debugfs. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c +@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void) + root_folder = NULL; + } + +-static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) +-{ +- struct brcmf_bus *bus = dev_get_drvdata(seq->private); +- +- seq_printf(seq, "chip: %x(%u) rev %u\n", +- bus->chip, bus->chip, bus->chiprev); +- return 0; +-} +- + int brcmf_debugfs_attach(struct brcmf_pub *drvr) + { + struct device *dev = drvr->bus_if->dev; +@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pu + return -ENODEV; + + drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); +- brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read); + + return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); + } diff --git a/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch b/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch new file mode 100644 index 0000000000..c38b2cd150 --- /dev/null +++ b/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch @@ -0,0 +1,53 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:34 +0200 +Subject: [PATCH] brcmfmac: remove watchdog reset from + brcmf_pcie_buscoreprep() + +The watchdog reset as done in brcmf_pcie_buscoreprep() is not +sufficient. It needs to modify PCIe core registers as well +which is properly done by brcmf_pcie_reset_device() after the +chip recognition is done. So the faulty watchdog reset can be +removed as it was causing driver reload to fail and hang the +system requiring a power-cycle. Instead the call to to the +brcmf_pcie_reset_device() function is done twice in the unload. + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(v + + static int brcmf_pcie_buscoreprep(void *ctx) + { +- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; +- int err; +- +- err = brcmf_pcie_get_resource(devinfo); +- if (err == 0) { +- /* Set CC watchdog to reset all the cores on the chip to bring +- * back dongle to a sane state. +- */ +- brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE, +- watchdog), 4); +- msleep(100); +- } +- +- return err; ++ return brcmf_pcie_get_resource(ctx); + } + + +@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) + brcmf_pcie_intr_disable(devinfo); + + brcmf_detach(&pdev->dev); ++ brcmf_pcie_reset_device(devinfo); + + kfree(bus->bus_priv.pcie); + kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch b/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch new file mode 100644 index 0000000000..756fbb2cb7 --- /dev/null +++ b/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch @@ -0,0 +1,69 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:35 +0200 +Subject: [PATCH] brcmfmac: use debugfs_create_devm_seqfile() helper + function + +Some time ago the function debugfs_create_devm_seqfile() was +introduced in debugfs. The caller simply needs to provide a +device pointer and read function. The function brcmf_debugfs_add_entry() +is now simply a wrapper only doing the work for CONFIG_BRCMDBG. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c +@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir( + return drvr->dbgfs_dir; + } + +-struct brcmf_debugfs_entry { +- int (*read)(struct seq_file *seq, void *data); +- struct brcmf_pub *drvr; +-}; +- +-static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f) +-{ +- struct brcmf_debugfs_entry *entry = inode->i_private; +- +- return single_open(f, entry->read, entry->drvr->bus_if->dev); +-} +- +-static const struct file_operations brcmf_debugfs_def_ops = { +- .owner = THIS_MODULE, +- .open = brcmf_debugfs_entry_open, +- .release = single_release, +- .read = seq_read, +- .llseek = seq_lseek +-}; +- + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) + { +- struct dentry *dentry = drvr->dbgfs_dir; +- struct brcmf_debugfs_entry *entry; +- +- if (IS_ERR_OR_NULL(dentry)) +- return -ENOENT; +- +- entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL); +- if (!entry) +- return -ENOMEM; +- +- entry->read = read_fn; +- entry->drvr = drvr; +- +- dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, +- &brcmf_debugfs_def_ops); ++ struct dentry *e; + +- return PTR_ERR_OR_ZERO(dentry); ++ e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, ++ drvr->dbgfs_dir, read_fn); ++ return PTR_ERR_OR_ZERO(e); + } diff --git a/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch b/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch deleted file mode 100644 index 74df9f93f7..0000000000 --- a/package/kernel/mac80211/patches/385-brcmfmac-Update-msgbuf-read-pointer-quicker.patch +++ /dev/null @@ -1,109 +0,0 @@ -From: Hante Meuleman -Date: Mon, 8 Jun 2015 14:38:32 +0200 -Subject: [PATCH] brcmfmac: Update msgbuf read pointer quicker. - -On device to host data using msgbuf the read pointer gets updated -once all data is processed. Updating this pointer more frequently -allows the firmware to add more data quicker. This will result in -slightly higher and more stable throughput on CPU bounded host -processors. - -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/brcm80211/brcmfmac/commonring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c -@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struc - void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, - u16 *n_items) - { -- void *ret_addr; -- - if (commonring->cr_update_wptr) - commonring->cr_update_wptr(commonring->cr_ctx); - -@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(stru - if (*n_items == 0) - return NULL; - -- ret_addr = commonring->buf_addr + -- (commonring->r_ptr * commonring->item_len); -- -- commonring->r_ptr += *n_items; -- if (commonring->r_ptr == commonring->depth) -- commonring->r_ptr = 0; -- -- return ret_addr; -+ return commonring->buf_addr + -+ (commonring->r_ptr * commonring->item_len); - } - - --int brcmf_commonring_read_complete(struct brcmf_commonring *commonring) -+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, -+ u16 n_items) - { -+ commonring->r_ptr += n_items; -+ if (commonring->r_ptr == commonring->depth) -+ commonring->r_ptr = 0; -+ - if (commonring->cr_write_rptr) - return commonring->cr_write_rptr(commonring->cr_ctx); - ---- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h -@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struc - u16 n_items); - void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, - u16 *n_items); --int brcmf_commonring_read_complete(struct brcmf_commonring *commonring); -+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, -+ u16 n_items); - - #define brcmf_commonring_n_items(commonring) (commonring->depth) - #define brcmf_commonring_len_item(commonring) (commonring->item_len) ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -75,6 +75,8 @@ - - #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 - #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 -+#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48 -+ - - struct msgbuf_common_hdr { - u8 msgtype; -@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(stru - { - void *buf; - u16 count; -+ u16 processed; - - again: - buf = brcmf_commonring_get_read_ptr(commonring, &count); - if (buf == NULL) - return; - -+ processed = 0; - while (count) { - brcmf_msgbuf_process_msgtype(msgbuf, - buf + msgbuf->rx_dataoffset); - buf += brcmf_commonring_len_item(commonring); -+ processed++; -+ if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) { -+ brcmf_commonring_read_complete(commonring, processed); -+ processed = 0; -+ } - count--; - } -- brcmf_commonring_read_complete(commonring); -+ if (processed) -+ brcmf_commonring_read_complete(commonring, processed); - - if (commonring->r_ptr == 0) - goto again; diff --git a/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch b/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch deleted file mode 100644 index 9e5b48608d..0000000000 --- a/package/kernel/mac80211/patches/386-brcmfmac-remove-chipinfo-debugfs-entry.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:33 +0200 -Subject: [PATCH] brcmfmac: remove chipinfo debugfs entry - -The information provided by chipinfo is also provided by the -revinfo debugfs entry. Removing it from debugfs. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c -@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void) - root_folder = NULL; - } - --static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) --{ -- struct brcmf_bus *bus = dev_get_drvdata(seq->private); -- -- seq_printf(seq, "chip: %x(%u) rev %u\n", -- bus->chip, bus->chip, bus->chiprev); -- return 0; --} -- - int brcmf_debugfs_attach(struct brcmf_pub *drvr) - { - struct device *dev = drvr->bus_if->dev; -@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pu - return -ENODEV; - - drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); -- brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read); - - return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); - } diff --git a/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch b/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch deleted file mode 100644 index c38b2cd150..0000000000 --- a/package/kernel/mac80211/patches/387-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:34 +0200 -Subject: [PATCH] brcmfmac: remove watchdog reset from - brcmf_pcie_buscoreprep() - -The watchdog reset as done in brcmf_pcie_buscoreprep() is not -sufficient. It needs to modify PCIe core registers as well -which is properly done by brcmf_pcie_reset_device() after the -chip recognition is done. So the faulty watchdog reset can be -removed as it was causing driver reload to fail and hang the -system requiring a power-cycle. Instead the call to to the -brcmf_pcie_reset_device() function is done twice in the unload. - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(v - - static int brcmf_pcie_buscoreprep(void *ctx) - { -- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; -- int err; -- -- err = brcmf_pcie_get_resource(devinfo); -- if (err == 0) { -- /* Set CC watchdog to reset all the cores on the chip to bring -- * back dongle to a sane state. -- */ -- brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE, -- watchdog), 4); -- msleep(100); -- } -- -- return err; -+ return brcmf_pcie_get_resource(ctx); - } - - -@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) - brcmf_pcie_intr_disable(devinfo); - - brcmf_detach(&pdev->dev); -+ brcmf_pcie_reset_device(devinfo); - - kfree(bus->bus_priv.pcie); - kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch b/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch deleted file mode 100644 index 756fbb2cb7..0000000000 --- a/package/kernel/mac80211/patches/388-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch +++ /dev/null @@ -1,69 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:35 +0200 -Subject: [PATCH] brcmfmac: use debugfs_create_devm_seqfile() helper - function - -Some time ago the function debugfs_create_devm_seqfile() was -introduced in debugfs. The caller simply needs to provide a -device pointer and read function. The function brcmf_debugfs_add_entry() -is now simply a wrapper only doing the work for CONFIG_BRCMDBG. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c -@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir( - return drvr->dbgfs_dir; - } - --struct brcmf_debugfs_entry { -- int (*read)(struct seq_file *seq, void *data); -- struct brcmf_pub *drvr; --}; -- --static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f) --{ -- struct brcmf_debugfs_entry *entry = inode->i_private; -- -- return single_open(f, entry->read, entry->drvr->bus_if->dev); --} -- --static const struct file_operations brcmf_debugfs_def_ops = { -- .owner = THIS_MODULE, -- .open = brcmf_debugfs_entry_open, -- .release = single_release, -- .read = seq_read, -- .llseek = seq_lseek --}; -- - int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, - int (*read_fn)(struct seq_file *seq, void *data)) - { -- struct dentry *dentry = drvr->dbgfs_dir; -- struct brcmf_debugfs_entry *entry; -- -- if (IS_ERR_OR_NULL(dentry)) -- return -ENOENT; -- -- entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL); -- if (!entry) -- return -ENOMEM; -- -- entry->read = read_fn; -- entry->drvr = drvr; -- -- dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, -- &brcmf_debugfs_def_ops); -+ struct dentry *e; - -- return PTR_ERR_OR_ZERO(dentry); -+ e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, -+ drvr->dbgfs_dir, read_fn); -+ return PTR_ERR_OR_ZERO(e); - }