mac80211: update brcmfmac to the wireless-drivers-next-for-davem-2015-04-09

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

SVN-Revision: 45576
v19.07.3_mercusys_ac12_duma
Rafał Miłecki 9 years ago
parent 33e597b241
commit c1a7e13587

@ -0,0 +1,44 @@
From: Hante Meuleman <meuleman@broadcom.com>
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 <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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) &&

@ -0,0 +1,157 @@
From: Hante Meuleman <meuleman@broadcom.com>
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 <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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;

@ -0,0 +1,83 @@
From: Hante Meuleman <meuleman@broadcom.com>
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 <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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)

@ -0,0 +1,86 @@
From: Syed Asifful Dayyan <syedd@broadcom.com>
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 <pieterpg@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Syed Asifful Dayyan <syedd@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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

@ -0,0 +1,48 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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);

@ -0,0 +1,74 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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)
{

@ -0,0 +1,240 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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]);
}

@ -0,0 +1,61 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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);

@ -0,0 +1,367 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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];
};

@ -0,0 +1,96 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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)

@ -0,0 +1,59 @@
From: Arend van Spriel <arend@broadcom.com>
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 <pontusf@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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

@ -0,0 +1,44 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -29,6 +29,7 @@
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/platform_data/brcmfmac-sdio.h>
+#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -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);

@ -0,0 +1,171 @@
From: Hante Meuleman <meuleman@broadcom.com>
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 <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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;

@ -0,0 +1,26 @@
From: Hante Meuleman <meuleman@broadcom.com>
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 <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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;
}
}

@ -0,0 +1,26 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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);

@ -0,0 +1,138 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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

@ -0,0 +1,50 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Syed Asifful Dayyan <syedd@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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) }
};

@ -0,0 +1,52 @@
From: Arend van Spriel <arend@broadcom.com>
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 <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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),

@ -0,0 +1,28 @@
From: Arend van Spriel <arend@broadcom.com>
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 <jkrause@posteo.de>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- 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) {
Loading…
Cancel
Save